diff options
Diffstat (limited to 'exa/exa.c')
-rw-r--r-- | exa/exa.c | 514 |
1 files changed, 165 insertions, 349 deletions
@@ -48,17 +48,6 @@ DevPrivateKey exaGCPrivateKey = &exaGCPrivateKeyIndex; static ShmFuncs exaShmFuncs = { NULL, NULL }; #endif -static _X_INLINE void* -ExaGetPixmapAddress(PixmapPtr p) -{ - ExaPixmapPriv(p); - - if (pExaPixmap->offscreen && pExaPixmap->fb_ptr) - return pExaPixmap->fb_ptr; - else - return pExaPixmap->sys_ptr; -} - /** * exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of * the beginning of the given pixmap. @@ -178,45 +167,6 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2) REGION_UNINIT(pScreen, ®ion); } -static Bool -exaDestroyPixmap (PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - ExaScreenPriv(pScreen); - Bool ret; - - if (pPixmap->refcnt == 1) - { - ExaPixmapPriv (pPixmap); - - if (pExaPixmap->driverPriv) { - pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); - pExaPixmap->driverPriv = NULL; - } - - if (pExaPixmap->area) - { - DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n", - (void*)pPixmap->drawable.id, - ExaGetPixmapPriv(pPixmap)->area->offset, - pPixmap->drawable.width, - pPixmap->drawable.height)); - /* Free the offscreen area */ - exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area); - pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; - pPixmap->devKind = pExaPixmap->sys_pitch; - } - REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validSys); - REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validFB); - } - - swap(pExaScr, pScreen, DestroyPixmap); - ret = pScreen->DestroyPixmap (pPixmap); - swap(pExaScr, pScreen, DestroyPixmap); - - return ret; -} - static int exaLog2(int val) { @@ -229,14 +179,14 @@ exaLog2(int val) return bits - 1; } -static void +void exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, int w, int h, int bpp) { pExaPixmap->accel_blocked = 0; if (pExaScr->info->maxPitchPixels) { - int max_pitch = pExaScr->info->maxPitchPixels * (bpp + 7) / 8; + int max_pitch = pExaScr->info->maxPitchPixels * bits_to_bytes(bpp); if (pExaPixmap->fb_pitch > max_pitch) pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; @@ -253,238 +203,33 @@ exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT; } -static void +void exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, int w, int h, int bpp) { if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1) - pExaPixmap->fb_pitch = ((1 << (exaLog2(w - 1) + 1)) * bpp + 7) / 8; + pExaPixmap->fb_pitch = bits_to_bytes((1 << (exaLog2(w - 1) + 1)) * bpp); else - pExaPixmap->fb_pitch = (w * bpp + 7) / 8; + pExaPixmap->fb_pitch = bits_to_bytes(w * bpp); pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch, pExaScr->info->pixmapPitchAlign); } /** - * exaCreatePixmap() creates a new pixmap. - * - * If width and height are 0, this won't be a full-fledged pixmap and it will - * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because - * ModifyPixmapHeader() would break migration. These types of pixmaps are used - * for scratch pixmaps, or to represent the visible screen. + * Returns TRUE if the pixmap is not movable. This is the case where it's a + * pixmap which has no private (almost always bad) or it's a scratch pixmap created by + * some X Server internal component (the score says it's pinned). */ -static PixmapPtr -exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint) -{ - PixmapPtr pPixmap; - ExaPixmapPrivPtr pExaPixmap; - BoxRec box; - int driver_alloc = 0; - int bpp; - ExaScreenPriv(pScreen); - - if (w > 32767 || h > 32767) - return NullPixmap; - - swap(pExaScr, pScreen, CreatePixmap); - if (!pExaScr->info->CreatePixmap && !pExaScr->info->CreatePixmap2) { - pPixmap = pScreen->CreatePixmap (pScreen, w, h, depth, usage_hint); - } else { - driver_alloc = 1; - pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); - } - swap(pExaScr, pScreen, CreatePixmap); - - if (!pPixmap) - return NULL; - - pExaPixmap = ExaGetPixmapPriv(pPixmap); - pExaPixmap->driverPriv = NULL; - - bpp = pPixmap->drawable.bitsPerPixel; - - if (driver_alloc) { - size_t paddedWidth, datasize; - - paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); - if (paddedWidth / 4 > 32767 || h > 32767) - return NullPixmap; - - exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); - - if (paddedWidth < pExaPixmap->fb_pitch) - paddedWidth = pExaPixmap->fb_pitch; - - datasize = h * paddedWidth; - - /* Set this before driver hooks, to allow for !offscreen pixmaps. - * !offscreen pixmaps have a valid pointer at all times. - */ - pPixmap->devPrivate.ptr = NULL; - - if (pExaScr->info->CreatePixmap2) - pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp); - else - pExaPixmap->driverPriv = pExaScr->info->CreatePixmap(pScreen, datasize, 0); - if (!pExaPixmap->driverPriv) { - swap(pExaScr, pScreen, DestroyPixmap); - pScreen->DestroyPixmap (pPixmap); - swap(pExaScr, pScreen, DestroyPixmap); - return NULL; - } - - /* Allow ModifyPixmapHeader to set sys_ptr appropriately. */ - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; - pExaPixmap->fb_ptr = NULL; - pExaPixmap->pDamage = NULL; - pExaPixmap->sys_ptr = NULL; - - (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0, - paddedWidth, NULL); - - } else { - pExaPixmap->driverPriv = NULL; - /* Scratch pixmaps may have w/h equal to zero, and may not be - * migrated. - */ - if (!w || !h) - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; - else - pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; - - pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; - pExaPixmap->sys_pitch = pPixmap->devKind; - - pPixmap->devPrivate.ptr = NULL; - pExaPixmap->offscreen = FALSE; - - pExaPixmap->fb_ptr = NULL; - exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); - pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; - - if (pExaPixmap->fb_pitch > 131071) { - swap(pExaScr, pScreen, DestroyPixmap); - pScreen->DestroyPixmap (pPixmap); - swap(pExaScr, pScreen, DestroyPixmap); - return NULL; - } - - /* 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->area = NULL; - - /* We set the initial pixmap as completely valid for a simple reason. - * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which - * could form single pixel rects as part of a region. Setting the complete region - * as valid is a natural defragmentation of the region. - */ - box.x1 = 0; - box.y1 = 0; - box.x2 = w; - box.y2 = h; - REGION_INIT(pScreen, &pExaPixmap->validSys, &box, 0); - REGION_INIT(pScreen, &pExaPixmap->validFB, &box, 0); - - exaSetAccelBlock(pExaScr, pExaPixmap, - w, h, bpp); - - return pPixmap; -} - -static Bool -exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData) +Bool +exaPixmapIsPinned (PixmapPtr pPix) { - ExaScreenPrivPtr pExaScr; - ExaPixmapPrivPtr pExaPixmap; - Bool ret; - - if (!pPixmap) - return FALSE; - - pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen); - pExaPixmap = ExaGetPixmapPriv(pPixmap); - - if (pExaPixmap) { - if (pPixData) - pExaPixmap->sys_ptr = pPixData; - - if (devKind > 0) - pExaPixmap->sys_pitch = devKind; - - /* Classic EXA: - * - Framebuffer. - * - Scratch pixmap with offscreen memory. - */ - if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) && - pExaScr->info->memoryBase && pPixData) { - if ((CARD8 *)pPixData >= pExaScr->info->memoryBase && - ((CARD8 *)pPixData - pExaScr->info->memoryBase) < - pExaScr->info->memorySize) { - pExaPixmap->fb_ptr = pPixData; - pExaPixmap->fb_pitch = devKind; - pExaPixmap->offscreen = TRUE; - } - } - - if (width > 0 && height > 0 && bitsPerPixel > 0) { - exaSetFbPitch(pExaScr, pExaPixmap, - width, height, bitsPerPixel); - - exaSetAccelBlock(pExaScr, pExaPixmap, - width, height, bitsPerPixel); - } - - /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or - * offscreen memory, so there's no need to track damage. - */ - if (pExaPixmap->pDamage) { - DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); - DamageDestroy(pExaPixmap->pDamage); - pExaPixmap->pDamage = NULL; - } - } - - if (pExaScr->info->ModifyPixmapHeader) { - ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth, - bitsPerPixel, devKind, pPixData); - /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL. - * If pPixmap->devPrivate.ptr is non-NULL, then we've got a non-offscreen pixmap. - * We need to store the pointer, because PrepareAccess won't be called. - */ - if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) { - pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; - pExaPixmap->sys_pitch = pPixmap->devKind; - } - if (ret == TRUE) - goto out; - } - ret = pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth, - bitsPerPixel, devKind, pPixData); + ExaPixmapPriv (pPix); -out: - /* Always NULL this, we don't want lingering pointers. */ - pPixmap->devPrivate.ptr = NULL; + if (pExaPixmap == NULL) + EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsPinned was called on a non-exa pixmap.\n"), TRUE); - return ret; + return pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED; } /** @@ -500,21 +245,15 @@ out: * @return TRUE if the given drawable is in framebuffer memory. */ Bool -exaPixmapIsOffscreen(PixmapPtr p) +exaPixmapIsOffscreen(PixmapPtr pPixmap) { - ScreenPtr pScreen = p->drawable.pScreen; + ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); - ExaPixmapPriv(p); - Bool ret; - if (pExaScr->info->PixmapIsOffscreen) { - p->devPrivate.ptr = ExaGetPixmapAddress(p); - ret = pExaScr->info->PixmapIsOffscreen(p); - p->devPrivate.ptr = NULL; - } else - ret = (pExaPixmap->offscreen && pExaPixmap->fb_ptr); + if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) + return FALSE; - return ret; + return (*pExaScr->pixmap_is_offscreen)(pPixmap); } /** @@ -554,6 +293,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); ExaPixmapPriv(pPixmap); Bool offscreen; + int i; if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return FALSE; @@ -561,19 +301,25 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) if (pExaPixmap == NULL) EXA_FatalErrorDebugWithRet(("EXA bug: ExaDoPrepareAccess was called on a non-exa pixmap.\n"), FALSE); - /* Check if we're dealing SRC == DST or similar. - * In that case the first PrepareAccess has already set pPixmap->devPrivate.ptr. - */ - if (pPixmap->devPrivate.ptr != NULL) { - int i; - for (i = 0; i < 6; i++) - if (pExaScr->prepare_access[i] == pPixmap) + /* Handle repeated / nested calls. */ + for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) { + if (pExaScr->access[i].pixmap == pPixmap) { + pExaScr->access[i].count++; + return TRUE; + } + } + + /* If slot for this index is taken, find an empty slot */ + if (pExaScr->access[index].pixmap) { + for (index = EXA_NUM_PREPARE_INDICES - 1; index >= 0; index--) + if (!pExaScr->access[index].pixmap) break; + } - /* No known PrepareAccess or double prepare on the same index. */ - if (i == 6 || i == index) - EXA_FatalErrorDebug(("EXA bug: pPixmap->devPrivate.ptr was %p, but should have been NULL.\n", - pPixmap->devPrivate.ptr)); + /* Access to this pixmap hasn't been prepared yet, so data pointer should be NULL. */ + if (pPixmap->devPrivate.ptr != NULL) { + EXA_FatalErrorDebug(("EXA bug: pPixmap->devPrivate.ptr was %p, but should have been NULL.\n", + pPixmap->devPrivate.ptr)); } offscreen = exaPixmapIsOffscreen(pPixmap); @@ -583,11 +329,22 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) else pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; - /* Store so we can check SRC and DEST being the same. */ - pExaScr->prepare_access[index] = pPixmap; - - if (!offscreen) + /* Store so we can handle repeated / nested calls. */ + pExaScr->access[index].pixmap = pPixmap; + pExaScr->access[index].count = 1; + + 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; + } + } return FALSE; + } exaWaitSync (pDrawable->pScreen); @@ -616,19 +373,24 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) void exaPrepareAccessReg(DrawablePtr pDrawable, 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 = exaGetDrawablePixmap (pDrawable); - pixmaps[0].pReg = pReg; + PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); + ExaScreenPriv(pPixmap->drawable.pScreen); - exaDoMigration(pixmaps, 1, FALSE); + 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); } @@ -657,6 +419,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index) ExaScreenPriv (pScreen); PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); ExaPixmapPriv (pPixmap); + int i; if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) return; @@ -664,11 +427,22 @@ exaFinishAccess(DrawablePtr pDrawable, int index) if (pExaPixmap == NULL) EXA_FatalErrorDebugWithRet(("EXA bug: exaFinishAccesss was called on a non-exa pixmap.\n"),); - /* Avoid mismatching indices. */ - if (pExaScr->prepare_access[index] != pPixmap) - EXA_FatalErrorDebug(("EXA bug: Calling FinishAccess on pixmap %p with index %d while " - "it should have been %p.\n", pPixmap, index, pExaScr->prepare_access[index])); - pExaScr->prepare_access[index] = NULL; + /* Handle repeated / nested calls. */ + for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) { + if (pExaScr->access[i].pixmap == pPixmap) { + if (--pExaScr->access[i].count > 0) + return; + index = i; + break; + } + } + + /* Catch unbalanced Prepare/FinishAccess calls. */ + if (i == EXA_NUM_PREPARE_INDICES) + EXA_FatalErrorDebug(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n", + pPixmap)); + + pExaScr->access[index].pixmap = NULL; /* We always hide the devPrivate.ptr. */ pPixmap->devPrivate.ptr = NULL; @@ -763,15 +537,7 @@ exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth, * For EXA_HANDLES_PIXMAPS the driver will handle whatever is needed. * We want to signal that the pixmaps will be used as destination. */ - if (pExaScr->prepare_access[EXA_PREPARE_DEST] == NULL) { - ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST); - pExaScr->prepare_access[EXA_PREPARE_DEST] = pPixmap; - } else if (pExaScr->prepare_access[EXA_PREPARE_AUX_DEST] == NULL) { - ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); - pExaScr->prepare_access[EXA_PREPARE_AUX_DEST] = pPixmap; - } else { - FatalError("exaCreatePixmapWithPrepare can only accomodate two pixmaps, we're at three.\n"); - } + ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); return pPixmap; } @@ -781,12 +547,9 @@ exaDestroyPixmapWithFinish(PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); - int i; Bool ret; - for (i = 0; i < 6; i++) - if (pExaScr->prepare_access[i] == pPixmap) - exaFinishAccess(&pPixmap->drawable, i); + exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); /* This swaps between this function and the real upper layer function. * Normally this would swap to the fb layer pointer, this is a very special case. @@ -848,8 +611,8 @@ exaValidateGC(GCPtr pGC, (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable); - if (pExaScr->prepare_access[EXA_PREPARE_SRC]) /* tile */ - exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_SRC]->drawable, EXA_PREPARE_SRC); + if (pTile) + exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC); if (pGC->stipple) exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); @@ -863,13 +626,6 @@ exaValidateGC(GCPtr pGC, /* restore copy of fb layer pointer. */ pExaScr->SavedDestroyPixmap = old_ptr2; - if (pExaScr->prepare_access[EXA_PREPARE_DEST]) - exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_DEST]->drawable, - EXA_PREPARE_DEST); - if (pExaScr->prepare_access[EXA_PREPARE_AUX_DEST]) - exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_AUX_DEST]->drawable, - EXA_PREPARE_AUX_DEST); - EXA_GC_EPILOGUE(pGC); } @@ -979,10 +735,10 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask) ret = pScreen->ChangeWindowAttributes(pWin, mask); swap(pExaScr, pScreen, ChangeWindowAttributes); - if (pExaScr->prepare_access[EXA_PREPARE_SRC]) /* background */ - exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_SRC]->drawable, EXA_PREPARE_SRC); - if (pExaScr->prepare_access[EXA_PREPARE_MASK]) /* border */ - exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_MASK]->drawable, EXA_PREPARE_MASK); + if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) + exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); + if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) + exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK); /* switch back to the normal upper layer. */ unwrap(pExaScr, pScreen, CreatePixmap); @@ -994,13 +750,6 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask) /* restore copy of fb layer pointer. */ pExaScr->SavedDestroyPixmap = old_ptr2; - if (pExaScr->prepare_access[EXA_PREPARE_DEST]) - exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_DEST]->drawable, - EXA_PREPARE_DEST); - if (pExaScr->prepare_access[EXA_PREPARE_AUX_DEST]) - exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_AUX_DEST]->drawable, - EXA_PREPARE_AUX_DEST); - return ret; } @@ -1313,10 +1062,33 @@ exaDriverInit (ScreenPtr pScreen, pScreen->myNum); return FALSE; } - wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap); - wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap); - - wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader); + if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) { + if (pExaScr->info->flags & EXA_MIXED_PIXMAPS) { + wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_mixed); + wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed); + wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_mixed); + pExaScr->do_migration = exaDoMigration_mixed; + pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_mixed; + pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed; + pExaScr->do_move_out_pixmap = NULL; + } else { + wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver); + wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver); + wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_driver); + pExaScr->do_migration = NULL; + pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_driver; + pExaScr->do_move_in_pixmap = NULL; + pExaScr->do_move_out_pixmap = NULL; + } + } else { + wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic); + wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic); + wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_classic); + pExaScr->do_migration = exaDoMigration_classic; + pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_classic; + pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic; + pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic; + } if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) { LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n", pScreen->myNum, @@ -1414,3 +1186,47 @@ void exaWaitSync(ScreenPtr pScreen) pExaScr->info->needsSync = FALSE; } } + +/** + * Performs migration of the pixmaps according to the operation information + * provided in pixmaps and can_accel and the migration scheme chosen in the + * config file. + */ +void +exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) +{ + ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen; + ExaScreenPriv(pScreen); + + if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) + return; + + if (pExaScr->do_migration) + (*pExaScr->do_migration)(pixmaps, npixmaps, can_accel); +} + +void +exaMoveInPixmap (PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); + + if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) + return; + + if (pExaScr->do_move_in_pixmap) + (*pExaScr->do_move_in_pixmap)(pPixmap); +} + +void +exaMoveOutPixmap (PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); + + if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) + return; + + if (pExaScr->do_move_out_pixmap) + (*pExaScr->do_move_out_pixmap)(pPixmap); +} |