added fast path to BPicture polygon drawing

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20296 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen
2007-03-02 00:33:23 +00:00
parent c8b7e8185a
commit 0690e6bc16
+79 -36
View File
@@ -133,6 +133,35 @@ ShapePainter::Draw(ViewLayer *view, BRect frame, bool filled)
} }
} }
static void
get_polygon_frame(const BPoint *points, int32 numPoints, BRect *_frame)
{
float l, t, r, b;
ASSERT(numPoints > 0);
l = r = points->x;
t = b = points->y;
points++;
numPoints--;
while (numPoints--) {
if (points->x < l)
l = points->x;
if (points->x > r)
r = points->x;
if (points->y < t)
t = points->y;
if (points->y > b)
b = points->y;
points++;
}
_frame->Set(l, t, r, b);
}
static void static void
nop() nop()
{ {
@@ -252,58 +281,72 @@ fill_ellipse(ViewLayer *view, BPoint center, BPoint radii)
static void static void
stroke_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints, bool isClosed) stroke_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints, bool isClosed)
{ {
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); if (numPoints <= 0) {
if (!points)
return; return;
} else if (numPoints <= 200) {
// fast path: no malloc/free, also avoid constructor/destructor calls
char data[200 * sizeof(BPoint)];
BPoint *points = (BPoint *)data;
view->ConvertToScreenForDrawing(points, viewPoints, numPoints); view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame = BRect(points[0], points[0]); BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
for (int32 i = 1; i < numPoints; i++) { view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
if (points[i].x < polyFrame.left) view->CurrentState(), false,
polyFrame.left = points[i].x; isClosed && numPoints > 2);
if (points[i].y < polyFrame.top) } else {
polyFrame.top = points[i].y; // avoid constructor/destructor calls by using malloc instead of new []
if (points[i].x > polyFrame.right) BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
polyFrame.right = points[i].x; if (!points)
if (points[i].y > polyFrame.bottom) return;
polyFrame.bottom = points[i].y;
view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
view->CurrentState(), false,
isClosed && numPoints > 2);
free(points);
} }
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->CurrentState(),
false, isClosed && numPoints > 2);
free(points);
} }
static void static void
fill_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints) fill_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints)
{ {
BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); if (numPoints <= 0) {
if (!points)
return; return;
} else if (numPoints <= 200) {
// fast path: no malloc/free, also avoid constructor/destructor calls
char data[200 * sizeof(BPoint)];
BPoint *points = (BPoint *)data;
view->ConvertToScreenForDrawing(points, viewPoints, numPoints); view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame = BRect(points[0], points[0]); BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
for (int32 i = 1; i < numPoints; i++) { view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
if (points[i].x < polyFrame.left) view->CurrentState(), true, true);
polyFrame.left = points[i].x; } else {
if (points[i].y < polyFrame.top) // avoid constructor/destructor calls by using malloc instead of new []
polyFrame.top = points[i].y; BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint));
if (points[i].x > polyFrame.right) if (!points)
polyFrame.right = points[i].x; return;
if (points[i].y > polyFrame.bottom)
polyFrame.bottom = points[i].y; view->ConvertToScreenForDrawing(points, viewPoints, numPoints);
BRect polyFrame;
get_polygon_frame(points, numPoints, &polyFrame);
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame,
view->CurrentState(), true, true);
free(points);
} }
view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, view->CurrentState(),
true, true);
free(points);
} }