diff options
author | Adam Jackson <ajax@benzedrine.nwnk.net> | 2007-07-27 13:10:39 -0400 |
---|---|---|
committer | Adam Jackson <ajax@benzedrine.nwnk.net> | 2007-07-27 13:10:39 -0400 |
commit | 486fd4145aed93093d1f1655de40c0a8582bb8b1 (patch) | |
tree | 4f51744f0eacd580ceefdcc72344c23dcdfbf390 /exa | |
parent | 50cb6c7e4419e067c1f080d1de940811d21fc725 (diff) |
exaGetPixmapFirstPixel: avoid framebuffer readbacks if possible.
If the pixel in framebuffer memory isn't modified since we uploaded it, we
can just read from the system memory copy, wihch avoids both a readback and
an accelerator stall.
In principle this function is still wrong, and all the framebuffer pixel
access should be going through (w)fb so we can get pixel layout corrections.
Diffstat (limited to 'exa')
-rw-r--r-- | exa/exa_unaccel.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index 708d1eac6..b67ea6389 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -369,31 +369,48 @@ ExaCheckComposite (CARD8 op, /** * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps * that happen to be 1x1. Pixmap must be at least 8bpp. + * + * XXX This really belongs in fb, so it can be aware of tiling and etc. */ CARD32 exaGetPixmapFirstPixel (PixmapPtr pPixmap) { CARD32 pixel; + void *fb; + Bool need_finish = FALSE; + BoxRec box; ExaMigrationRec pixmaps[1]; + ExaPixmapPriv (pPixmap); + + /* Try to avoid framebuffer readbacks */ + if (exaPixmapIsOffscreen(pPixmap)) { + if (!miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box)) { + fb = pExaPixmap->sys_ptr; + } else { + need_finish = TRUE; + fb = pPixmap->devPrivate.ptr; + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pPix = pPixmap; + exaDoMigration (pixmaps, 1, FALSE); + exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + } + } - pixmaps[0].as_dst = FALSE; - pixmaps[0].as_src = TRUE; - pixmaps[0].pPix = pPixmap; - exaDoMigration (pixmaps, 1, FALSE); - - exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); switch (pPixmap->drawable.bitsPerPixel) { case 32: - pixel = *(CARD32 *)(pPixmap->devPrivate.ptr); + pixel = *(CARD32 *)fb; break; case 16: - pixel = *(CARD16 *)(pPixmap->devPrivate.ptr); + pixel = *(CARD16 *)fb; break; default: - pixel = *(CARD8 *)(pPixmap->devPrivate.ptr); + pixel = *(CARD8 *)fb; break; } - exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + + if (need_finish) + exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); return pixel; } |