From 0690e6bc161c341368113534fc608c6654b6bdbb Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Fri, 2 Mar 2007 00:33:23 +0000 Subject: [PATCH] added fast path to BPicture polygon drawing git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20296 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/ServerPicture.cpp | 115 ++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 36 deletions(-) diff --git a/src/servers/app/ServerPicture.cpp b/src/servers/app/ServerPicture.cpp index 15e8b1c2e6..d3a6e77808 100644 --- a/src/servers/app/ServerPicture.cpp +++ b/src/servers/app/ServerPicture.cpp @@ -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 nop() { @@ -252,58 +281,72 @@ fill_ellipse(ViewLayer *view, BPoint center, BPoint radii) static void stroke_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints, bool isClosed) { - BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); - if (!points) + if (numPoints <= 0) { 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++) { - if (points[i].x < polyFrame.left) - polyFrame.left = points[i].x; - if (points[i].y < polyFrame.top) - polyFrame.top = points[i].y; - if (points[i].x > polyFrame.right) - polyFrame.right = points[i].x; - if (points[i].y > polyFrame.bottom) - polyFrame.bottom = points[i].y; + view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + view->CurrentState(), false, + isClosed && numPoints > 2); + } else { + // avoid constructor/destructor calls by using malloc instead of new [] + BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); + if (!points) + return; + + 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 fill_polygon(ViewLayer *view, int32 numPoints, const BPoint *viewPoints) { - BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); - if (!points) + if (numPoints <= 0) { 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++) { - if (points[i].x < polyFrame.left) - polyFrame.left = points[i].x; - if (points[i].y < polyFrame.top) - polyFrame.top = points[i].y; - if (points[i].x > polyFrame.right) - polyFrame.right = points[i].x; - if (points[i].y > polyFrame.bottom) - polyFrame.bottom = points[i].y; + view->Window()->GetDrawingEngine()->DrawPolygon(points, numPoints, polyFrame, + view->CurrentState(), true, true); + } else { + // avoid constructor/destructor calls by using malloc instead of new [] + BPoint *points = (BPoint *)malloc(numPoints * sizeof(BPoint)); + if (!points) + return; + + 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); }