From 22ee31f3ff13ef6585736ccba54622356c8cd8d7 Mon Sep 17 00:00:00 2001 From: attila Date: Thu, 25 Jul 2024 10:57:29 +0200 Subject: [PATCH] EdgeTable: Use HeapBlock instead of vector for better Android Debug drawing performance This is reverting 417d97b36e0f47763eaca0087ee1ecc8bbc543c4. --- .../juce_graphics/geometry/juce_EdgeTable.cpp | 97 +++++++++++-------- .../juce_graphics/geometry/juce_EdgeTable.h | 10 +- 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.cpp b/modules/juce_graphics/geometry/juce_EdgeTable.cpp index 17d8607cd8..94593e80f4 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.cpp +++ b/modules/juce_graphics/geometry/juce_EdgeTable.cpp @@ -47,7 +47,7 @@ EdgeTable::EdgeTable (Rectangle area, const Path& path, const AffineTransfo lineStrideElements (maxEdgesPerLine * 2 + 1) { allocate(); - int* t = table.data(); + int* t = table; for (int i = bounds.getHeight(); --i >= 0;) { @@ -125,7 +125,7 @@ EdgeTable::EdgeTable (Rectangle rectangleToAdd) auto x1 = scale * rectangleToAdd.getX(); auto x2 = scale * rectangleToAdd.getRight(); - int* t = table.data(); + int* t = table; for (int i = rectangleToAdd.getHeight(); --i >= 0;) { @@ -227,7 +227,7 @@ EdgeTable::EdgeTable (Rectangle rectangleToAdd) } int lineY = 0; - int* t = table.data(); + int* t = table; if ((y1 / scale) == (y2 / scale)) { @@ -278,6 +278,40 @@ EdgeTable::EdgeTable (Rectangle rectangleToAdd) } } +static void copyEdgeTableData (int* dest, + size_t destLineStride, + const int* src, + size_t srcLineStride, + size_t numLines) noexcept +{ + for (size_t line = 0; line < numLines; ++line) + { + const auto* srcLine = src + line * srcLineStride; + std::copy (srcLine, srcLine + *srcLine * 2 + 1, dest + line * destLineStride); + } +} + +EdgeTable::EdgeTable (const EdgeTable& other) +{ + operator= (other); +} + +EdgeTable& EdgeTable::operator= (const EdgeTable& other) +{ + bounds = other.bounds; + maxEdgesPerLine = other.maxEdgesPerLine; + lineStrideElements = other.lineStrideElements; + needToCheckEmptiness = other.needToCheckEmptiness; + + allocate(); + copyEdgeTableData (table, + (size_t) lineStrideElements, + other.table, + (size_t) lineStrideElements, + (size_t) bounds.getHeight()); + return *this; +} + //============================================================================== static size_t getEdgeTableAllocationSize (int lineStride, int height) noexcept { @@ -287,12 +321,12 @@ static size_t getEdgeTableAllocationSize (int lineStride, int height) noexcept void EdgeTable::allocate() { - table.resize (getEdgeTableAllocationSize (lineStrideElements, bounds.getHeight())); + table.malloc (getEdgeTableAllocationSize (lineStrideElements, bounds.getHeight())); } void EdgeTable::clearLineSizes() noexcept { - int* t = table.data(); + int* t = table; for (int i = bounds.getHeight(); --i >= 0;) { @@ -304,7 +338,7 @@ void EdgeTable::clearLineSizes() noexcept void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept { // Convert the table from relative windings to absolute levels.. - int* lineStart = table.data(); + int* lineStart = table; for (int y = bounds.getHeight(); --y >= 0;) { @@ -365,19 +399,6 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept } } -static void copyEdgeTableData (int* dest, - size_t destLineStride, - const int* src, - size_t srcLineStride, - size_t numLines) noexcept -{ - for (size_t line = 0; line < numLines; ++line) - { - const auto* srcLine = src + line * srcLineStride; - std::copy (srcLine, srcLine + *srcLine * 2 + 1, dest + line * destLineStride); - } -} - void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) { if (newNumEdgesPerLine != maxEdgesPerLine) @@ -388,14 +409,14 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) jassert (bounds.getHeight() > 0); auto newLineStrideElements = maxEdgesPerLine * 2 + 1; - std::vector newTable (getEdgeTableAllocationSize (newLineStrideElements, bounds.getHeight())); - copyEdgeTableData (newTable.data(), + HeapBlock newTable (getEdgeTableAllocationSize (newLineStrideElements, bounds.getHeight())); + copyEdgeTableData (newTable, (size_t) newLineStrideElements, - table.data(), + table, (size_t) lineStrideElements, (size_t) bounds.getHeight()); - table = std::move (newTable); + table.swapWith (newTable); lineStrideElements = newLineStrideElements; } } @@ -420,13 +441,13 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding) { jassert (y >= 0 && y < bounds.getHeight()); - auto* line = table.data() + lineStrideElements * y; + auto* line = table + lineStrideElements * y; auto numPoints = line[0]; if (numPoints >= maxEdgesPerLine) { remapWithExtraSpace (numPoints); - line = table.data() + lineStrideElements * y; + line = table + lineStrideElements * y; } line[0] = numPoints + 1; @@ -439,13 +460,13 @@ void EdgeTable::addEdgePointPair (int x1, int x2, int y, int winding) { jassert (y >= 0 && y < bounds.getHeight()); - auto* line = table.data() + lineStrideElements * y; + auto* line = table + lineStrideElements * y; auto numPoints = line[0]; if (numPoints + 1 >= maxEdgesPerLine) { remapWithExtraSpace (numPoints + 1); - line = table.data() + lineStrideElements * y; + line = table + lineStrideElements * y; } line[0] = numPoints + 2; @@ -460,7 +481,7 @@ void EdgeTable::translate (float dx, int dy) noexcept { bounds.translate ((int) std::floor (dx), dy); - int* lineStart = table.data(); + int* lineStart = table; auto intDx = (int) (dx * 256.0f); for (int i = bounds.getHeight(); --i >= 0;) @@ -479,7 +500,7 @@ void EdgeTable::translate (float dx, int dy) noexcept void EdgeTable::multiplyLevels (float amount) { - int* lineStart = table.data(); + int* lineStart = table; auto multiplier = (int) (amount * 256.0f); for (int y = 0; y < bounds.getHeight(); ++y) @@ -500,7 +521,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL { jassert (y >= 0 && y < bounds.getHeight()); - auto* srcLine = table.data() + lineStrideElements * y; + auto* srcLine = table + lineStrideElements * y; const auto srcNum1 = *srcLine; if (srcNum1 == 0) @@ -596,15 +617,15 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL std::copy (srcLine1.begin(), srcLine1.end(), stackBuffer); remapTableForNumEdges (jmax (256, destTotal * 2)); - srcLine = table.data() + lineStrideElements * y; + srcLine = table + lineStrideElements * y; - reseat (srcLine1, table.data() + lineStrideElements * bounds.getHeight()); + reseat (srcLine1, table + lineStrideElements * bounds.getHeight()); std::copy (stackBuffer, stackBuffer + srcLine1.size(), srcLine1.data()); } else { remapTableForNumEdges (jmax (256, destTotal * 2)); - srcLine = table.data() + lineStrideElements * y; + srcLine = table + lineStrideElements * y; } } @@ -614,7 +635,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL if (! isUsingTempSpace) { isUsingTempSpace = true; - auto* temp = table.data() + lineStrideElements * bounds.getHeight(); + auto* temp = table + lineStrideElements * bounds.getHeight(); std::copy (srcLine1.begin(), srcLine1.end(), temp); reseat (srcLine1, temp); } @@ -631,7 +652,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL { srcLine[0] = destTotal; remapTableForNumEdges (jmax (256, destTotal * 2)); - srcLine = table.data() + lineStrideElements * y; + srcLine = table + lineStrideElements * y; } ++destTotal; @@ -707,7 +728,7 @@ void EdgeTable::clipToRectangle (Rectangle r) { auto x1 = scale * clipped.getX(); auto x2 = scale * jmin (bounds.getRight(), clipped.getRight()); - int* line = table.data() + lineStrideElements * top; + int* line = table + lineStrideElements * top; for (int i = bottom - top; --i >= 0;) { @@ -766,7 +787,7 @@ void EdgeTable::clipToEdgeTable (const EdgeTable& other) for (int i = 0; i < top; ++i) table[(size_t) lineStrideElements * (size_t) i] = 0; - auto* otherLine = other.table.data() + other.lineStrideElements * (clipped.getY() - other.bounds.getY()); + auto* otherLine = other.table + other.lineStrideElements * (clipped.getY() - other.bounds.getY()); for (int i = top; i < bottom; ++i) { @@ -827,7 +848,7 @@ bool EdgeTable::isEmpty() noexcept if (needToCheckEmptiness) { needToCheckEmptiness = false; - int* t = table.data(); + int* t = table; for (int i = bounds.getHeight(); --i >= 0;) { diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.h b/modules/juce_graphics/geometry/juce_EdgeTable.h index 1e3c4c6300..1f4df7e18c 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.h +++ b/modules/juce_graphics/geometry/juce_EdgeTable.h @@ -72,6 +72,12 @@ public: /** Creates an edge table containing a rectangle list. */ explicit EdgeTable (const RectangleList& rectanglesToAdd); + /** Creates a copy of another edge table. */ + EdgeTable (const EdgeTable&); + + /** Copies from another edge table. */ + EdgeTable& operator= (const EdgeTable&); + //============================================================================== void clipToRectangle (Rectangle r); void excludeRectangle (Rectangle r); @@ -111,7 +117,7 @@ public: template void iterate (EdgeTableIterationCallback& iterationCallback) const noexcept { - const int* lineStart = table.data(); + const int* lineStart = table; for (int y = 0; y < bounds.getHeight(); ++y) { @@ -204,7 +210,7 @@ private: bool operator< (const LineItem& other) const noexcept { return x < other.x; } }; - std::vector table; + HeapBlock table; Rectangle bounds; int maxEdgesPerLine, lineStrideElements; bool needToCheckEmptiness = true;