From 1f457ff3db24178eefecfbbf177aaf6554adb204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 30 Aug 2007 13:44:20 +0200 Subject: [PATCH] EXA: Improvements for 1x1 pixmaps. Initialize system and FB copy in exaFillRegionSolid and adapt exaGetPixmapFirstPixel to the new migration infrastructure. This should mostly eliminate migration overhead for these, whether they are used for acceleration or fallbacks. --- exa/exa_accel.c | 36 +++++++++++++++++++++++++++++++----- exa/exa_unaccel.c | 22 ++++++++++++++++++---- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/exa/exa_accel.c b/exa/exa_accel.c index e9ca47263..4cae1985e 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -1012,8 +1012,6 @@ exaFillRegionSolid (DrawablePtr pDrawable, PixmapPtr pPixmap; int xoff, yoff; ExaMigrationRec pixmaps[1]; - int nbox = REGION_NUM_RECTS (pRegion); - BoxPtr pBox = REGION_RECTS (pRegion); pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; @@ -1031,15 +1029,43 @@ exaFillRegionSolid (DrawablePtr pDrawable, if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) { + int nbox; + BoxPtr pBox; + + REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); + + nbox = REGION_NUM_RECTS (pRegion); + pBox = REGION_RECTS (pRegion); + while (nbox--) { - (*pExaScr->info->Solid) (pPixmap, - pBox->x1 + xoff, pBox->y1 + yoff, - pBox->x2 + xoff, pBox->y2 + yoff); + (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2, + pBox->y2); pBox++; } (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pDrawable->pScreen); + + if (pDrawable->width == 1 && pDrawable->height == 1 && + pDrawable->bitsPerPixel != 24) { + ExaPixmapPriv(pPixmap); + + switch (pDrawable->bitsPerPixel) { + case 32: + *(CARD32*)pExaPixmap->sys_ptr = pixel; + break; + case 16: + *(CARD16*)pExaPixmap->sys_ptr = pixel; + break; + case 8: + *(CARD8*)pExaPixmap->sys_ptr = pixel; + } + + REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, + pRegion); + } + + REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); } else { diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index 8dadd066d..fbc48dd34 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -358,16 +358,28 @@ exaGetPixmapFirstPixel (PixmapPtr pPixmap) void *fb; Bool need_finish = FALSE; BoxRec box; + RegionRec migration; ExaPixmapPriv (pPixmap); + Bool sys_valid = !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box); + Bool damaged = miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, + &box); + Bool offscreen = exaPixmapIsOffscreen(pPixmap); fb = pExaPixmap->sys_ptr; /* Try to avoid framebuffer readbacks */ - if (exaPixmapIsOffscreen(pPixmap) && - miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box)) + if ((!offscreen && !sys_valid && !damaged) || + (offscreen && (!sys_valid || damaged))) { + box.x1 = 0; + box.y1 = 0; + box.x2 = 1; + box.y2 = 1; + REGION_INIT(pScreen, &migration, &box, 1); + need_finish = TRUE; - exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + + exaPrepareAccessReg(&pPixmap->drawable, EXA_PREPARE_SRC, &migration); fb = pPixmap->devPrivate.ptr; } @@ -383,8 +395,10 @@ exaGetPixmapFirstPixel (PixmapPtr pPixmap) break; } - if (need_finish) + if (need_finish) { exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + REGION_UNINIT(pScreen, &migration); + } return pixel; }