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; }