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
80
exa/exa.c
80
exa/exa.c
|
@ -286,11 +286,10 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
|
||||||
* Returns TRUE if pixmap can be accessed offscreen.
|
* Returns TRUE if pixmap can be accessed offscreen.
|
||||||
*/
|
*/
|
||||||
Bool
|
Bool
|
||||||
ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pDrawable->pScreen;
|
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||||
ExaScreenPriv (pScreen);
|
ExaScreenPriv (pScreen);
|
||||||
PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
|
|
||||||
ExaPixmapPriv(pPixmap);
|
ExaPixmapPriv(pPixmap);
|
||||||
Bool offscreen;
|
Bool offscreen;
|
||||||
int i;
|
int i;
|
||||||
|
@ -324,7 +323,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
|
|
||||||
offscreen = exaPixmapIsOffscreen(pPixmap);
|
offscreen = exaPixmapIsOffscreen(pPixmap);
|
||||||
|
|
||||||
if (offscreen)
|
if (offscreen && pExaPixmap->fb_ptr)
|
||||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||||
else
|
else
|
||||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||||
|
@ -333,20 +332,10 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
pExaScr->access[index].pixmap = pPixmap;
|
pExaScr->access[index].pixmap = pPixmap;
|
||||||
pExaScr->access[index].count = 1;
|
pExaScr->access[index].count = 1;
|
||||||
|
|
||||||
if (!offscreen) {
|
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;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
exaWaitSync (pDrawable->pScreen);
|
exaWaitSync (pScreen);
|
||||||
|
|
||||||
if (pExaScr->info->PrepareAccess == NULL)
|
if (pExaScr->info->PrepareAccess == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -360,7 +349,8 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*pExaScr->info->PrepareAccess) (pPixmap, 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");
|
FatalError("Driver failed PrepareAccess on a pinned pixmap.\n");
|
||||||
exaMoveOutPixmap (pPixmap);
|
exaMoveOutPixmap (pPixmap);
|
||||||
|
|
||||||
|
@ -370,31 +360,6 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
|
* exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
|
||||||
*
|
*
|
||||||
|
@ -404,7 +369,13 @@ exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
|
||||||
void
|
void
|
||||||
exaPrepareAccess(DrawablePtr pDrawable, int index)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -432,7 +403,6 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
|
||||||
if (pExaScr->access[i].pixmap == pPixmap) {
|
if (pExaScr->access[i].pixmap == pPixmap) {
|
||||||
if (--pExaScr->access[i].count > 0)
|
if (--pExaScr->access[i].count > 0)
|
||||||
return;
|
return;
|
||||||
index = i;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,25 +412,25 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
|
||||||
EXA_FatalErrorDebug(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n",
|
EXA_FatalErrorDebug(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n",
|
||||||
pPixmap));
|
pPixmap));
|
||||||
|
|
||||||
pExaScr->access[index].pixmap = NULL;
|
pExaScr->access[i].pixmap = NULL;
|
||||||
|
|
||||||
/* We always hide the devPrivate.ptr. */
|
/* We always hide the devPrivate.ptr. */
|
||||||
pPixmap->devPrivate.ptr = NULL;
|
pPixmap->devPrivate.ptr = NULL;
|
||||||
|
|
||||||
if (pExaScr->info->FinishAccess == NULL)
|
if (pExaScr->finish_access)
|
||||||
|
pExaScr->finish_access(pPixmap, index);
|
||||||
|
|
||||||
|
if (!pExaScr->info->FinishAccess || !exaPixmapIsOffscreen(pPixmap))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!exaPixmapIsOffscreen (pPixmap))
|
if (i >= EXA_PREPARE_AUX_DEST &&
|
||||||
return;
|
|
||||||
|
|
||||||
if (index >= EXA_PREPARE_AUX_DEST &&
|
|
||||||
!(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
|
!(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
|
||||||
ErrorF("EXA bug: Trying to call driver FinishAccess hook with "
|
ErrorF("EXA bug: Trying to call driver FinishAccess hook with "
|
||||||
"unsupported index EXA_PREPARE_AUX*\n");
|
"unsupported index EXA_PREPARE_AUX*\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*pExaScr->info->FinishAccess) (pPixmap, index);
|
(*pExaScr->info->FinishAccess) (pPixmap, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -537,7 +507,7 @@ exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
|
||||||
* For EXA_HANDLES_PIXMAPS the driver will handle whatever is needed.
|
* For EXA_HANDLES_PIXMAPS the driver will handle whatever is needed.
|
||||||
* We want to signal that the pixmaps will be used as destination.
|
* We want to signal that the pixmaps will be used as destination.
|
||||||
*/
|
*/
|
||||||
ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
|
ExaDoPrepareAccess(pPixmap, EXA_PREPARE_AUX_DEST);
|
||||||
|
|
||||||
return pPixmap;
|
return pPixmap;
|
||||||
}
|
}
|
||||||
|
@ -1071,6 +1041,8 @@ exaDriverInit (ScreenPtr pScreen,
|
||||||
pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_mixed;
|
pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_mixed;
|
||||||
pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
|
pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
|
||||||
pExaScr->do_move_out_pixmap = NULL;
|
pExaScr->do_move_out_pixmap = NULL;
|
||||||
|
pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
|
||||||
|
pExaScr->finish_access = exaFinishAccess_mixed;
|
||||||
} else {
|
} else {
|
||||||
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
|
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
|
||||||
wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
|
wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
|
||||||
|
@ -1079,6 +1051,8 @@ exaDriverInit (ScreenPtr pScreen,
|
||||||
pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_driver;
|
pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_driver;
|
||||||
pExaScr->do_move_in_pixmap = NULL;
|
pExaScr->do_move_in_pixmap = NULL;
|
||||||
pExaScr->do_move_out_pixmap = NULL;
|
pExaScr->do_move_out_pixmap = NULL;
|
||||||
|
pExaScr->prepare_access_reg = NULL;
|
||||||
|
pExaScr->finish_access = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
|
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
|
||||||
|
@ -1088,6 +1062,8 @@ exaDriverInit (ScreenPtr pScreen,
|
||||||
pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_classic;
|
pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_classic;
|
||||||
pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
|
pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
|
||||||
pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
|
pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
|
||||||
|
pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
|
||||||
|
pExaScr->finish_access = NULL;
|
||||||
}
|
}
|
||||||
if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
|
if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
|
||||||
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
|
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
|
||||||
|
|
|
@ -120,7 +120,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
|
||||||
Bool need_sync = FALSE;
|
Bool need_sync = FALSE;
|
||||||
|
|
||||||
/* Damaged bits are valid in current copy but invalid in other one */
|
/* 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,
|
REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
|
||||||
damage);
|
damage);
|
||||||
REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
|
REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
|
||||||
|
@ -225,7 +225,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
|
||||||
pExaPixmap->sys_pitch))
|
pExaPixmap->sys_pitch))
|
||||||
{
|
{
|
||||||
if (!access_prepared) {
|
if (!access_prepared) {
|
||||||
ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
|
ExaDoPrepareAccess(pPixmap, fallback_index);
|
||||||
access_prepared = TRUE;
|
access_prepared = TRUE;
|
||||||
}
|
}
|
||||||
exaMemcpyBox (pPixmap, pBox,
|
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
|
* the framebuffer memory copy to the system memory copy. Both areas must be
|
||||||
* allocated.
|
* allocated.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
exaCopyDirtyToSys (ExaMigrationPtr migrate)
|
exaCopyDirtyToSys (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
PixmapPtr pPixmap = migrate->pPix;
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
|
@ -281,7 +281,7 @@ exaCopyDirtyToSys (ExaMigrationPtr migrate)
|
||||||
* the system memory copy to the framebuffer memory copy. Both areas must be
|
* the system memory copy to the framebuffer memory copy. Both areas must be
|
||||||
* allocated.
|
* allocated.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
exaCopyDirtyToFb (ExaMigrationPtr migrate)
|
exaCopyDirtyToFb (ExaMigrationPtr migrate)
|
||||||
{
|
{
|
||||||
PixmapPtr pPixmap = migrate->pPix;
|
PixmapPtr pPixmap = migrate->pPix;
|
||||||
|
@ -545,7 +545,7 @@ exaAssertNotDirty (PixmapPtr pPixmap)
|
||||||
pExaPixmap->offscreen = TRUE;
|
pExaPixmap->offscreen = TRUE;
|
||||||
pPixmap->devKind = pExaPixmap->fb_pitch;
|
pPixmap->devKind = pExaPixmap->fb_pitch;
|
||||||
|
|
||||||
if (!ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC))
|
if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
while (nbox--) {
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -31,55 +31,16 @@
|
||||||
#include "exa_priv.h"
|
#include "exa_priv.h"
|
||||||
#include "exa.h"
|
#include "exa.h"
|
||||||
|
|
||||||
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
|
void
|
||||||
exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
|
exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||||
ExaScreenPriv(pScreen);
|
ExaScreenPriv(pScreen);
|
||||||
ExaPixmapPriv(pPixmap);
|
ExaPixmapPriv(pPixmap);
|
||||||
RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
|
|
||||||
void *sys_buffer = pExaPixmap->sys_ptr;
|
|
||||||
int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
|
int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
|
||||||
int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel;
|
int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel;
|
||||||
int usage_hint = pPixmap->usage_hint;
|
int usage_hint = pPixmap->usage_hint;
|
||||||
int sys_pitch = pExaPixmap->sys_pitch;
|
int paddedWidth = pExaPixmap->sys_pitch;
|
||||||
int paddedWidth = sys_pitch;
|
|
||||||
int nbox;
|
|
||||||
BoxPtr pbox;
|
|
||||||
|
|
||||||
/* Already done. */
|
/* Already done. */
|
||||||
if (pExaPixmap->driverPriv)
|
if (pExaPixmap->driverPriv)
|
||||||
|
@ -105,50 +66,8 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
|
||||||
if (!pExaPixmap->driverPriv)
|
if (!pExaPixmap->driverPriv)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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,
|
(*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
|
||||||
paddedWidth, NULL);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -175,8 +94,16 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
||||||
for (i = 0; i < npixmaps; i++) {
|
for (i = 0; i < npixmaps; i++) {
|
||||||
PixmapPtr pPixmap = pixmaps[i].pPix;
|
PixmapPtr pPixmap = pixmaps[i].pPix;
|
||||||
ExaPixmapPriv(pPixmap);
|
ExaPixmapPriv(pPixmap);
|
||||||
|
|
||||||
if (!pExaPixmap->driverPriv)
|
if (!pExaPixmap->driverPriv)
|
||||||
exaCreateDriverPixmap_mixed(pPixmap);
|
exaCreateDriverPixmap_mixed(pPixmap);
|
||||||
|
|
||||||
|
if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
|
||||||
|
pPixmap->devKind = pExaPixmap->fb_pitch;
|
||||||
|
exaCopyDirtyToFb(pixmaps + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,3 +119,91 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap)
|
||||||
|
|
||||||
exaDoMigration(pixmaps, 1, TRUE);
|
exaDoMigration(pixmaps, 1, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
#include "exa.h"
|
#include "exa.h"
|
||||||
|
|
||||||
/* This file holds the driver allocated pixmaps + better initial placement code.
|
/* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static _X_INLINE void*
|
static _X_INLINE void*
|
||||||
|
@ -46,9 +44,6 @@ ExaGetPixmapAddress(PixmapPtr p)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* exaCreatePixmap() creates a new pixmap.
|
* exaCreatePixmap() creates a new pixmap.
|
||||||
*
|
|
||||||
* Pixmaps are always marked as pinned, unless the pixmap can still be transfered to a
|
|
||||||
* driver pixmaps.
|
|
||||||
*/
|
*/
|
||||||
PixmapPtr
|
PixmapPtr
|
||||||
exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
|
exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
|
||||||
|
@ -85,7 +80,6 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
|
||||||
pExaPixmap->sys_pitch = paddedWidth;
|
pExaPixmap->sys_pitch = paddedWidth;
|
||||||
|
|
||||||
pExaPixmap->area = NULL;
|
pExaPixmap->area = NULL;
|
||||||
pExaPixmap->offscreen = FALSE;
|
|
||||||
pExaPixmap->fb_ptr = NULL;
|
pExaPixmap->fb_ptr = NULL;
|
||||||
pExaPixmap->pDamage = NULL;
|
pExaPixmap->pDamage = NULL;
|
||||||
|
|
||||||
|
@ -93,36 +87,15 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
|
||||||
exaSetAccelBlock(pExaScr, pExaPixmap,
|
exaSetAccelBlock(pExaScr, pExaPixmap,
|
||||||
w, h, bpp);
|
w, h, bpp);
|
||||||
|
|
||||||
/* Avoid freeing sys_ptr. */
|
|
||||||
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
|
|
||||||
|
|
||||||
(*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
|
(*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
|
||||||
paddedWidth, NULL);
|
paddedWidth, NULL);
|
||||||
|
|
||||||
/* 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. */
|
/* A scratch pixmap will become a driver pixmap right away. */
|
||||||
if (!w || !h) {
|
if (!w || !h) {
|
||||||
exaCreateDriverPixmap_mixed(pPixmap);
|
exaCreateDriverPixmap_mixed(pPixmap);
|
||||||
} else {
|
pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
|
||||||
/* Set up damage tracking */
|
} else
|
||||||
pExaPixmap->pDamage = DamageCreate (NULL, NULL,
|
pExaPixmap->offscreen = FALSE;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pPixmap;
|
return pPixmap;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +107,7 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||||
ExaScreenPrivPtr pExaScr;
|
ExaScreenPrivPtr pExaScr;
|
||||||
ExaPixmapPrivPtr pExaPixmap;
|
ExaPixmapPrivPtr pExaPixmap;
|
||||||
Bool ret;
|
Bool ret, is_offscreen;
|
||||||
|
|
||||||
if (!pPixmap)
|
if (!pPixmap)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -142,26 +115,23 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
pExaScr = ExaGetScreenPriv(pScreen);
|
pExaScr = ExaGetScreenPriv(pScreen);
|
||||||
pExaPixmap = ExaGetPixmapPriv(pPixmap);
|
pExaPixmap = ExaGetPixmapPriv(pPixmap);
|
||||||
|
|
||||||
if (pExaPixmap) {
|
if (pPixData) {
|
||||||
if (!exaPixmapIsPinned(pPixmap)) {
|
if (pExaPixmap->driverPriv) {
|
||||||
free(pExaPixmap->sys_ptr);
|
|
||||||
pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr = NULL;
|
|
||||||
pExaPixmap->sys_pitch = pPixmap->devKind = 0;
|
|
||||||
|
|
||||||
/* We no longer need this. */
|
|
||||||
if (pExaPixmap->pDamage) {
|
if (pExaPixmap->pDamage) {
|
||||||
DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
|
DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
|
||||||
DamageDestroy(pExaPixmap->pDamage);
|
DamageDestroy(pExaPixmap->pDamage);
|
||||||
pExaPixmap->pDamage = NULL;
|
pExaPixmap->pDamage = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
|
||||||
|
pExaPixmap->driverPriv = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pPixData)
|
pExaPixmap->offscreen = FALSE;
|
||||||
pExaPixmap->sys_ptr = pPixData;
|
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
|
||||||
|
}
|
||||||
if (devKind > 0)
|
|
||||||
pExaPixmap->sys_pitch = devKind;
|
|
||||||
|
|
||||||
|
if (pExaPixmap->driverPriv) {
|
||||||
if (width > 0 && height > 0 && bitsPerPixel > 0) {
|
if (width > 0 && height > 0 && bitsPerPixel > 0) {
|
||||||
exaSetFbPitch(pExaScr, pExaPixmap,
|
exaSetFbPitch(pExaScr, pExaPixmap,
|
||||||
width, height, bitsPerPixel);
|
width, height, bitsPerPixel);
|
||||||
|
@ -169,9 +139,15 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
exaSetAccelBlock(pExaScr, pExaPixmap,
|
exaSetAccelBlock(pExaScr, pExaPixmap,
|
||||||
width, height, bitsPerPixel);
|
width, height, bitsPerPixel);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Anything can happen, don't try to predict it all. */
|
is_offscreen = exaPixmapIsOffscreen(pPixmap);
|
||||||
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only pass driver pixmaps to the driver. */
|
/* Only pass driver pixmaps to the driver. */
|
||||||
|
@ -182,10 +158,6 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
* If pPixmap->devPrivate.ptr is non-NULL, then we've got a non-offscreen pixmap.
|
* 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.
|
* 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)
|
if (ret == TRUE)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +168,13 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
swap(pExaScr, pScreen, ModifyPixmapHeader);
|
swap(pExaScr, pScreen, ModifyPixmapHeader);
|
||||||
|
|
||||||
out:
|
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. */
|
/* Always NULL this, we don't want lingering pointers. */
|
||||||
pPixmap->devPrivate.ptr = NULL;
|
pPixmap->devPrivate.ptr = NULL;
|
||||||
|
|
||||||
|
@ -215,10 +194,14 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
|
||||||
|
|
||||||
if (pExaPixmap->driverPriv)
|
if (pExaPixmap->driverPriv)
|
||||||
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
|
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
|
||||||
else if (pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap))
|
|
||||||
free(pExaPixmap->sys_ptr);
|
|
||||||
pExaPixmap->driverPriv = NULL;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
swap(pExaScr, pScreen, DestroyPixmap);
|
swap(pExaScr, pScreen, DestroyPixmap);
|
||||||
|
|
|
@ -176,6 +176,8 @@ typedef struct {
|
||||||
Bool (*pixmap_is_offscreen) (PixmapPtr pPixmap);
|
Bool (*pixmap_is_offscreen) (PixmapPtr pPixmap);
|
||||||
void (*do_move_in_pixmap) (PixmapPtr pPixmap);
|
void (*do_move_in_pixmap) (PixmapPtr pPixmap);
|
||||||
void (*do_move_out_pixmap) (PixmapPtr pPixmap);
|
void (*do_move_out_pixmap) (PixmapPtr pPixmap);
|
||||||
|
void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
|
||||||
|
void (*finish_access)(PixmapPtr pPixmap, int index);
|
||||||
|
|
||||||
Bool swappedOut;
|
Bool swappedOut;
|
||||||
enum ExaMigrationHeuristic migration;
|
enum ExaMigrationHeuristic migration;
|
||||||
|
@ -511,10 +513,7 @@ ExaOffscreenFini (ScreenPtr pScreen);
|
||||||
|
|
||||||
/* exa.c */
|
/* exa.c */
|
||||||
Bool
|
Bool
|
||||||
ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
|
ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
|
||||||
|
|
||||||
void
|
|
||||||
exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
exaPrepareAccess(DrawablePtr pDrawable, int index);
|
exaPrepareAccess(DrawablePtr pDrawable, int index);
|
||||||
|
@ -609,6 +608,12 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
|
||||||
void
|
void
|
||||||
exaMoveInPixmap_mixed(PixmapPtr pPixmap);
|
exaMoveInPixmap_mixed(PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaFinishAccess_mixed(PixmapPtr pPixmap, int index);
|
||||||
|
|
||||||
/* exa_render.c */
|
/* exa_render.c */
|
||||||
Bool
|
Bool
|
||||||
exaOpReadsDestination (CARD8 op);
|
exaOpReadsDestination (CARD8 op);
|
||||||
|
@ -664,6 +669,12 @@ exaGlyphs (CARD8 op,
|
||||||
GlyphPtr *glyphs);
|
GlyphPtr *glyphs);
|
||||||
|
|
||||||
/* exa_migration_classic.c */
|
/* exa_migration_classic.c */
|
||||||
|
void
|
||||||
|
exaCopyDirtyToSys (ExaMigrationPtr migrate);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaCopyDirtyToFb (ExaMigrationPtr migrate);
|
||||||
|
|
||||||
void
|
void
|
||||||
exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
|
exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
|
||||||
|
|
||||||
|
@ -676,4 +687,7 @@ exaMoveOutPixmap_classic (PixmapPtr pPixmap);
|
||||||
void
|
void
|
||||||
exaMoveInPixmap_classic (PixmapPtr pPixmap);
|
exaMoveInPixmap_classic (PixmapPtr pPixmap);
|
||||||
|
|
||||||
|
void
|
||||||
|
exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
|
||||||
|
|
||||||
#endif /* EXAPRIV_H */
|
#endif /* EXAPRIV_H */
|
||||||
|
|
|
@ -101,16 +101,19 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
|
||||||
int x, int y, int w, int h, int leftPad, int format,
|
int x, int y, int w, int h, int leftPad, int format,
|
||||||
char *bits)
|
char *bits)
|
||||||
{
|
{
|
||||||
ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
|
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
|
||||||
|
ExaPixmapPriv(pPixmap);
|
||||||
|
ExaScreenPriv(pDrawable->pScreen);
|
||||||
|
|
||||||
EXA_GC_PROLOGUE(pGC);
|
EXA_GC_PROLOGUE(pGC);
|
||||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
|
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))
|
pGC->alu, pGC->clientClipType))
|
||||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
else
|
else
|
||||||
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ?
|
pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
|
||||||
DamagePendingRegion(pExaPixmap->pDamage) : NULL);
|
DamagePendingRegion(pExaPixmap->pDamage));
|
||||||
pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
|
pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
EXA_GC_EPILOGUE(pGC);
|
EXA_GC_EPILOGUE(pGC);
|
||||||
|
@ -323,9 +326,6 @@ void
|
||||||
ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
|
ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
|
||||||
unsigned int format, unsigned long planeMask, char *d)
|
unsigned int format, unsigned long planeMask, char *d)
|
||||||
{
|
{
|
||||||
BoxRec Box;
|
|
||||||
RegionRec Reg;
|
|
||||||
int xoff, yoff;
|
|
||||||
ScreenPtr pScreen = pDrawable->pScreen;
|
ScreenPtr pScreen = pDrawable->pScreen;
|
||||||
PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
|
PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
|
||||||
ExaScreenPriv(pScreen);
|
ExaScreenPriv(pScreen);
|
||||||
|
@ -333,16 +333,24 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
|
||||||
EXA_FALLBACK(("from %p (%c)\n", pDrawable,
|
EXA_FALLBACK(("from %p (%c)\n", pDrawable,
|
||||||
exaDrawableLocation(pDrawable)));
|
exaDrawableLocation(pDrawable)));
|
||||||
|
|
||||||
exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
|
if (pExaScr->prepare_access_reg) {
|
||||||
|
int xoff, yoff;
|
||||||
|
BoxRec Box;
|
||||||
|
RegionRec Reg;
|
||||||
|
|
||||||
Box.x1 = pDrawable->y + x + xoff;
|
exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
|
||||||
Box.y1 = pDrawable->y + y + yoff;
|
|
||||||
Box.x2 = Box.x1 + w;
|
|
||||||
Box.y2 = Box.y1 + h;
|
|
||||||
|
|
||||||
REGION_INIT(pScreen, &Reg, &Box, 1);
|
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);
|
||||||
|
|
||||||
|
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);
|
swap(pExaScr, pScreen, GetImage);
|
||||||
pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
|
pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
|
||||||
swap(pExaScr, pScreen, GetImage);
|
swap(pExaScr, pScreen, GetImage);
|
||||||
|
@ -401,23 +409,23 @@ ExaCheckComposite (CARD8 op,
|
||||||
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
|
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
|
||||||
exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
|
exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
|
||||||
|
|
||||||
if (!exaOpReadsDestination(op)) {
|
if (!exaOpReadsDestination(op) && pExaScr->prepare_access_reg) {
|
||||||
|
PixmapPtr pDstPix;
|
||||||
|
|
||||||
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
|
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
|
||||||
xSrc, ySrc, xMask, yMask, xDst, yDst,
|
xSrc, ySrc, xMask, yMask, xDst, yDst,
|
||||||
width, height))
|
width, height))
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
exaGetDrawableDeltas (pDst->pDrawable,
|
pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
|
||||||
exaGetDrawablePixmap(pDst->pDrawable),
|
exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
|
||||||
&xoff, &yoff);
|
|
||||||
|
|
||||||
REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
|
REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
|
||||||
|
|
||||||
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
||||||
exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST,
|
pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
|
||||||
®ion);
|
EXA_PREPARE_AUX_DEST, ®ion);
|
||||||
|
|
||||||
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion);
|
pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, ®ion);
|
||||||
} else {
|
} else {
|
||||||
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
|
||||||
exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
|
exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
|
||||||
|
|
Loading…
Reference in New Issue