View: optimize Fill/StrokePolygon with raw points array argument
Converting points array to `BPolygon` has significant cost, including heap allocation, when drawing a lot of polygons. Change-Id: I81e6b4031bac4beadcc79412c58eedddffc00a82 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10337 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
@@ -40,7 +40,7 @@ private:
|
|||||||
|
|
||||||
bool _AddPoints(const BPoint* points, int32 count,
|
bool _AddPoints(const BPoint* points, int32 count,
|
||||||
bool computeBounds);
|
bool computeBounds);
|
||||||
void _ComputeBounds();
|
static BRect _ComputeBounds(const BPoint* points, uint32 count);
|
||||||
void _MapPoint(BPoint* point, const BRect& source,
|
void _MapPoint(BPoint* point, const BRect& source,
|
||||||
const BRect& destination);
|
const BRect& destination);
|
||||||
void _MapRectangle(BRect* rect, const BRect& source,
|
void _MapRectangle(BRect* rect, const BRect& source,
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ BPolygon::PrintToStream() const
|
|||||||
//BPolygon::TransformBy(const BAffineTransform& transform)
|
//BPolygon::TransformBy(const BAffineTransform& transform)
|
||||||
//{
|
//{
|
||||||
// transform.Apply(fPoints, (int32)fCount);
|
// transform.Apply(fPoints, (int32)fCount);
|
||||||
// _ComputeBounds();
|
// fBounds = _ComputeBounds(fPoints, fCount);
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -177,35 +177,35 @@ BPolygon::_AddPoints(const BPoint* points, int32 count, bool computeBounds)
|
|||||||
fCount += count;
|
fCount += count;
|
||||||
|
|
||||||
if (computeBounds)
|
if (computeBounds)
|
||||||
_ComputeBounds();
|
fBounds = _ComputeBounds(fPoints, fCount);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
BRect
|
||||||
BPolygon::_ComputeBounds()
|
BPolygon::_ComputeBounds(const BPoint* points, uint32 count)
|
||||||
{
|
{
|
||||||
if (fCount == 0) {
|
if (count == 0)
|
||||||
fBounds = BRect(0.0, 0.0, -1.0f, -1.0f);
|
return BRect(0.0, 0.0, -1.0f, -1.0f);
|
||||||
return;
|
|
||||||
|
BRect bounds(points[0], points[0]);
|
||||||
|
|
||||||
|
for (uint32 i = 1; i < count; i++) {
|
||||||
|
if (points[i].x < bounds.left)
|
||||||
|
bounds.left = points[i].x;
|
||||||
|
|
||||||
|
if (points[i].y < bounds.top)
|
||||||
|
bounds.top = points[i].y;
|
||||||
|
|
||||||
|
if (points[i].x > bounds.right)
|
||||||
|
bounds.right = points[i].x;
|
||||||
|
|
||||||
|
if (points[i].y > bounds.bottom)
|
||||||
|
bounds.bottom = points[i].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
fBounds = BRect(fPoints[0], fPoints[0]);
|
return bounds;
|
||||||
|
|
||||||
for (uint32 i = 1; i < fCount; i++) {
|
|
||||||
if (fPoints[i].x < fBounds.left)
|
|
||||||
fBounds.left = fPoints[i].x;
|
|
||||||
|
|
||||||
if (fPoints[i].y < fBounds.top)
|
|
||||||
fBounds.top = fPoints[i].y;
|
|
||||||
|
|
||||||
if (fPoints[i].x > fBounds.right)
|
|
||||||
fBounds.right = fPoints[i].x;
|
|
||||||
|
|
||||||
if (fPoints[i].y > fBounds.bottom)
|
|
||||||
fBounds.bottom = fPoints[i].y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+80
-12
@@ -3611,10 +3611,28 @@ void
|
|||||||
BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, bool closed,
|
BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, bool closed,
|
||||||
::pattern pattern)
|
::pattern pattern)
|
||||||
{
|
{
|
||||||
BPolygon polygon(pointArray, numPoints);
|
if (pointArray == NULL
|
||||||
|
|| numPoints <= 1
|
||||||
|
|| fOwner == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
StrokePolygon(polygon.fPoints, polygon.fCount, polygon.Frame(), closed,
|
BRect bounds = BPolygon::_ComputeBounds(pointArray, numPoints);
|
||||||
pattern);
|
|
||||||
|
_CheckLockAndSwitchCurrent();
|
||||||
|
_UpdatePattern(pattern);
|
||||||
|
|
||||||
|
if (fOwner->fLink->StartMessage(AS_STROKE_POLYGON,
|
||||||
|
numPoints * sizeof(BPoint) + sizeof(BRect) + sizeof(bool)
|
||||||
|
+ sizeof(int32)) == B_OK) {
|
||||||
|
fOwner->fLink->Attach<BRect>(bounds);
|
||||||
|
fOwner->fLink->Attach<bool>(closed);
|
||||||
|
fOwner->fLink->Attach<int32>(numPoints);
|
||||||
|
fOwner->fLink->Attach(pointArray, numPoints * sizeof(BPoint));
|
||||||
|
|
||||||
|
_FlushIfNotInTransaction();
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "ERROR: Can't send polygon to app_server!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3663,10 +3681,28 @@ void
|
|||||||
BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, bool closed,
|
BView::StrokePolygon(const BPoint* pointArray, int32 numPoints, bool closed,
|
||||||
const BGradient& gradient)
|
const BGradient& gradient)
|
||||||
{
|
{
|
||||||
BPolygon polygon(pointArray, numPoints);
|
if (pointArray == NULL
|
||||||
|
|| numPoints <= 1
|
||||||
|
|| fOwner == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
StrokePolygon(polygon.fPoints, polygon.fCount, polygon.Frame(), closed,
|
BRect bounds = BPolygon::_ComputeBounds(pointArray, numPoints);
|
||||||
gradient);
|
|
||||||
|
_CheckLockAndSwitchCurrent();
|
||||||
|
|
||||||
|
if (fOwner->fLink->StartMessage(AS_STROKE_POLYGON_GRADIENT,
|
||||||
|
numPoints * sizeof(BPoint) + sizeof(BRect) + sizeof(bool)
|
||||||
|
+ sizeof(int32)) == B_OK) {
|
||||||
|
fOwner->fLink->Attach<BRect>(bounds);
|
||||||
|
fOwner->fLink->Attach<bool>(closed);
|
||||||
|
fOwner->fLink->Attach<int32>(numPoints);
|
||||||
|
fOwner->fLink->Attach(pointArray, numPoints * sizeof(BPoint));
|
||||||
|
fOwner->fLink->AttachGradient(gradient);
|
||||||
|
|
||||||
|
_FlushIfNotInTransaction();
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "ERROR: Can't send polygon to app_server!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3755,11 +3791,27 @@ BView::FillPolygon(const BPolygon* polygon, const BGradient& gradient)
|
|||||||
void
|
void
|
||||||
BView::FillPolygon(const BPoint* pointArray, int32 numPoints, ::pattern pattern)
|
BView::FillPolygon(const BPoint* pointArray, int32 numPoints, ::pattern pattern)
|
||||||
{
|
{
|
||||||
if (pointArray == NULL)
|
if (pointArray == NULL
|
||||||
|
|| numPoints <= 2
|
||||||
|
|| fOwner == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BPolygon polygon(pointArray, numPoints);
|
BRect bounds = BPolygon::_ComputeBounds(pointArray, numPoints);
|
||||||
FillPolygon(&polygon, pattern);
|
|
||||||
|
_CheckLockAndSwitchCurrent();
|
||||||
|
_UpdatePattern(pattern);
|
||||||
|
|
||||||
|
if (fOwner->fLink->StartMessage(AS_FILL_POLYGON,
|
||||||
|
numPoints * sizeof(BPoint) + sizeof(BRect) + sizeof(int32))
|
||||||
|
== B_OK) {
|
||||||
|
fOwner->fLink->Attach<BRect>(bounds);
|
||||||
|
fOwner->fLink->Attach<int32>(numPoints);
|
||||||
|
fOwner->fLink->Attach(pointArray, numPoints * sizeof(BPoint));
|
||||||
|
|
||||||
|
_FlushIfNotInTransaction();
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "ERROR: Can't send polygon to app_server!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3767,11 +3819,27 @@ void
|
|||||||
BView::FillPolygon(const BPoint* pointArray, int32 numPoints,
|
BView::FillPolygon(const BPoint* pointArray, int32 numPoints,
|
||||||
const BGradient& gradient)
|
const BGradient& gradient)
|
||||||
{
|
{
|
||||||
if (pointArray == NULL)
|
if (pointArray == NULL
|
||||||
|
|| numPoints <= 2
|
||||||
|
|| fOwner == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BPolygon polygon(pointArray, numPoints);
|
BRect bounds = BPolygon::_ComputeBounds(pointArray, numPoints);
|
||||||
FillPolygon(&polygon, gradient);
|
|
||||||
|
_CheckLockAndSwitchCurrent();
|
||||||
|
|
||||||
|
if (fOwner->fLink->StartMessage(AS_FILL_POLYGON_GRADIENT,
|
||||||
|
numPoints * sizeof(BPoint) + sizeof(BRect) + sizeof(int32))
|
||||||
|
== B_OK) {
|
||||||
|
fOwner->fLink->Attach<BRect>(bounds);
|
||||||
|
fOwner->fLink->Attach<int32>(numPoints);
|
||||||
|
fOwner->fLink->Attach(pointArray, numPoints * sizeof(BPoint));
|
||||||
|
fOwner->fLink->AttachGradient(gradient);
|
||||||
|
|
||||||
|
_FlushIfNotInTransaction();
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "ERROR: Can't send polygon to app_server!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user