mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-14 00:01:20 +00:00
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.
This commit is contained in:
parent
e23bffc41b
commit
1818cbd70f
6 changed files with 232 additions and 216 deletions
|
|
@ -120,7 +120,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
|
|||
Bool need_sync = FALSE;
|
||||
|
||||
/* 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,
|
||||
damage);
|
||||
REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
|
||||
|
|
@ -225,7 +225,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
|
|||
pExaPixmap->sys_pitch))
|
||||
{
|
||||
if (!access_prepared) {
|
||||
ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
|
||||
ExaDoPrepareAccess(pPixmap, fallback_index);
|
||||
access_prepared = TRUE;
|
||||
}
|
||||
exaMemcpyBox (pPixmap, pBox,
|
||||
|
|
@ -263,7 +263,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
|
|||
* the framebuffer memory copy to the system memory copy. Both areas must be
|
||||
* allocated.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
exaCopyDirtyToSys (ExaMigrationPtr migrate)
|
||||
{
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
|
|
@ -281,7 +281,7 @@ exaCopyDirtyToSys (ExaMigrationPtr migrate)
|
|||
* the system memory copy to the framebuffer memory copy. Both areas must be
|
||||
* allocated.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
exaCopyDirtyToFb (ExaMigrationPtr migrate)
|
||||
{
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
|
|
@ -545,7 +545,7 @@ exaAssertNotDirty (PixmapPtr pPixmap)
|
|||
pExaPixmap->offscreen = TRUE;
|
||||
pPixmap->devKind = pExaPixmap->fb_pitch;
|
||||
|
||||
if (!ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC))
|
||||
if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
|
||||
goto skip;
|
||||
|
||||
while (nbox--) {
|
||||
|
|
@ -718,3 +718,23 @@ 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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue