/** * For the "greedy" migration scheme, pushes the pixmap toward being located in * system memory. */ static void exaMigrateTowardSys (PixmapPtr pPixmap) { ExaPixmapPriv (pPixmap); if (pExaPixmap == NULL) { DBG_MIGRATE(("UseMem: ignoring exa-uncontrolled pixmap %p (%s)\n", (pointer)pPixmap, exaPixmapIsOffscreen(pPixmap) ? "s" : "m")); return; } DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)pPixmap, pExaPixmap->score)); if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) return; if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) pExaPixmap->score = 0; if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN) pExaPixmap->score--; if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area) exaMoveOutPixmap (pPixmap); }
/** * Copies out important pixmap data and removes references to framebuffer area. * Called when the memory manager decides it's time to kick the pixmap out of * framebuffer entirely. */ void exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area) { PixmapPtr pPixmap = area->privData; ExaPixmapPriv(pPixmap); RegionPtr pDamageReg = DamageRegion(pExaPixmap->pDamage); DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap, (void*)(ExaGetPixmapPriv(pPixmap)->area ? ExaGetPixmapPriv(pPixmap)->area->offset : 0), pPixmap->drawable.width, pPixmap->drawable.height, exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); if (exaPixmapIsOffscreen(pPixmap)) { exaCopyDirtyToSys (pPixmap); pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devKind = pExaPixmap->sys_pitch; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; } pExaPixmap->fb_ptr = NULL; pExaPixmap->area = NULL; /* Mark all valid bits as damaged, so they'll get copied to FB next time */ REGION_UNION(pPixmap->drawable.pScreen, pDamageReg, pDamageReg, &pExaPixmap->validReg); }
/** * For the "greedy" migration scheme, pushes the pixmap toward being located in * system memory. */ static void exaMigrateTowardSys(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaPixmapPriv(pPixmap); DBG_MIGRATE(("UseMem: %p score %d\n", (pointer) pPixmap, pExaPixmap->score)); if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) return; if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) pExaPixmap->score = 0; if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN) pExaPixmap->score--; if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area) exaDoMoveOutPixmap(migrate); if (exaPixmapHasGpuCopy(pPixmap)) { exaCopyDirtyToFb(migrate); ExaOffscreenMarkUsed(pPixmap); } else exaCopyDirtyToSys(migrate); }
/** * Switches the current active location of the pixmap to system memory, copying * updated data out if necessary. */ static void exaDoMoveOutPixmap(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaPixmapPriv(pPixmap); if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap)) return; exaCopyDirtyToSys(migrate); if (exaPixmapHasGpuCopy(pPixmap)) { DBG_MIGRATE(("<- %p (%p) (%dx%d) (%c)\n", pPixmap, (void *) (ExaGetPixmapPriv(pPixmap)->area ? ExaGetPixmapPriv(pPixmap)->area->offset : 0), pPixmap->drawable.width, pPixmap->drawable.height, exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); pExaPixmap->use_gpu_copy = FALSE; pPixmap->devKind = pExaPixmap->sys_pitch; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; } }
/** * Allocates a framebuffer copy of the pixmap if necessary, and then copies * any necessary pixmap data into the framebuffer copy and points the pixmap at * it. * * Note that when first allocated, a pixmap will have FALSE dirty flag. * This is intentional because pixmap data starts out undefined. So if we move * it in due to the first operation against it being accelerated, it will have * undefined framebuffer contents that we didn't have to upload. If we do * moveouts (and moveins) after the first movein, then we will only have to copy * back and forth if the pixmap was written to after the last synchronization of * the two copies. Then, at exaPixmapSave (when the framebuffer copy goes away) * we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move * all the data, since it's almost surely all valid now. */ static void exaDoMoveInPixmap(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv(pScreen); ExaPixmapPriv(pPixmap); /* If we're VT-switched away, no touching card memory allowed. */ if (pExaScr->swappedOut) return; /* If we're not allowed to move, then fail. */ if (exaPixmapIsPinned(pPixmap)) return; /* Don't migrate in pixmaps which are less than 8bpp. This avoids a lot of * fragility in EXA, and <8bpp is probably not used enough any more to care * (at least, not in acceleratd paths). */ if (pPixmap->drawable.bitsPerPixel < 8) return; if (pExaPixmap->accel_blocked) return; if (pExaPixmap->area == NULL) { pExaPixmap->area = exaOffscreenAlloc(pScreen, pExaPixmap->fb_size, pExaScr->info->pixmapOffsetAlign, FALSE, exaPixmapSave, (pointer) pPixmap); if (pExaPixmap->area == NULL) return; pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase + pExaPixmap->area->offset; } exaCopyDirtyToFb(migrate); if (exaPixmapHasGpuCopy(pPixmap)) return; DBG_MIGRATE(("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap, (ExaGetPixmapPriv(pPixmap)->area ? ExaGetPixmapPriv(pPixmap)->area->offset : 0), pPixmap->drawable.width, pPixmap->drawable.height, exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); pExaPixmap->use_gpu_copy = TRUE; pPixmap->devKind = pExaPixmap->fb_pitch; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; }
/** * For the "greedy" migration scheme, pushes the pixmap toward being located in * framebuffer memory. */ static void exaMigrateTowardFb (PixmapPtr pPixmap) { ExaPixmapPriv (pPixmap); if (pExaPixmap == NULL) { DBG_MIGRATE(("UseScreen: ignoring exa-uncontrolled pixmap %p (%s)\n", (pointer)pPixmap, exaPixmapIsOffscreen(pPixmap) ? "s" : "m")); return; } if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) { DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n", (pointer)pPixmap)); return; } DBG_MIGRATE(("UseScreen %p score %d\n", (pointer)pPixmap, pExaPixmap->score)); if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) { exaMoveInPixmap(pPixmap); pExaPixmap->score = 0; } if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX) pExaPixmap->score++; if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN && !exaPixmapIsOffscreen(pPixmap)) { exaMoveInPixmap (pPixmap); } ExaOffscreenMarkUsed (pPixmap); }
/** * For the "greedy" migration scheme, pushes the pixmap toward being located in * framebuffer memory. */ static void exaMigrateTowardFb(ExaMigrationPtr migrate) { PixmapPtr pPixmap = migrate->pPix; ExaPixmapPriv(pPixmap); if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) { DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n", (pointer) pPixmap)); return; } DBG_MIGRATE(("UseScreen %p score %d\n", (pointer) pPixmap, pExaPixmap->score)); if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) { exaDoMoveInPixmap(migrate); pExaPixmap->score = 0; } if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX) pExaPixmap->score++; if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN && !exaPixmapHasGpuCopy(pPixmap)) { exaDoMoveInPixmap(migrate); } if (exaPixmapHasGpuCopy(pPixmap)) { exaCopyDirtyToFb(migrate); ExaOffscreenMarkUsed(pPixmap); } else exaCopyDirtyToSys(migrate); }
void kaaMoveInPixmap (PixmapPtr pPixmap) { ScreenPtr pScreen = pPixmap->drawable.pScreen; KaaScreenPriv (pScreen); KaaPixmapPriv (pPixmap); int dst_pitch, src_pitch, bytes; unsigned char *dst, *src; int i; DBG_MIGRATE (("-> 0x%08x (0x%x) (%dx%d)\n", pPixmap->drawable.id, KaaGetPixmapPriv(pPixmap)->area ? KaaGetPixmapPriv(pPixmap)->area->offset : -1, pPixmap->drawable.width, pPixmap->drawable.height)); src = pPixmap->devPrivate.ptr; src_pitch = pPixmap->devKind; if (!kaaPixmapAllocArea (pPixmap)) return; pKaaPixmap->dirty = FALSE; if (pKaaScr->info->UploadToScreen) { if (pKaaScr->info->UploadToScreen(pPixmap, (char *) src, src_pitch)) return; } dst = pPixmap->devPrivate.ptr; dst_pitch = pPixmap->devKind; bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch; kaaWaitSync (pPixmap->drawable.pScreen); i = pPixmap->drawable.height; while (i--) { memcpy (dst, src, bytes); dst += dst_pitch; src += src_pitch; } }
static void kaaMoveOutPixmap (PixmapPtr pPixmap) { KaaPixmapPriv (pPixmap); KdOffscreenArea *area = pKaaPixmap->area; DBG_MIGRATE (("<- 0x%08x (0x%x) (%dx%d)\n", pPixmap->drawable.id, KaaGetPixmapPriv(pPixmap)->area ? KaaGetPixmapPriv(pPixmap)->area->offset : -1, pPixmap->drawable.width, pPixmap->drawable.height)); if (area) { kaaPixmapSave (pPixmap->drawable.pScreen, area); KdOffscreenFree (pPixmap->drawable.pScreen, area); } }
static void kaaPixmapSave (ScreenPtr pScreen, KdOffscreenArea *area) { PixmapPtr pPixmap = area->privData; KaaPixmapPriv(pPixmap); int dst_pitch, src_pitch, bytes; unsigned char *dst, *src; int i; DBG_MIGRATE (("Save 0x%08x (0x%x) (%dx%d)\n", pPixmap->drawable.id, KaaGetPixmapPriv(pPixmap)->area ? KaaGetPixmapPriv(pPixmap)->area->offset : -1, pPixmap->drawable.width, pPixmap->drawable.height)); src_pitch = pPixmap->devKind; dst_pitch = pKaaPixmap->devKind; src = pPixmap->devPrivate.ptr; dst = pKaaPixmap->devPrivate.ptr; pPixmap->devKind = dst_pitch; pPixmap->devPrivate.ptr = dst; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pKaaPixmap->area = NULL; #if 0 if (!pKaaPixmap->dirty) return; #endif kaaWaitSync (pPixmap->drawable.pScreen); bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch; i = pPixmap->drawable.height; while (i--) { memcpy (dst, src, bytes); dst += dst_pitch; src += src_pitch; } }
/** * Switches the current active location of the pixmap to system memory, copying * updated data out if necessary. */ void exaMoveOutPixmap (PixmapPtr pPixmap) { ExaPixmapPriv (pPixmap); if (exaPixmapIsPinned(pPixmap)) return; if (exaPixmapIsOffscreen(pPixmap)) { DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap, (void*)(ExaGetPixmapPriv(pPixmap)->area ? ExaGetPixmapPriv(pPixmap)->area->offset : 0), pPixmap->drawable.width, pPixmap->drawable.height, exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); exaCopyDirtyToSys (pPixmap); pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; pPixmap->devKind = pExaPixmap->sys_pitch; pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; } }