From f4a7a709aec91ee1fc72e3b3514fcaac2e3c30fb Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Mon, 10 May 2010 12:00:49 +0100 Subject: [PATCH] Minor graphics speed optimisations. --- src/gui/graphics/contexts/juce_EdgeTable.h | 19 ++-- .../juce_LowLevelGraphicsSoftwareRenderer.cpp | 106 +++++++++++++++--- 2 files changed, 104 insertions(+), 21 deletions(-) diff --git a/src/gui/graphics/contexts/juce_EdgeTable.h b/src/gui/graphics/contexts/juce_EdgeTable.h index 0147bde86e..29a312eaa5 100644 --- a/src/gui/graphics/contexts/juce_EdgeTable.h +++ b/src/gui/graphics/contexts/juce_EdgeTable.h @@ -105,7 +105,9 @@ public: @code inline void setEdgeTableYPos (int y); inline void handleEdgeTablePixel (int x, int alphaLevel) const; + inline void handleEdgeTablePixelFull (int x) const; inline void handleEdgeTableLine (int x, int width, int alphaLevel) const; + inline void handleEdgeTableLineFull (int x, int width) const; @endcode (these don't necessarily have to be 'const', but it might help it go faster) */ @@ -153,9 +155,9 @@ public: if (levelAccumulator > 0) { if (levelAccumulator >> 8) - levelAccumulator = 0xff; - - iterationCallback.handleEdgeTablePixel (x, levelAccumulator); + iterationCallback.handleEdgeTablePixelFull (x); + else + iterationCallback.handleEdgeTablePixel (x, levelAccumulator); } // if there's a run of similar pixels, do it all in one go.. @@ -177,13 +179,14 @@ public: if (levelAccumulator > 0) { - levelAccumulator >>= 8; - if (levelAccumulator >> 8) - levelAccumulator = 0xff; - x >>= 8; jassert (x >= bounds.getX() && x < bounds.getRight()); - iterationCallback.handleEdgeTablePixel (x, levelAccumulator); + + levelAccumulator >>= 8; + if (levelAccumulator >> 8) + iterationCallback.handleEdgeTablePixelFull (x); + else + iterationCallback.handleEdgeTablePixel (x, levelAccumulator); } } } diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index 0ae183fe57..59c2e2fbf0 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -87,7 +87,15 @@ public: linePixels[x].blend (sourceColour, alphaLevel); } - forcedinline void handleEdgeTableLine (const int x, int width, const int alphaLevel) const throw() + forcedinline void handleEdgeTablePixelFull (const int x) const throw() + { + if (replaceExisting) + linePixels[x].set (sourceColour); + else + linePixels[x].blend (sourceColour); + } + + forcedinline void handleEdgeTableLine (const int x, const int width, const int alphaLevel) const throw() { PixelARGB p (sourceColour); p.multiplyAlpha (alphaLevel); @@ -100,6 +108,16 @@ public: blendLine (dest, p, width); } + forcedinline void handleEdgeTableLineFull (const int x, const int width) const throw() + { + PixelType* dest = linePixels + x; + + if (replaceExisting || sourceColour.getAlpha() >= 0xff) + replaceLine (dest, sourceColour, width); + else + blendLine (dest, sourceColour, width); + } + private: const Image::BitmapData& data; PixelType* linePixels; @@ -153,7 +171,7 @@ private: } } - forcedinline void replaceLine (PixelAlpha* dest, const PixelARGB& colour, int width) const throw() + forcedinline void replaceLine (PixelAlpha* const dest, const PixelARGB& colour, int const width) const throw() { memset (dest, colour.getAlpha(), width); } @@ -353,7 +371,12 @@ public: linePixels[x].blend (GradientType::getPixel (x), alphaLevel); } - forcedinline void handleEdgeTableLine (int x, int width, const int alphaLevel) const throw() + forcedinline void handleEdgeTablePixelFull (const int x) const throw() + { + linePixels[x].blend (GradientType::getPixel (x)); + } + + void handleEdgeTableLine (int x, int width, const int alphaLevel) const throw() { PixelType* dest = linePixels + x; @@ -373,6 +396,16 @@ public: } } + void handleEdgeTableLineFull (int x, int width) const throw() + { + PixelType* dest = linePixels + x; + + do + { + (dest++)->blend (GradientType::getPixel (x++)); + } while (--width > 0); + } + private: const Image::BitmapData& destData; PixelType* linePixels; @@ -420,14 +453,19 @@ public: sourceLineStart = (SrcPixelType*) srcData.getLinePointer (y); } - forcedinline void handleEdgeTablePixel (int x, int alphaLevel) const throw() + forcedinline void handleEdgeTablePixel (const int x, int alphaLevel) const throw() { alphaLevel = (alphaLevel * extraAlpha) >> 8; linePixels[x].blend (sourceLineStart [repeatPattern ? ((x - xOffset) % srcData.width) : (x - xOffset)], alphaLevel); } - forcedinline void handleEdgeTableLine (int x, int width, int alphaLevel) const throw() + forcedinline void handleEdgeTablePixelFull (const int x) const throw() + { + linePixels[x].blend (sourceLineStart [repeatPattern ? ((x - xOffset) % srcData.width) : (x - xOffset)], extraAlpha); + } + + void handleEdgeTableLine (int x, int width, int alphaLevel) const throw() { DestPixelType* dest = linePixels + x; alphaLevel = (alphaLevel * extraAlpha) >> 8; @@ -458,6 +496,36 @@ public: } } + void handleEdgeTableLineFull (int x, int width) const throw() + { + DestPixelType* dest = linePixels + x; + x -= xOffset; + + jassert (repeatPattern || (x >= 0 && x + width <= srcData.width)); + + if (extraAlpha < 0xfe) + { + do + { + dest++ ->blend (sourceLineStart [repeatPattern ? (x++ % srcData.width) : x++], extraAlpha); + } while (--width > 0); + } + else + { + if (repeatPattern) + { + do + { + dest++ ->blend (sourceLineStart [x++ % srcData.width]); + } while (--width > 0); + } + else + { + copyRow (dest, sourceLineStart + x, width); + } + } + } + void clipEdgeTableLine (EdgeTable& et, int x, int y, int width) { jassert (x - xOffset >= 0 && x + width - xOffset <= srcData.width); @@ -540,7 +608,15 @@ public: linePixels[x].blend (p, alphaLevel); } - forcedinline void handleEdgeTableLine (const int x, int width, int alphaLevel) throw() + forcedinline void handleEdgeTablePixelFull (const int x) throw() + { + SrcPixelType p; + generate (&p, x, 1); + + linePixels[x].blend (p, extraAlpha); + } + + void handleEdgeTableLine (const int x, int width, int alphaLevel) throw() { if (width > scratchSize) { @@ -571,6 +647,11 @@ public: } } + forcedinline void handleEdgeTableLineFull (const int x, int width) throw() + { + handleEdgeTableLine (x, width, 255); + } + void clipEdgeTableLine (EdgeTable& et, int x, int y_, int width) { if (width > scratchSize) @@ -901,8 +982,8 @@ public: typedef ReferenceCountedObjectPtr Ptr; virtual const Ptr clone() const = 0; - virtual const Ptr applyClipTo (const Ptr& target) const = 0; + virtual const Ptr clipToRectangle (const Rectangle& r) = 0; virtual const Ptr clipToRectangleList (const RectangleList& r) = 0; virtual const Ptr excludeClipRectangle (const Rectangle& r) = 0; @@ -1118,8 +1199,7 @@ public: const Ptr clipToRectangleList (const RectangleList& r) { - EdgeTable et (r); - edgeTable.clipToEdgeTable (et); + edgeTable.clipToEdgeTable (EdgeTable (r)); return edgeTable.isEmpty() ? 0 : this; } @@ -1426,7 +1506,7 @@ public: for (int y = rect.getY(); y < bottom; ++y) { r.setEdgeTableYPos (y); - r.handleEdgeTableLine (x, w, 255); + r.handleEdgeTableLineFull (x, w); } } } @@ -1459,7 +1539,7 @@ private: for (int y = rect.getY(); y < bottom; ++y) { r.setEdgeTableYPos (y); - r.handleEdgeTableLine (x, w, 255); + r.handleEdgeTableLineFull (x, w); } } } @@ -1568,7 +1648,7 @@ private: for (int y = jmax (clipTop, top); y < endY; ++y) { r.setEdgeTableYPos (y); - r.handleEdgeTablePixel (left, 255); + r.handleEdgeTablePixelFull (left); } if (bottomAlpha != 0 && bottom < clipBottom) @@ -1607,7 +1687,7 @@ private: r.handleEdgeTablePixel (totalLeft, leftAlpha); if (clippedWidth > 0) - r.handleEdgeTableLine (clippedLeft, clippedWidth, 255); + r.handleEdgeTableLineFull (clippedLeft, clippedWidth); if (doRightAlpha) r.handleEdgeTablePixel (right, rightAlpha);