1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
This commit is contained in:
John Cooper 2025-08-17 12:47:52 +00:00 committed by GitHub
commit a242fd2d56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 55 additions and 0 deletions

View file

@ -1554,6 +1554,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;
@ -1670,6 +1676,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);
@ -1794,6 +1805,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

@ -1797,6 +1797,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);