diff options
author | Eric Anholt <anholt@freebsd.org> | 2006-03-14 21:30:12 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2006-03-14 21:30:12 +0000 |
commit | 693e42114f1127528448126d78a5209dd1198d8d (patch) | |
tree | 4ad88c1d3ae4b2b7b34028c18a771f92ebd5df73 | |
parent | d30905478078036383977ae9d4a3685c2e2c642f (diff) |
Move migration logic to a new function, exaDoMigration(). This is largely a
manual conversion to allow for different migration schemes to be
implemented reasonably, but does include some minor improvements such
as accounting for pinned pixmaps not being acceleratable, and for our
current GetImage and GetSpans not being accelerated.
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | exa/exa.c | 4 | ||||
-rw-r--r-- | exa/exa_accel.c | 166 | ||||
-rw-r--r-- | exa/exa_migration.c | 91 | ||||
-rw-r--r-- | exa/exa_priv.h | 42 | ||||
-rw-r--r-- | exa/exa_render.c | 71 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 11 |
7 files changed, 317 insertions, 87 deletions
@@ -1,5 +1,24 @@ 2006-03-14 Eric Anholt <anholt@FreeBSD.org> + * exa/exa.c: (exaDriverInit): + * exa/exa_accel.c: (exaFillSpans), (exaCopyNtoN), + (exaPolyFillRect), (exaSolidBoxClipped), (exaFillRegionSolid), + (exaFillRegionTiled), (exaGetImage), (exaGetSpans): + * exa/exa_migration.c: (exaPixmapIsPinned), (exaMigrateTowardFb), + (exaMigrateTowardSys), (exaDoMigration): + * exa/exa_priv.h: + * exa/exa_render.c: (exaOpReadsDestination), + (exaTryDriverSolidFill), (exaTryDriverComposite), (exaComposite), + (exaGlyphs): + * exa/exa_unaccel.c: (exaGetPixmapFirstPixel): + Move migration logic to a new function, exaDoMigration(). This is + largely a manual conversion to allow for different migration schemes + to be implemented reasonably, but does include some minor improvements + such as accounting for pinned pixmaps not being acceleratable, and for + our current GetImage and GetSpans not being accelerated. + +2006-03-14 Eric Anholt <anholt@FreeBSD.org> + * exa/exa_accel.c: (exaFillRegionTiled): * exa/exa_priv.h: * exa/exa_render.c: (exaTryDriverSolidFill): @@ -404,10 +404,10 @@ exaDriverInit (ScreenPtr pScreen, pScreen->CreateGC = exaCreateGC; pExaScr->SavedGetImage = pScreen->GetImage; - pScreen->GetImage = ExaCheckGetImage; + pScreen->GetImage = exaGetImage; pExaScr->SavedGetSpans = pScreen->GetSpans; - pScreen->GetSpans = ExaCheckGetSpans; + pScreen->GetSpans = exaGetSpans; pExaScr->SavedCopyWindow = pScreen->CopyWindow; pScreen->CopyWindow = exaCopyWindow; diff --git a/exa/exa_accel.c b/exa/exa_accel.c index ca3afc3ec..7770ef152 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -45,17 +45,25 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, int fullX1, fullX2, fullY1; int partX1, partX2; int off_x, off_y; + ExaMigrationRec pixmaps[1]; + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); - if (pExaScr->swappedOut) { - ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted); - return; + if (pExaScr->swappedOut || + pGC->fillStyle != FillSolid || + pDrawable->width > pExaScr->info->maxX || + pDrawable->height > pExaScr->info->maxY) + { + exaDoMigration (pixmaps, 1, FALSE); + ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); + return; + } else { + exaDoMigration (pixmaps, 1, TRUE); } - if (pGC->fillStyle != FillSolid || - pDrawable->width > pExaScr->info->maxX || - pDrawable->height > pExaScr->info->maxY || - !(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || + if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(*pExaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, @@ -263,6 +271,14 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, PixmapPtr pSrcPixmap, pDstPixmap; int src_off_x, src_off_y; int dst_off_x, dst_off_y; + ExaMigrationRec pixmaps[2]; + + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDstDrawable); + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = exaGetDrawablePixmap (pSrcDrawable); /* Respect maxX/maxY in a trivial way: don't set up drawing when we might * violate the limits. The proper solution would be a temporary pixmap @@ -273,22 +289,10 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, pDstDrawable->width > pExaScr->info->maxX || pDstDrawable->height > pExaScr->info->maxY) { - exaDrawableUseMemory (pSrcDrawable); - exaDrawableUseMemory (pDstDrawable); + exaDoMigration (pixmaps, 2, FALSE); goto fallback; - } - - /* If either drawable is already in framebuffer, try to get both of them - * there. Otherwise, be happy with where they are. - */ - if (exaDrawableIsOffscreen(pDstDrawable) || - exaDrawableIsOffscreen(pSrcDrawable)) - { - exaDrawableUseScreen (pSrcDrawable); - exaDrawableUseScreen (pDstDrawable); } else { - exaDrawableUseMemory (pSrcDrawable); - exaDrawableUseMemory (pDstDrawable); + exaDoMigration (pixmaps, 2, TRUE); } /* Mixed directions must be handled specially if the card is lame */ @@ -367,12 +371,25 @@ exaPolyFillRect(DrawablePtr pDrawable, int xoff, yoff; int xorg, yorg; int n; + ExaMigrationRec pixmaps[1]; + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + if (pExaScr->swappedOut || - pGC->fillStyle != FillSolid || + pGC->fillStyle != FillSolid || pDrawable->width > pExaScr->info->maxX || - pDrawable->height > pExaScr->info->maxY || - !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || + pDrawable->height > pExaScr->info->maxY) + { + exaDoMigration (pixmaps, 1, FALSE); + ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect); + return; + } else { + exaDoMigration (pixmaps, 1, TRUE); + } + + if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(*pExaScr->info->PrepareSolid) (pPixmap, pGC->alu, pGC->planemask, @@ -471,13 +488,27 @@ exaSolidBoxClipped (DrawablePtr pDrawable, int nbox; int xoff, yoff; int partX1, partX2, partY1, partY2; + ExaMigrationRec pixmaps[1]; + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + if (pExaScr->swappedOut || pDrawable->width > pExaScr->info->maxX || - pDrawable->height > pExaScr->info->maxY || - !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || + pDrawable->height > pExaScr->info->maxY) + { + EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable)); + exaDoMigration (pixmaps, 1, FALSE); + goto fallback; + } else { + exaDoMigration (pixmaps, 1, TRUE); + } + + if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg)) { +fallback: EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable)); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel); @@ -724,10 +755,22 @@ exaFillRegionSolid (DrawablePtr pDrawable, ExaScreenPriv(pDrawable->pScreen); PixmapPtr pPixmap; int xoff, yoff; + ExaMigrationRec pixmaps[1]; - if (pDrawable->width <= pExaScr->info->maxX && - pDrawable->height <= pExaScr->info->maxY && - (pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + + if (pDrawable->width > pExaScr->info->maxX || + pDrawable->height > pExaScr->info->maxY) + { + exaDoMigration (pixmaps, 1, FALSE); + goto fallback; + } else { + exaDoMigration (pixmaps, 1, TRUE); + } + + if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && (*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) { int nbox = REGION_NUM_RECTS (pRegion); @@ -746,6 +789,7 @@ exaFillRegionSolid (DrawablePtr pDrawable, } else { +fallback: EXA_FALLBACK(("to 0x%lx\n", (long)pDrawable)); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); fbFillRegionSolid (pDrawable, pRegion, 0, @@ -766,18 +810,11 @@ exaFillRegionTiled (DrawablePtr pDrawable, PixmapPtr pPixmap; int xoff, yoff; int tileWidth, tileHeight; + ExaMigrationRec pixmaps[2]; tileWidth = pTile->drawable.width; tileHeight = pTile->drawable.height; - if (pDrawable->width > pExaScr->info->maxX || - pDrawable->height > pExaScr->info->maxY || - tileWidth > pExaScr->info->maxX || - tileHeight > pExaScr->info->maxY) - { - goto fallback; - } - /* If we're filling with a solid color, grab it out and go to * FillRegionSolid, saving numerous copies. */ @@ -786,11 +823,28 @@ exaFillRegionTiled (DrawablePtr pDrawable, return; } + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = pTile; + + if (pDrawable->width > pExaScr->info->maxX || + pDrawable->height > pExaScr->info->maxY || + tileWidth > pExaScr->info->maxX || + tileHeight > pExaScr->info->maxY) + { + exaDoMigration (pixmaps, 2, FALSE); + goto fallback; + } else { + exaDoMigration (pixmaps, 2, TRUE); + } + pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); if (!pPixmap) goto fallback; - exaPixmapUseScreen(pTile); if (!exaPixmapIsOffscreen(pTile)) goto fallback; @@ -891,3 +945,39 @@ exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) } ExaCheckPaintWindow (pWin, pRegion, what); } + +/** + * GetImage isn't accelerated yet, but performs migration so that we'll + * hopefully avoid the read-from-framebuffer cost. + */ +void +exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, char *d) +{ + ExaMigrationRec pixmaps[1]; + + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + exaDoMigration (pixmaps, 1, FALSE); + + ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d); +} + +/** + * GetSpans isn't accelerated yet, but performs migration so that we'll + * hopefully avoid the read-from-framebuffer cost. + */ +void +exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, + int nspans, char *pdstStart) +{ + ExaMigrationRec pixmaps[1]; + + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); + exaDoMigration (pixmaps, 1, FALSE); + + ExaCheckGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); +} diff --git a/exa/exa_migration.c b/exa/exa_migration.c index 720271cb7..d48abf066 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -40,6 +40,20 @@ #define DBG_MIGRATE(a) #endif +/** + * Returns TRUE if the pixmap is not movable. This is the case where it's a + * fake pixmap for the frontbuffer (no pixmap private) or it's a scratch + * pixmap created by some other X Server internals (the score says it's + * pinned). + */ +static Bool +exaPixmapIsPinned (PixmapPtr pPix) +{ + ExaPixmapPriv (pPix); + + return pExaPixmap == NULL || pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED; +} + static void exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area) { @@ -233,20 +247,8 @@ exaMoveOutPixmap (PixmapPtr pPixmap) } } -void -exaDrawableUseScreen(DrawablePtr pDrawable) -{ - exaPixmapUseScreen (exaGetDrawablePixmap (pDrawable)); -} - -void -exaDrawableUseMemory(DrawablePtr pDrawable) -{ - exaPixmapUseMemory (exaGetDrawablePixmap (pDrawable)); -} - -void -exaPixmapUseScreen (PixmapPtr pPixmap) +static void +exaMigrateTowardFb (PixmapPtr pPixmap) { ExaPixmapPriv (pPixmap); @@ -283,8 +285,8 @@ exaPixmapUseScreen (PixmapPtr pPixmap) ExaOffscreenMarkUsed (pPixmap); } -void -exaPixmapUseMemory (PixmapPtr pPixmap) +static void +exaMigrateTowardSys (PixmapPtr pPixmap) { ExaPixmapPriv (pPixmap); @@ -309,3 +311,60 @@ exaPixmapUseMemory (PixmapPtr pPixmap) if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area) exaMoveOutPixmap (pPixmap); } + +/** + * Performs migration of the pixmaps according to the operation information + * provided in pixmaps and can_accel. In the future, other migration schemes + * may be added, which is facilitated by having this logic all in one place. + */ +void +exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) +{ + ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen; + int i, j; + + /* If anything is pinned in system memory, we won't be able to + * accelerate. + */ + for (i = 0; i < npixmaps; i++) { + if (exaPixmapIsPinned (pixmaps[i].pPix) && + !exaPixmapIsOffscreen (pixmaps[i].pPix)) + { + EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix, + pixmaps[i].pPix->drawable.width, + pixmaps[i].pPix->drawable.height)); + can_accel = FALSE; + break; + } + } + + /* If we can't accelerate, either because the driver can't or because one of + * the pixmaps is pinned in system memory, then we migrate everybody toward + * system memory. + * + * We also migrate toward system if all pixmaps involved are currently in + * system memory -- this can mitigate thrashing when there are significantly + * more pixmaps active than would fit in memory. + * + * If not, then we migrate toward FB so that hopefully acceleration can + * happen. + */ + if (!can_accel) { + for (i = 0; i < npixmaps; i++) + exaMigrateTowardSys (pixmaps[i].pPix); + return; + } + + for (i = 0; i < npixmaps; i++) { + if (exaPixmapIsOffscreen(pixmaps[i].pPix)) { + /* Found one in FB, so move all to FB. */ + for (j = 0; j < npixmaps; j++) + exaMigrateTowardFb(pixmaps[j].pPix); + return; + } + } + + /* Nobody's in FB, so move all away from FB. */ + for (i = 0; i < npixmaps; i++) + exaMigrateTowardSys(pixmaps[i].pPix); +} diff --git a/exa/exa_priv.h b/exa/exa_priv.h index d9f0be1a4..036433266 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -140,6 +140,12 @@ typedef struct { Bool dirty; unsigned int size; } ExaPixmapPrivRec, *ExaPixmapPrivPtr; + +typedef struct _ExaMigrationRec { + Bool as_dst; + Bool as_src; + PixmapPtr pPix; +} ExaMigrationRec, *ExaMigrationPtr; /** * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place @@ -256,6 +262,14 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); void exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what); +void +exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, char *d); + +void +exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, + int nspans, char *pdstStart); + extern const GCOps exaOps, exaAsyncPixmapGCOps; #ifdef RENDER @@ -292,18 +306,6 @@ ExaOffscreenFini (ScreenPtr pScreen); /* exa.c */ void -exaDrawableUseScreen(DrawablePtr pDrawable); - -void -exaDrawableUseMemory(DrawablePtr pDrawable); - -void -exaPixmapUseScreen (PixmapPtr pPixmap); - -void -exaPixmapUseMemory (PixmapPtr pPixmap); - -void exaPrepareAccess(DrawablePtr pDrawable, int index); void @@ -324,12 +326,6 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp); PixmapPtr exaGetDrawablePixmap(DrawablePtr pDrawable); -void -exaMoveInPixmap (PixmapPtr pPixmap); - -void -exaMoveOutPixmap (PixmapPtr pPixmap); - RegionPtr exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty); @@ -372,4 +368,14 @@ exaGlyphs (CARD8 op, GlyphListPtr list, GlyphPtr *glyphs); +/* exa_migration.c */ +void +exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); + +void +exaMoveInPixmap (PixmapPtr pPixmap); + +void +exaMoveOutPixmap (PixmapPtr pPixmap); + #endif /* EXAPRIV_H */ diff --git a/exa/exa_render.c b/exa/exa_render.c index 713817095..41fc8ddeb 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -109,7 +109,25 @@ exaPrintCompositeFallback(CARD8 op, " dst %s, \n", sop, srcdesc, maskdesc, dstdesc); } -#endif +#endif /* DEBUG_TRACE_FALL */ + +static Bool +exaOpReadsDestination (CARD8 op) +{ + /* FALSE (does not read destination) is the list of ops in the protocol + * document with "0" in the "Fb" column and no "Ab" in the "Fa" column. + * That's just Clear and Src. ReduceCompositeOp() will already have + * converted con/disjoint clear/src to Clear or Src. + */ + switch (op) { + case PictOpClear: + case PictOpSrc: + return FALSE; + default: + return TRUE; + } +} + static Bool exaGetPixelFromRGBA(CARD32 *pixel, @@ -152,7 +170,6 @@ exaGetPixelFromRGBA(CARD32 *pixel, return TRUE; } - static Bool exaGetRGBAFromPixel(CARD32 pixel, CARD16 *red, @@ -232,6 +249,7 @@ exaTryDriverSolidFill(PicturePtr pSrc, PixmapPtr pSrcPix, pDstPix; CARD32 pixel; CARD16 red, green, blue, alpha; + ExaMigrationRec pixmaps[1]; xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; @@ -246,7 +264,10 @@ exaTryDriverSolidFill(PicturePtr pSrc, pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); pixel = exaGetPixmapFirstPixel (pSrcPix); - exaDrawableUseScreen(pDst->pDrawable); + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable); + exaDoMigration(pixmaps, 1, TRUE); pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y); if (!pDstPix) { @@ -309,6 +330,7 @@ exaTryDriverComposite(CARD8 op, int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y; PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; struct _Pixmap scratch; + ExaMigrationRec pixmaps[3]; /* Bail if we might exceed coord limits by rendering from/to these. We * should really be making some scratch pixmaps with offsets and coords @@ -347,10 +369,20 @@ exaTryDriverComposite(CARD8 op, return -1; } - exaDrawableUseScreen(pSrc->pDrawable); - if (pMask != NULL) - exaDrawableUseScreen(pMask->pDrawable); - exaDrawableUseScreen(pDst->pDrawable); + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = exaOpReadsDestination(op); + pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable); + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable); + if (pMask) { + pixmaps[2].as_dst = FALSE; + pixmaps[2].as_src = TRUE; + pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable); + exaDoMigration(pixmaps, 3, TRUE); + } else { + exaDoMigration(pixmaps, 2, TRUE); + } pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); if (pMask) @@ -508,13 +540,24 @@ exaComposite(CARD8 op, } if (ret != 0) { + ExaMigrationRec pixmaps[3]; /* failure to accelerate was not due to pixmaps being in the wrong * locations. */ - exaDrawableUseMemory(pSrc->pDrawable); - if (pMask != NULL) - exaDrawableUseMemory(pMask->pDrawable); - exaDrawableUseMemory(pDst->pDrawable); + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = exaOpReadsDestination(op); + pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable); + pixmaps[1].as_dst = FALSE; + pixmaps[1].as_src = TRUE; + pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable); + if (pMask) { + pixmaps[2].as_dst = FALSE; + pixmaps[2].as_src = TRUE; + pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable); + exaDoMigration(pixmaps, 3, FALSE); + } else { + exaDoMigration(pixmaps, 2, FALSE); + } } #if DEBUG_TRACE_FALL @@ -621,6 +664,7 @@ exaGlyphs (CARD8 op, { GCPtr pGC; int maxwidth = 0, maxheight = 0, i; + ExaMigrationRec pixmaps[1]; x += list->xOff; y += list->yOff; @@ -681,7 +725,10 @@ exaGlyphs (CARD8 op, /* Give the temporary pixmap an initial kick towards the screen, so * it'll stick there. */ - exaPixmapUseScreen (pPixmap); + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pPix = pPixmap; + exaDoMigration (pixmaps, 1, TRUE); while (n--) { diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index 361147cea..1ffecb811 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -279,6 +279,11 @@ ExaCheckRestoreAreas (PixmapPtr pPixmap, exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST); } +/* XXX: Note the lack of a prepare on the tile, if the window has a tiled + * background. This function happens to only be called if pExaScr->swappedOut, + * so we actually end up not having to do it since the tile won't be in fb. + * That doesn't make this not dirty, though. + */ void ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what) { @@ -334,8 +339,12 @@ CARD32 exaGetPixmapFirstPixel (PixmapPtr pPixmap) { CARD32 pixel; + ExaMigrationRec pixmaps[1]; - exaDrawableUseMemory(&pPixmap->drawable); + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pPix = pPixmap; + exaDoMigration (pixmaps, 1, TRUE); exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); switch (pPixmap->drawable.bitsPerPixel) { |