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 <chris@chris-wilson.co.uk>
This commit is contained in:
parent
c8e10f7791
commit
cb887cfc67
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue