From cb887cfc670bf63993bd313ff33927afb8198eae Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 26 Mar 2010 09:59:51 +0000 Subject: uxa: solid rects The cost of performing relocations outweigh the advantages of using the blitter for solids with lots of rectangles. References: Bug 22127 - [UXA] 50% performance regression for XRenderFillRectangles https://bugs.freedesktop.org/show_bug.cgi?id=22127 By using the 3D pipeline we improve our performance by around 4x on i945, measured by the jxbench microbenchmark, and a factor of 10x by short-cutting to the 3D pipeline for blended rectangles. Before, on a i945GME: 19982.412060 Ops/s; rects (!); 15x15 9599.131693 Ops/s; rects (!); 75x75 3803.654743 Ops/s; rects (!); 250x250 6836.743772 Ops/s; rects blended; 15x15 1443.750000 Ops/s; rects blended; 75x75 495.335821 Ops/s; rects blended; 250x250 23247.933884 Ops/s; rects composition (!); 15x15 10993.073048 Ops/s; rects composition (!); 75x75 3595.905172 Ops/s; rects composition (!); 250x250 After: 87271.145975 Ops/s; rects (!); 15x15 32347.744361 Ops/s; rects (!); 75x75 5884.177215 Ops/s; rects (!); 250x250 73500.000000 Ops/s; rects blended; 15x15 33580.882353 Ops/s; rects blended; 75x75 5858.811749 Ops/s; rects blended; 250x250 25582.317073 Ops/s; rects composition (!); 15x15 6664.728682 Ops/s; rects composition (!); 75x75 14965.909091 Ops/s; rects composition (!); 250x250 [suspicious] This has no impact on Cairo, but I have a suspicion from watching xtrace that Qt likes to blit thousands of 1x1 rectangles with the same colour. However, we are still around 2-3x slower than the reported figures for EXA! Signed-off-by: Chris Wilson --- uxa/uxa-priv.h | 8 +++++++ uxa/uxa-render.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ uxa/uxa.c | 4 ++++ 3 files changed, 81 insertions(+) diff --git a/uxa/uxa-priv.h b/uxa/uxa-priv.h index c1f3688c..a4763b41 100644 --- a/uxa/uxa-priv.h +++ b/uxa/uxa-priv.h @@ -156,6 +156,7 @@ typedef struct { BitmapToRegionProcPtr SavedBitmapToRegion; #ifdef RENDER CompositeProcPtr SavedComposite; + CompositeRectsProcPtr SavedCompositeRects; TrianglesProcPtr SavedTriangles; GlyphsProcPtr SavedGlyphs; TrapezoidsProcPtr SavedTrapezoids; @@ -416,6 +417,13 @@ uxa_composite_rects(CARD8 op, PicturePtr pSrc, PicturePtr pDst, int nrect, uxa_composite_rect_t * rects); +void +uxa_solid_rects (CARD8 op, + PicturePtr dst, + xRenderColor *color, + int num_rects, + xRectangle *rects); + void uxa_trapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c index 244d2746..f8105aff 100644 --- a/uxa/uxa-render.c +++ b/uxa/uxa-render.c @@ -828,6 +828,75 @@ uxa_acquire_mask(ScreenPtr screen, out_x, out_y); } +void +uxa_solid_rects (CARD8 op, + PicturePtr dst, + xRenderColor *color, + int num_rects, + xRectangle *rects) +{ + ScreenPtr screen = dst->pDrawable->pScreen; + uxa_screen_t *uxa_screen = uxa_get_screen(screen); + PixmapPtr pixmap; + int dst_x, dst_y; + PicturePtr src; + int error; + + /* Using GEM, the relocation costs outweigh the advantages of the blitter */ + if (num_rects == 1) + goto fallback; + + if (dst->alphaMap) + goto fallback; + + if (!uxa_screen->info->check_composite_texture) + goto fallback; + + pixmap = uxa_get_offscreen_pixmap(dst->pDrawable, &dst_x, &dst_y); + if (!pixmap) + goto fallback; + + if (op == PictOpClear) + color->red = color->green = color->blue = color->alpha = 0; + if (PICT_FORMAT_A(dst->format) == 0) + color->alpha = 0xffff; + if (color->alpha >= 0xff00 && op == PictOpOver) + op = PictOpSrc; + + src = CreateSolidPicture(0, color, &error); + if (!src) + goto fallback; + + if (!uxa_screen->info->check_composite(op, src, NULL, dst) || + !uxa_screen->info->check_composite_texture(screen, src)) { + FreePicture(src, 0); + goto fallback; + } + + if (!uxa_screen->info->prepare_composite(op, src, NULL, dst, NULL, NULL, pixmap)) { + FreePicture(src, 0); + goto fallback; + } + + while (num_rects--) { + uxa_screen->info->composite(pixmap, + 0, 0, 0, 0, + rects->x + dst_x, + rects->y + dst_y, + rects->width, + rects->height); + rects++; + } + + uxa_screen->info->done_composite(pixmap); + FreePicture(src, 0); + + return; + +fallback: + uxa_screen->SavedCompositeRects(op, dst, color, num_rects, rects); +} + static int uxa_try_driver_composite_rects(CARD8 op, PicturePtr pSrc, diff --git a/uxa/uxa.c b/uxa/uxa.c index d6ad5a63..9ea14662 100644 --- a/uxa/uxa.c +++ b/uxa/uxa.c @@ -388,6 +388,7 @@ static Bool uxa_close_screen(int i, ScreenPtr pScreen) #ifdef RENDER if (ps) { ps->Composite = uxa_screen->SavedComposite; + ps->CompositeRects = uxa_screen->SavedCompositeRects; ps->Glyphs = uxa_screen->SavedGlyphs; ps->Trapezoids = uxa_screen->SavedTrapezoids; ps->AddTraps = uxa_screen->SavedAddTraps; @@ -517,6 +518,9 @@ Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver) uxa_screen->SavedComposite = ps->Composite; ps->Composite = uxa_composite; + uxa_screen->SavedCompositeRects = ps->CompositeRects; + ps->CompositeRects = uxa_solid_rects; + uxa_screen->SavedGlyphs = ps->Glyphs; ps->Glyphs = uxa_glyphs; -- cgit v1.2.3