1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-11 23:54:18 +00:00

optimization to improve the cases where we can get opengl to render a single textured quad if there's a single rectangle cutout of an image that needs repainting

This commit is contained in:
John Cooper 2024-06-13 10:54:33 -07:00
parent 4808fdce30
commit edab002cc7
2 changed files with 55 additions and 0 deletions

View file

@ -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;
@ -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);
@ -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);

View file

@ -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);