diff options
author | Michel Dänzer <daenzer@vmware.com> | 2009-09-26 01:59:39 +0200 |
---|---|---|
committer | Michel Dänzer <daenzer@vmware.com> | 2009-09-26 01:59:39 +0200 |
commit | 1818cbd70fc1f2e1487b4c678e67e28f1265c0ef (patch) | |
tree | c19cc48b73ed6885079f48a321aa775068fae57e | |
parent | e23bffc41b007f1bc2b8f5cd4ac54213062c95cc (diff) |
EXA: Extend mixed pixmaps scheme to allow driver PrepareAccess hook to fail.
If the PrepareAccess hook fails, use the DownloadFromScreen hook to retrieve
driver pixmap contents to a system RAM copy, perform software rendering on that
and copy the results back using the UploadToScreen hook. Use the classic
migration logic to minimize transfers (which as a bonus allows slightly
cleaning up some of the existing mixed pixmap code).
This enables things that weren't possible before with driver-allocated pixmap
storage: If some (or all) GPU pixmap storage can't be mapped directly by the
CPU, this can be handled between the PrepareAccess and
DownloadFrom/UploadToScreen hooks, e.g.:
* Radeon KMS on big endian machines can fail PrepareAccess if the pixmap
requires byte-swapping and swap bytes in DownloadFrom/UploadToScreen.
* Environments where GPU and CPU don't have a shared address space at all.
Here the driver PrepareAccess hook will always fail and leave all transfers
between GPU / CPU storage to the Download/From/UploadToScreen hooks.
Drivers which can handle all pixmaps in the PrepareAccess hook should notice
little if any difference.
-rw-r--r-- | exa/exa.c | 78 | ||||
-rw-r--r-- | exa/exa_migration_classic.c | 30 | ||||
-rw-r--r-- | exa/exa_migration_mixed.c | 179 | ||||
-rw-r--r-- | exa/exa_mixed.c | 87 | ||||
-rw-r--r-- | exa/exa_priv.h | 22 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 52 |
6 files changed, 232 insertions, 216 deletions
@@ -288,7 +288,6 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp) Bool -ExaDoPrepareAccess(DrawablePtr pDrawable, int index) +ExaDoPrepareAccess(PixmapPtr pPixmap, int index) { - ScreenPtr pScreen = pDrawable->pScreen; + ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv (pScreen); - PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); ExaPixmapPriv(pPixmap); @@ -326,3 +325,3 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) - if (offscreen) + if (offscreen && pExaPixmap->fb_ptr) pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; @@ -335,16 +334,6 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) - if (!offscreen) { - /* Do we need to allocate our system buffer? */ - if ((pExaScr->info->flags & EXA_HANDLES_PIXMAPS) && (pExaScr->info->flags & EXA_MIXED_PIXMAPS)) { - if (!pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap)) { - pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch * pDrawable->height); - if (!pExaPixmap->sys_ptr) - FatalError("EXA: malloc failed for size %d bytes\n", pExaPixmap->sys_pitch * pDrawable->height); - pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; - } - } + if (!offscreen) return FALSE; - } - exaWaitSync (pDrawable->pScreen); + exaWaitSync (pScreen); @@ -362,3 +351,4 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) { - if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) + if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED && + !(pExaScr->info->flags & EXA_MIXED_PIXMAPS)) FatalError("Driver failed PrepareAccess on a pinned pixmap.\n"); @@ -372,27 +362,2 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) -void -exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg) -{ - PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); - ExaScreenPriv(pPixmap->drawable.pScreen); - - if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[1]; - - if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - } else { - pixmaps[0].as_dst = FALSE; - pixmaps[0].as_src = TRUE; - } - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = pReg; - - exaDoMigration(pixmaps, 1, FALSE); - } - - ExaDoPrepareAccess(pDrawable, index); -} - /** @@ -406,3 +371,9 @@ exaPrepareAccess(DrawablePtr pDrawable, int index) { - exaPrepareAccessReg(pDrawable, index, NULL); + PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); + ExaScreenPriv(pDrawable->pScreen); + + if (pExaScr->prepare_access_reg) + pExaScr->prepare_access_reg(pPixmap, index, NULL); + else + (void)ExaDoPrepareAccess(pPixmap, index); } @@ -434,3 +405,2 @@ exaFinishAccess(DrawablePtr pDrawable, int index) return; - index = i; break; @@ -444,3 +414,3 @@ exaFinishAccess(DrawablePtr pDrawable, int index) - pExaScr->access[index].pixmap = NULL; + pExaScr->access[i].pixmap = NULL; @@ -449,9 +419,9 @@ exaFinishAccess(DrawablePtr pDrawable, int index) - if (pExaScr->info->FinishAccess == NULL) - return; + if (pExaScr->finish_access) + pExaScr->finish_access(pPixmap, index); - if (!exaPixmapIsOffscreen (pPixmap)) + if (!pExaScr->info->FinishAccess || !exaPixmapIsOffscreen(pPixmap)) return; - if (index >= EXA_PREPARE_AUX_DEST && + if (i >= EXA_PREPARE_AUX_DEST && !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) { @@ -462,3 +432,3 @@ exaFinishAccess(DrawablePtr pDrawable, int index) - (*pExaScr->info->FinishAccess) (pPixmap, index); + (*pExaScr->info->FinishAccess) (pPixmap, i); } @@ -539,3 +509,3 @@ exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth, */ - ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); + ExaDoPrepareAccess(pPixmap, EXA_PREPARE_AUX_DEST); @@ -1073,2 +1043,4 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->do_move_out_pixmap = NULL; + pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed; + pExaScr->finish_access = exaFinishAccess_mixed; } else { @@ -1081,2 +1053,4 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->do_move_out_pixmap = NULL; + pExaScr->prepare_access_reg = NULL; + pExaScr->finish_access = NULL; } @@ -1090,2 +1064,4 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic; + pExaScr->prepare_access_reg = exaPrepareAccessReg_classic; + pExaScr->finish_access = NULL; } diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c index d8e1e86da..0032f02f9 100644 --- a/exa/exa_migration_classic.c +++ b/exa/exa_migration_classic.c @@ -122,3 +122,3 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, /* Damaged bits are valid in current copy but invalid in other one */ - if (exaPixmapIsOffscreen(pPixmap)) { + if (pExaPixmap->offscreen) { REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB, @@ -227,3 +227,3 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, if (!access_prepared) { - ExaDoPrepareAccess(&pPixmap->drawable, fallback_index); + ExaDoPrepareAccess(pPixmap, fallback_index); access_prepared = TRUE; @@ -265,3 +265,3 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, */ -static void +void exaCopyDirtyToSys (ExaMigrationPtr migrate) @@ -283,3 +283,3 @@ exaCopyDirtyToSys (ExaMigrationPtr migrate) */ -static void +void exaCopyDirtyToFb (ExaMigrationPtr migrate) @@ -547,3 +547,3 @@ exaAssertNotDirty (PixmapPtr pPixmap) - if (!ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC)) + if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC)) goto skip; @@ -720 +720,21 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) } + +void +exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg) +{ + ExaMigrationRec pixmaps[1]; + + if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + } else { + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + } + pixmaps[0].pPix = pPixmap; + pixmaps[0].pReg = pReg; + + exaDoMigration(pixmaps, 1, FALSE); + + (void)ExaDoPrepareAccess(pPixmap, index); +} diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c index d1ee9871b..f42c9c233 100644 --- a/exa/exa_migration_mixed.c +++ b/exa/exa_migration_mixed.c @@ -33,36 +33,2 @@ -static void -exaUploadFallback(PixmapPtr pPixmap, CARD8 *src, int src_pitch) -{ - ExaPixmapPriv(pPixmap); - RegionPtr damage = DamageRegion (pExaPixmap->pDamage); - GCPtr pGC = GetScratchGC (pPixmap->drawable.depth, - pPixmap->drawable.pScreen); - int nbox, cpp = pPixmap->drawable.bitsPerPixel / 8; - DamagePtr backup = pExaPixmap->pDamage; - BoxPtr pbox; - CARD8 *src2; - - /* We don't want damage optimisations. */ - pExaPixmap->pDamage = NULL; - ValidateGC (&pPixmap->drawable, pGC); - - pbox = REGION_RECTS(damage); - nbox = REGION_NUM_RECTS(damage); - - while (nbox--) { - src2 = src + pbox->y1 * src_pitch + pbox->x1 * cpp; - - ExaCheckPutImage(&pPixmap->drawable, pGC, - pPixmap->drawable.depth, pbox->x1, pbox->y1, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 0, - ZPixmap, (char*) src2); - - pbox++; - } - - FreeScratchGC (pGC); - pExaPixmap->pDamage = backup; -} - void @@ -73,4 +39,2 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap) ExaPixmapPriv(pPixmap); - RegionPtr damage = DamageRegion (pExaPixmap->pDamage); - void *sys_buffer = pExaPixmap->sys_ptr; int w = pPixmap->drawable.width, h = pPixmap->drawable.height; @@ -78,6 +42,3 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap) int usage_hint = pPixmap->usage_hint; - int sys_pitch = pExaPixmap->sys_pitch; - int paddedWidth = sys_pitch; - int nbox; - BoxPtr pbox; + int paddedWidth = pExaPixmap->sys_pitch; @@ -107,46 +68,4 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap) - pExaPixmap->offscreen = TRUE; - pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr = NULL; - pExaPixmap->sys_pitch = pPixmap->devKind = 0; - - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0, paddedWidth, NULL); - - /* scratch pixmaps */ - if (!w || !h) - goto finish; - - /* we do not malloc memory by default. */ - if (!sys_buffer) - goto finish; - - if (!pExaScr->info->UploadToScreen) - goto fallback; - - pbox = REGION_RECTS(damage); - nbox = REGION_NUM_RECTS(damage); - - while (nbox--) { - if (!pExaScr->info->UploadToScreen(pPixmap, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1, (char *) (sys_buffer) + pbox->y1 * sys_pitch + pbox->x1 * (bpp / 8), sys_pitch)) - goto fallback; - - pbox++; - } - - goto finish; - -fallback: - exaUploadFallback(pPixmap, sys_buffer, sys_pitch); - -finish: - free(sys_buffer); - - /* We no longer need this. */ - if (pExaPixmap->pDamage) { - DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); - DamageDestroy(pExaPixmap->pDamage); - pExaPixmap->pDamage = NULL; - } } @@ -177,4 +96,12 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) ExaPixmapPriv(pPixmap); + if (!pExaPixmap->driverPriv) exaCreateDriverPixmap_mixed(pPixmap); + + if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) { + pPixmap->devKind = pExaPixmap->fb_pitch; + exaCopyDirtyToFb(pixmaps + i); + } + + pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap); } @@ -194 +121,89 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap) } + +/* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we + * use the DownloadFromScreen hook to retrieve contents to a copy in system + * memory, perform software rendering on that and move back the results with the + * UploadToScreen hook (see exaFinishAccess_mixed). + */ +void +exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) +{ + if (!ExaDoPrepareAccess(pPixmap, index)) { + ExaPixmapPriv(pPixmap); + Bool is_offscreen = exaPixmapIsOffscreen(pPixmap); + ExaMigrationRec pixmaps[1]; + + /* Do we need to allocate our system buffer? */ + if (!pExaPixmap->sys_ptr) { + pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch * + pPixmap->drawable.height); + if (!pExaPixmap->sys_ptr) + FatalError("EXA: malloc failed for size %d bytes\n", + pExaPixmap->sys_pitch * pPixmap->drawable.height); + } + + if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + } else { + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + } + pixmaps[0].pPix = pPixmap; + pixmaps[0].pReg = pReg; + + if (!pExaPixmap->pDamage && (is_offscreen || !exaPixmapIsPinned(pPixmap))) { + Bool as_dst = pixmaps[0].as_dst; + + /* Set up damage tracking */ + pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone, + TRUE, pPixmap->drawable.pScreen, + pPixmap); + + DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage); + /* This ensures that pending damage reflects the current operation. */ + /* This is used by exa to optimize migration. */ + DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE); + + if (is_offscreen) { + exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, + pPixmap->drawable.height); + + /* We don't know which region of the destination will be damaged, + * have to assume all of it + */ + if (as_dst) { + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pReg = NULL; + } + pPixmap->devKind = pExaPixmap->fb_pitch; + exaCopyDirtyToSys(pixmaps); + } + + if (as_dst) + exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, + pPixmap->drawable.height); + } else if (is_offscreen) { + pPixmap->devKind = pExaPixmap->fb_pitch; + exaCopyDirtyToSys(pixmaps); + } + + pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; + pPixmap->devKind = pExaPixmap->sys_pitch; + pExaPixmap->offscreen = FALSE; + } +} + +/* Move back results of software rendering on system memory copy of mixed driver + * pixmap (see exaPrepareAccessReg_mixed). + */ +void exaFinishAccess_mixed(PixmapPtr pPixmap, int index) +{ + ExaPixmapPriv(pPixmap); + + if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) { + DamageRegionProcessPending(&pPixmap->drawable); + exaMoveInPixmap_mixed(pPixmap); + } +} diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c index 6aa73f2b6..167ffa9d5 100644 --- a/exa/exa_mixed.c +++ b/exa/exa_mixed.c @@ -34,4 +34,2 @@ /* This file holds the driver allocated pixmaps + better initial placement code. - * A pinned pixmap implies one that is either driver based already or otherwise altered. - * Proper care is taken to free the initially allocated buffer. */ @@ -48,5 +46,2 @@ ExaGetPixmapAddress(PixmapPtr p) * exaCreatePixmap() creates a new pixmap. - * - * Pixmaps are always marked as pinned, unless the pixmap can still be transfered to a - * driver pixmaps. */ @@ -87,3 +82,2 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, pExaPixmap->area = NULL; - pExaPixmap->offscreen = FALSE; pExaPixmap->fb_ptr = NULL; @@ -95,5 +89,2 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, - /* Avoid freeing sys_ptr. */ - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; - (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0, @@ -101,5 +92,2 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, - /* We want to be able to transfer the pixmap to driver memory later on. */ - pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; - /* A scratch pixmap will become a driver pixmap right away. */ @@ -107,20 +95,5 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, exaCreateDriverPixmap_mixed(pPixmap); - } else { - /* Set up damage tracking */ - pExaPixmap->pDamage = DamageCreate (NULL, NULL, - DamageReportNone, TRUE, - pScreen, pPixmap); - - if (pExaPixmap->pDamage == NULL) { - swap(pExaScr, pScreen, DestroyPixmap); - pScreen->DestroyPixmap (pPixmap); - swap(pExaScr, pScreen, DestroyPixmap); - return NULL; - } - - DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); - /* This ensures that pending damage reflects the current operation. */ - /* This is used by exa to optimize migration. */ - DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); - } + pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap); + } else + pExaPixmap->offscreen = FALSE; @@ -136,3 +109,3 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, ExaPixmapPrivPtr pExaPixmap; - Bool ret; + Bool ret, is_offscreen; @@ -144,9 +117,4 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, - if (pExaPixmap) { - if (!exaPixmapIsPinned(pPixmap)) { - free(pExaPixmap->sys_ptr); - pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr = NULL; - pExaPixmap->sys_pitch = pPixmap->devKind = 0; - - /* We no longer need this. */ + if (pPixData) { + if (pExaPixmap->driverPriv) { if (pExaPixmap->pDamage) { @@ -156,10 +124,12 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, } - } - if (pPixData) - pExaPixmap->sys_ptr = pPixData; + pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); + pExaPixmap->driverPriv = NULL; + } - if (devKind > 0) - pExaPixmap->sys_pitch = devKind; + pExaPixmap->offscreen = FALSE; + pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; + } + if (pExaPixmap->driverPriv) { if (width > 0 && height > 0 && bitsPerPixel > 0) { @@ -171,5 +141,11 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, } + } - /* Anything can happen, don't try to predict it all. */ - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; + is_offscreen = exaPixmapIsOffscreen(pPixmap); + if (is_offscreen) { + pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; + pPixmap->devKind = pExaPixmap->fb_pitch; + } else { + pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; + pPixmap->devKind = pExaPixmap->sys_pitch; } @@ -184,6 +160,2 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, */ - if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) { - pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; - pExaPixmap->sys_pitch = pPixmap->devKind; - } if (ret == TRUE) @@ -198,2 +170,9 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, out: + if (is_offscreen) { + pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr; + pExaPixmap->fb_pitch = pPixmap->devKind; + } else { + pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; + pExaPixmap->sys_pitch = pPixmap->devKind; + } /* Always NULL this, we don't want lingering pointers. */ @@ -217,6 +196,10 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap) pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); - else if (pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap)) - free(pExaPixmap->sys_ptr); pExaPixmap->driverPriv = NULL; - pExaPixmap->sys_ptr = NULL; + + if (pExaPixmap->pDamage) { + if (pExaPixmap->sys_ptr) + free(pExaPixmap->sys_ptr); + pExaPixmap->sys_ptr = NULL; + pExaPixmap->pDamage = NULL; + } } diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 869cf1772..1aec8e966 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -178,2 +178,4 @@ typedef struct { void (*do_move_out_pixmap) (PixmapPtr pPixmap); + void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg); + void (*finish_access)(PixmapPtr pPixmap, int index); @@ -513,6 +515,3 @@ ExaOffscreenFini (ScreenPtr pScreen); Bool -ExaDoPrepareAccess(DrawablePtr pDrawable, int index); - -void -exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg); +ExaDoPrepareAccess(PixmapPtr pPixmap, int index); @@ -611,2 +610,8 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap); +void +exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg); + +void +exaFinishAccess_mixed(PixmapPtr pPixmap, int index); + /* exa_render.c */ @@ -667,2 +672,8 @@ exaGlyphs (CARD8 op, void +exaCopyDirtyToSys (ExaMigrationPtr migrate); + +void +exaCopyDirtyToFb (ExaMigrationPtr migrate); + +void exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); @@ -678,2 +689,5 @@ exaMoveInPixmap_classic (PixmapPtr pPixmap); +void +exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg); + #endif /* EXAPRIV_H */ diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index f4700adac..c8f017243 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -103,3 +103,5 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, { - ExaPixmapPriv(exaGetDrawablePixmap(pDrawable)); + PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); + ExaPixmapPriv(pPixmap); + ExaScreenPriv(pDrawable->pScreen); @@ -107,3 +109,4 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, + if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage || + exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, pGC->alu, pGC->clientClipType)) @@ -111,4 +114,4 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, else - exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ? - DamagePendingRegion(pExaPixmap->pDamage) : NULL); + pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, + DamagePendingRegion(pExaPixmap->pDamage)); pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); @@ -325,5 +328,2 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, { - BoxRec Box; - RegionRec Reg; - int xoff, yoff; ScreenPtr pScreen = pDrawable->pScreen; @@ -335,12 +335,20 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, - exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff); + if (pExaScr->prepare_access_reg) { + int xoff, yoff; + BoxRec Box; + RegionRec Reg; + + exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff); + + Box.x1 = pDrawable->y + x + xoff; + Box.y1 = pDrawable->y + y + yoff; + Box.x2 = Box.x1 + w; + Box.y2 = Box.y1 + h; - Box.x1 = pDrawable->y + x + xoff; - Box.y1 = pDrawable->y + y + yoff; - Box.x2 = Box.x1 + w; - Box.y2 = Box.y1 + h; + REGION_INIT(pScreen, &Reg, &Box, 1); - REGION_INIT(pScreen, &Reg, &Box, 1); + pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, &Reg); + } else + exaPrepareAccess(pDrawable, EXA_PREPARE_SRC); - exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg); swap(pExaScr, pScreen, GetImage); @@ -403,3 +411,5 @@ ExaCheckComposite (CARD8 op, - if (!exaOpReadsDestination(op)) { + if (!exaOpReadsDestination(op) && pExaScr->prepare_access_reg) { + PixmapPtr pDstPix; + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, @@ -409,6 +419,4 @@ ExaCheckComposite (CARD8 op, - exaGetDrawableDeltas (pDst->pDrawable, - exaGetDrawablePixmap(pDst->pDrawable), - &xoff, &yoff); - + pDstPix = exaGetDrawablePixmap(pDst->pDrawable); + exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff); REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); @@ -416,6 +424,6 @@ ExaCheckComposite (CARD8 op, if (pDst->alphaMap && pDst->alphaMap->pDrawable) - exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST, - ®ion); + pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), + EXA_PREPARE_AUX_DEST, ®ion); - exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion); + pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, ®ion); } else { |