mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
EdgeTable: Use HeapBlock instead of vector for better Android Debug drawing performance
This is reverting 417d97b36e.
This commit is contained in:
parent
cc96592e7c
commit
22ee31f3ff
2 changed files with 67 additions and 40 deletions
|
|
@ -47,7 +47,7 @@ EdgeTable::EdgeTable (Rectangle<int> area, const Path& path, const AffineTransfo
|
||||||
lineStrideElements (maxEdgesPerLine * 2 + 1)
|
lineStrideElements (maxEdgesPerLine * 2 + 1)
|
||||||
{
|
{
|
||||||
allocate();
|
allocate();
|
||||||
int* t = table.data();
|
int* t = table;
|
||||||
|
|
||||||
for (int i = bounds.getHeight(); --i >= 0;)
|
for (int i = bounds.getHeight(); --i >= 0;)
|
||||||
{
|
{
|
||||||
|
|
@ -125,7 +125,7 @@ EdgeTable::EdgeTable (Rectangle<int> rectangleToAdd)
|
||||||
|
|
||||||
auto x1 = scale * rectangleToAdd.getX();
|
auto x1 = scale * rectangleToAdd.getX();
|
||||||
auto x2 = scale * rectangleToAdd.getRight();
|
auto x2 = scale * rectangleToAdd.getRight();
|
||||||
int* t = table.data();
|
int* t = table;
|
||||||
|
|
||||||
for (int i = rectangleToAdd.getHeight(); --i >= 0;)
|
for (int i = rectangleToAdd.getHeight(); --i >= 0;)
|
||||||
{
|
{
|
||||||
|
|
@ -227,7 +227,7 @@ EdgeTable::EdgeTable (Rectangle<float> rectangleToAdd)
|
||||||
}
|
}
|
||||||
|
|
||||||
int lineY = 0;
|
int lineY = 0;
|
||||||
int* t = table.data();
|
int* t = table;
|
||||||
|
|
||||||
if ((y1 / scale) == (y2 / scale))
|
if ((y1 / scale) == (y2 / scale))
|
||||||
{
|
{
|
||||||
|
|
@ -278,6 +278,40 @@ EdgeTable::EdgeTable (Rectangle<float> 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
|
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()
|
void EdgeTable::allocate()
|
||||||
{
|
{
|
||||||
table.resize (getEdgeTableAllocationSize (lineStrideElements, bounds.getHeight()));
|
table.malloc (getEdgeTableAllocationSize (lineStrideElements, bounds.getHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeTable::clearLineSizes() noexcept
|
void EdgeTable::clearLineSizes() noexcept
|
||||||
{
|
{
|
||||||
int* t = table.data();
|
int* t = table;
|
||||||
|
|
||||||
for (int i = bounds.getHeight(); --i >= 0;)
|
for (int i = bounds.getHeight(); --i >= 0;)
|
||||||
{
|
{
|
||||||
|
|
@ -304,7 +338,7 @@ void EdgeTable::clearLineSizes() noexcept
|
||||||
void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept
|
void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept
|
||||||
{
|
{
|
||||||
// Convert the table from relative windings to absolute levels..
|
// Convert the table from relative windings to absolute levels..
|
||||||
int* lineStart = table.data();
|
int* lineStart = table;
|
||||||
|
|
||||||
for (int y = bounds.getHeight(); --y >= 0;)
|
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)
|
void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine)
|
||||||
{
|
{
|
||||||
if (newNumEdgesPerLine != maxEdgesPerLine)
|
if (newNumEdgesPerLine != maxEdgesPerLine)
|
||||||
|
|
@ -388,14 +409,14 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine)
|
||||||
jassert (bounds.getHeight() > 0);
|
jassert (bounds.getHeight() > 0);
|
||||||
auto newLineStrideElements = maxEdgesPerLine * 2 + 1;
|
auto newLineStrideElements = maxEdgesPerLine * 2 + 1;
|
||||||
|
|
||||||
std::vector<int> newTable (getEdgeTableAllocationSize (newLineStrideElements, bounds.getHeight()));
|
HeapBlock<int> newTable (getEdgeTableAllocationSize (newLineStrideElements, bounds.getHeight()));
|
||||||
copyEdgeTableData (newTable.data(),
|
copyEdgeTableData (newTable,
|
||||||
(size_t) newLineStrideElements,
|
(size_t) newLineStrideElements,
|
||||||
table.data(),
|
table,
|
||||||
(size_t) lineStrideElements,
|
(size_t) lineStrideElements,
|
||||||
(size_t) bounds.getHeight());
|
(size_t) bounds.getHeight());
|
||||||
|
|
||||||
table = std::move (newTable);
|
table.swapWith (newTable);
|
||||||
lineStrideElements = newLineStrideElements;
|
lineStrideElements = newLineStrideElements;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -420,13 +441,13 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding)
|
||||||
{
|
{
|
||||||
jassert (y >= 0 && y < bounds.getHeight());
|
jassert (y >= 0 && y < bounds.getHeight());
|
||||||
|
|
||||||
auto* line = table.data() + lineStrideElements * y;
|
auto* line = table + lineStrideElements * y;
|
||||||
auto numPoints = line[0];
|
auto numPoints = line[0];
|
||||||
|
|
||||||
if (numPoints >= maxEdgesPerLine)
|
if (numPoints >= maxEdgesPerLine)
|
||||||
{
|
{
|
||||||
remapWithExtraSpace (numPoints);
|
remapWithExtraSpace (numPoints);
|
||||||
line = table.data() + lineStrideElements * y;
|
line = table + lineStrideElements * y;
|
||||||
}
|
}
|
||||||
|
|
||||||
line[0] = numPoints + 1;
|
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());
|
jassert (y >= 0 && y < bounds.getHeight());
|
||||||
|
|
||||||
auto* line = table.data() + lineStrideElements * y;
|
auto* line = table + lineStrideElements * y;
|
||||||
auto numPoints = line[0];
|
auto numPoints = line[0];
|
||||||
|
|
||||||
if (numPoints + 1 >= maxEdgesPerLine)
|
if (numPoints + 1 >= maxEdgesPerLine)
|
||||||
{
|
{
|
||||||
remapWithExtraSpace (numPoints + 1);
|
remapWithExtraSpace (numPoints + 1);
|
||||||
line = table.data() + lineStrideElements * y;
|
line = table + lineStrideElements * y;
|
||||||
}
|
}
|
||||||
|
|
||||||
line[0] = numPoints + 2;
|
line[0] = numPoints + 2;
|
||||||
|
|
@ -460,7 +481,7 @@ void EdgeTable::translate (float dx, int dy) noexcept
|
||||||
{
|
{
|
||||||
bounds.translate ((int) std::floor (dx), dy);
|
bounds.translate ((int) std::floor (dx), dy);
|
||||||
|
|
||||||
int* lineStart = table.data();
|
int* lineStart = table;
|
||||||
auto intDx = (int) (dx * 256.0f);
|
auto intDx = (int) (dx * 256.0f);
|
||||||
|
|
||||||
for (int i = bounds.getHeight(); --i >= 0;)
|
for (int i = bounds.getHeight(); --i >= 0;)
|
||||||
|
|
@ -479,7 +500,7 @@ void EdgeTable::translate (float dx, int dy) noexcept
|
||||||
|
|
||||||
void EdgeTable::multiplyLevels (float amount)
|
void EdgeTable::multiplyLevels (float amount)
|
||||||
{
|
{
|
||||||
int* lineStart = table.data();
|
int* lineStart = table;
|
||||||
auto multiplier = (int) (amount * 256.0f);
|
auto multiplier = (int) (amount * 256.0f);
|
||||||
|
|
||||||
for (int y = 0; y < bounds.getHeight(); ++y)
|
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());
|
jassert (y >= 0 && y < bounds.getHeight());
|
||||||
|
|
||||||
auto* srcLine = table.data() + lineStrideElements * y;
|
auto* srcLine = table + lineStrideElements * y;
|
||||||
const auto srcNum1 = *srcLine;
|
const auto srcNum1 = *srcLine;
|
||||||
|
|
||||||
if (srcNum1 == 0)
|
if (srcNum1 == 0)
|
||||||
|
|
@ -596,15 +617,15 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL
|
||||||
std::copy (srcLine1.begin(), srcLine1.end(), stackBuffer);
|
std::copy (srcLine1.begin(), srcLine1.end(), stackBuffer);
|
||||||
|
|
||||||
remapTableForNumEdges (jmax (256, destTotal * 2));
|
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());
|
std::copy (stackBuffer, stackBuffer + srcLine1.size(), srcLine1.data());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
remapTableForNumEdges (jmax (256, destTotal * 2));
|
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)
|
if (! isUsingTempSpace)
|
||||||
{
|
{
|
||||||
isUsingTempSpace = true;
|
isUsingTempSpace = true;
|
||||||
auto* temp = table.data() + lineStrideElements * bounds.getHeight();
|
auto* temp = table + lineStrideElements * bounds.getHeight();
|
||||||
std::copy (srcLine1.begin(), srcLine1.end(), temp);
|
std::copy (srcLine1.begin(), srcLine1.end(), temp);
|
||||||
reseat (srcLine1, temp);
|
reseat (srcLine1, temp);
|
||||||
}
|
}
|
||||||
|
|
@ -631,7 +652,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL
|
||||||
{
|
{
|
||||||
srcLine[0] = destTotal;
|
srcLine[0] = destTotal;
|
||||||
remapTableForNumEdges (jmax (256, destTotal * 2));
|
remapTableForNumEdges (jmax (256, destTotal * 2));
|
||||||
srcLine = table.data() + lineStrideElements * y;
|
srcLine = table + lineStrideElements * y;
|
||||||
}
|
}
|
||||||
|
|
||||||
++destTotal;
|
++destTotal;
|
||||||
|
|
@ -707,7 +728,7 @@ void EdgeTable::clipToRectangle (Rectangle<int> r)
|
||||||
{
|
{
|
||||||
auto x1 = scale * clipped.getX();
|
auto x1 = scale * clipped.getX();
|
||||||
auto x2 = scale * jmin (bounds.getRight(), clipped.getRight());
|
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;)
|
for (int i = bottom - top; --i >= 0;)
|
||||||
{
|
{
|
||||||
|
|
@ -766,7 +787,7 @@ void EdgeTable::clipToEdgeTable (const EdgeTable& other)
|
||||||
for (int i = 0; i < top; ++i)
|
for (int i = 0; i < top; ++i)
|
||||||
table[(size_t) lineStrideElements * (size_t) i] = 0;
|
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)
|
for (int i = top; i < bottom; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -827,7 +848,7 @@ bool EdgeTable::isEmpty() noexcept
|
||||||
if (needToCheckEmptiness)
|
if (needToCheckEmptiness)
|
||||||
{
|
{
|
||||||
needToCheckEmptiness = false;
|
needToCheckEmptiness = false;
|
||||||
int* t = table.data();
|
int* t = table;
|
||||||
|
|
||||||
for (int i = bounds.getHeight(); --i >= 0;)
|
for (int i = bounds.getHeight(); --i >= 0;)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,12 @@ public:
|
||||||
/** Creates an edge table containing a rectangle list. */
|
/** Creates an edge table containing a rectangle list. */
|
||||||
explicit EdgeTable (const RectangleList<float>& rectanglesToAdd);
|
explicit EdgeTable (const RectangleList<float>& rectanglesToAdd);
|
||||||
|
|
||||||
|
/** Creates a copy of another edge table. */
|
||||||
|
EdgeTable (const EdgeTable&);
|
||||||
|
|
||||||
|
/** Copies from another edge table. */
|
||||||
|
EdgeTable& operator= (const EdgeTable&);
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
void clipToRectangle (Rectangle<int> r);
|
void clipToRectangle (Rectangle<int> r);
|
||||||
void excludeRectangle (Rectangle<int> r);
|
void excludeRectangle (Rectangle<int> r);
|
||||||
|
|
@ -111,7 +117,7 @@ public:
|
||||||
template <class EdgeTableIterationCallback>
|
template <class EdgeTableIterationCallback>
|
||||||
void iterate (EdgeTableIterationCallback& iterationCallback) const noexcept
|
void iterate (EdgeTableIterationCallback& iterationCallback) const noexcept
|
||||||
{
|
{
|
||||||
const int* lineStart = table.data();
|
const int* lineStart = table;
|
||||||
|
|
||||||
for (int y = 0; y < bounds.getHeight(); ++y)
|
for (int y = 0; y < bounds.getHeight(); ++y)
|
||||||
{
|
{
|
||||||
|
|
@ -204,7 +210,7 @@ private:
|
||||||
bool operator< (const LineItem& other) const noexcept { return x < other.x; }
|
bool operator< (const LineItem& other) const noexcept { return x < other.x; }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<int> table;
|
HeapBlock<int> table;
|
||||||
Rectangle<int> bounds;
|
Rectangle<int> bounds;
|
||||||
int maxEdgesPerLine, lineStrideElements;
|
int maxEdgesPerLine, lineStrideElements;
|
||||||
bool needToCheckEmptiness = true;
|
bool needToCheckEmptiness = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue