mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Direct2D: Fix performance issue when drawing transformed unclipped regions
This issue could be observed in the GraphicsDemo's SVG pane, when the "rotation" option was enabled. Drawables internally enable the unclipped painting flag, which normally prevents slow clipping when drawing subcomponents of the drawable. The Direct2D graphics context was using the frame area as the default area, used to signal that no clipping should be applied. However, when non-axis-aligned transform was active, this area was incorrectly applied as a geometric clipping region. D2D geometric clips are relatively slow, so this caused large slowdowns. This solution adds a flag that is set whenever a clip is explicitly requested. If no clip is explicitly requested, then clipping will be entirely bypassed. This can make rendering of Drawables significantly faster.
This commit is contained in:
parent
336dcfc08c
commit
f887979ec0
2 changed files with 25 additions and 5 deletions
|
|
@ -1070,21 +1070,24 @@ void Direct2DGraphicsContext::resetPendingClipList()
|
|||
|
||||
void Direct2DGraphicsContext::applyPendingClipList()
|
||||
{
|
||||
if (! pendingClipList.isClipApplied())
|
||||
return;
|
||||
|
||||
auto& transform = currentState->currentTransform;
|
||||
bool const axisAligned = currentState->isCurrentTransformAxisAligned();
|
||||
const auto axisAligned = currentState->isCurrentTransformAxisAligned();
|
||||
const auto list = pendingClipList.getList();
|
||||
|
||||
// Clip if the pending clip list is not empty and smaller than the frame size
|
||||
if (! list.containsRectangle (getPimpl()->getFrameSize().toFloat()) && ! list.isEmpty())
|
||||
{
|
||||
if (list.getNumRectangles() == 1 && (transform.isOnlyTranslated || axisAligned))
|
||||
if (list.getNumRectangles() == 1 && axisAligned)
|
||||
{
|
||||
auto r = list.getRectangle (0);
|
||||
currentState->pushAliasedAxisAlignedClipLayer (r);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto clipTransform = transform.isOnlyTranslated || axisAligned ? AffineTransform{} : transform.getTransform();
|
||||
auto clipTransform = axisAligned ? AffineTransform{} : transform.getTransform();
|
||||
if (auto clipGeometry = D2DHelpers::rectListToPathGeometry (getPimpl()->getDirect2DFactory(),
|
||||
list,
|
||||
clipTransform,
|
||||
|
|
|
|||
|
|
@ -122,29 +122,46 @@ protected:
|
|||
public:
|
||||
void clipTo (Rectangle<float> i)
|
||||
{
|
||||
list.clipTo (i);
|
||||
if (std::exchange (clipApplied, true))
|
||||
list.clipTo (i);
|
||||
else
|
||||
list = i;
|
||||
}
|
||||
|
||||
template <typename Numeric>
|
||||
void clipTo (const RectangleList<Numeric>& other)
|
||||
{
|
||||
list.clipTo (other);
|
||||
if (std::exchange (clipApplied, true))
|
||||
{
|
||||
list.clipTo (other);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.clear();
|
||||
|
||||
for (const auto& r : other)
|
||||
list.add (r.toFloat());
|
||||
}
|
||||
}
|
||||
|
||||
void subtract (Rectangle<float> i)
|
||||
{
|
||||
list.subtract (i);
|
||||
clipApplied = true;
|
||||
}
|
||||
|
||||
RectangleList<float> getList() const { return list; }
|
||||
bool isClipApplied() const { return clipApplied; }
|
||||
|
||||
void reset (Rectangle<float> maxBounds)
|
||||
{
|
||||
list = maxBounds;
|
||||
clipApplied = false;
|
||||
}
|
||||
|
||||
private:
|
||||
RectangleList<float> list;
|
||||
bool clipApplied = false;
|
||||
};
|
||||
|
||||
PendingClipList pendingClipList;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue