Skip to content

Commit

Permalink
optimization to improve the cases where we can get opengl to render a…
Browse files Browse the repository at this point in the history
… single textured quad if there's a single rectangle cutout of an image that needs repainting
  • Loading branch information
jcooper-korg committed Jun 13, 2024
1 parent 4808fdc commit edab002
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
20 changes: 20 additions & 0 deletions modules/juce_graphics/native/juce_RenderingHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,12 @@ namespace ClipRegions
virtual Ptr clipToImageAlpha (const Image&, const AffineTransform&, Graphics::ResamplingQuality) = 0;
virtual void translate (Point<int> delta) = 0;

// Check whether the supplied rectangle can be drawn clipped inside a single
// rectangle.
// Pessimistic check; only used for optimization - returning false is always
// a correct choice, though it might lead to a slower path in the rasterizer.
virtual bool trimRectangularClip(Rectangle<int> requestedDrawRect, Rectangle<int>& trimmedDrawRect) const = 0;

virtual bool clipRegionIntersects (Rectangle<int>) const = 0;
virtual Rectangle<int> getClipBounds() const = 0;

Expand Down Expand Up @@ -1669,6 +1675,11 @@ namespace ClipRegions
edgeTable.translate ((float) delta.x, delta.y);
}

bool trimRectangularClip(Rectangle<int>, Rectangle<int>&) const override
{
return false;
}

bool clipRegionIntersects (Rectangle<int> r) const override
{
return edgeTable.getMaximumBounds().intersects (r);
Expand Down Expand Up @@ -1793,6 +1804,15 @@ namespace ClipRegions
bool clipRegionIntersects (Rectangle<int> r) const override { return clip.intersects (r); }
Rectangle<int> getClipBounds() const override { return clip.getBounds(); }

bool trimRectangularClip(Rectangle<int> requestedDrawRect, Rectangle<int>& trimmedDrawRect) const override
{
if (clip.getNumRectangles() != 1) return false;

Rectangle<int> rect = clip.getRectangle(0);
trimmedDrawRect = rect.getIntersection(requestedDrawRect);
return !trimmedDrawRect.isEmpty();
}

void fillRectWithColour (SavedStateType& state, Rectangle<int> area, PixelARGB colour, bool replaceContents) const override
{
SubRectangleIterator iter (clip, area);
Expand Down
35 changes: 35 additions & 0 deletions modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,41 @@ struct SavedState final : public RenderingHelpers::SavedStateBase<SavedState>
previousTarget (createCopyIfNotNull (other.previousTarget.get()))
{}

void drawImage (const Image& sourceImage, const AffineTransform& trans)
{
auto t = transform.getTransformWith (trans);
auto alpha = fillType.colour.getAlpha();

// If we're only translating, and if the target image can be drawn with a
// clip that can be reduced to a single rectangle, we can just add a single
// quad to the queue and dispatch a draw call.
if (isOnlyTranslationAllowingError (t, 0.002f))
{
auto targetRect = Rectangle<int>{
(int)t.getTranslationX(),
(int)t.getTranslationY(),
sourceImage.getWidth(),
sourceImage.getHeight(),
};
Rectangle<int> trimmedTargetRect;

if (clip->trimRectangularClip(targetRect, trimmedTargetRect))
{
state->shaderQuadQueue.flush();
state->setShaderForTiledImageFill (state->cachedImageList->getTextureFor (sourceImage), t, 0, nullptr, false);

state->shaderQuadQueue.add (trimmedTargetRect, PixelARGB ((uint8) alpha, (uint8) alpha, (uint8) alpha, (uint8) alpha));
state->shaderQuadQueue.flush();

state->currentShader.clearShader (state->shaderQuadQueue);

return;
}
}

BaseClass::drawImage(sourceImage, trans);
}

SavedState* beginTransparencyLayer (float opacity)
{
auto* s = new SavedState (*this);
Expand Down

0 comments on commit edab002

Please sign in to comment.