summaryrefslogtreecommitdiff
path: root/hw/xfree86/dri2/dri2.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/dri2/dri2.c')
-rw-r--r--hw/xfree86/dri2/dri2.c67
1 files changed, 47 insertions, 20 deletions
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 1176878b7..7a3dd6628 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -99,6 +99,7 @@ typedef struct _DRI2Drawable {
unsigned long serialNumber;
Bool needInvalidate;
int prime_id;
+ PixmapPtr redirectpixmap;
} DRI2DrawableRec, *DRI2DrawablePtr;
typedef struct _DRI2Screen {
@@ -231,7 +232,7 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
xorg_list_init(&pPriv->reference_list);
pPriv->serialNumber = DRI2DrawableSerial(pDraw);
pPriv->needInvalidate = FALSE;
-
+ pPriv->redirectpixmap = NULL;
if (pDraw->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr) pDraw;
dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, pPriv);
@@ -398,6 +399,12 @@ DRI2DrawableGone(pointer p, XID id)
free(pPriv->buffers);
}
+ if (pPriv->redirectpixmap) {
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ (*pDraw->pScreen->ReplaceScanoutPixmap)(pDraw, pPriv->redirectpixmap, FALSE);
+ (*pDraw->pScreen->DestroyPixmap)(pPriv->redirectpixmap);
+ }
+
free(pPriv);
return Success;
@@ -745,31 +752,52 @@ DrawablePtr DRI2UpdatePrime(DrawablePtr pDraw, DRI2BufferPtr pDest)
ScreenPtr master, slave;
int fd_handle;
Bool ret;
-
+ Bool set_front = FALSE;
master = mpix->drawable.pScreen;
- ret = master->SharePixmapBacking(mpix, &fd_handle);
- if (ret == FALSE) {
- ErrorF("share pixmap backing failed\n");
- return;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ PixmapPtr pPixmap = pDraw->pScreen->GetWindowPixmap(pWin);
+ DRI2ScreenPtr ds;
+
+ if (pDraw->pScreen->GetScreenPixmap(pDraw->pScreen) == pPixmap) {
+ if (pPriv->redirectpixmap &&
+ pPriv->redirectpixmap->drawable.width == pDraw->width &&
+ pPriv->redirectpixmap->drawable.height == pDraw->height &&
+ pPriv->redirectpixmap->drawable.depth == pDraw->depth) {
+ mpix = pPriv->redirectpixmap;
+ } else {
+ ErrorF("creating redirect pixmap\n");
+ ds = DRI2GetScreen(master);
+
+ if (master->ReplaceScanoutPixmap) {
+ mpix = (*master->CreatePixmap)(master, pDraw->width, pDraw->height,
+ pDraw->depth, CREATE_PIXMAP_USAGE_SHARED);
+ if (!mpix)
+ return NULL;
+
+ set_front = TRUE;
+ pPriv->redirectpixmap = mpix;
+ } else
+ return NULL;
+ }
+ } else if (pPriv->redirectpixmap) {
+ ErrorF("destroying redirect pixmap\n");
+ (*master->ReplaceScanoutPixmap)(pDraw, pPriv->redirectpixmap, FALSE);
+ (*mpix->drawable.pScreen->DestroyPixmap)(pPriv->redirectpixmap);
+ pPriv->redirectpixmap = NULL;
+ }
}
slave = GetScreenPrime(pDraw->pScreen, pPriv->prime_id);
- spix = slave->CreatePixmap(slave, 0, 0, (pDest->format != 0) ? pDest->format : mpix->drawable.depth, CREATE_PIXMAP_USAGE_SHARED);
- if (!spix) {
- ErrorF("failed to create pixmap for sharing\n");
- return;
- }
+ spix = PixmapShareToSlave(mpix, slave);
+ if (!spix)
+ return NULL;
- slave->ModifyPixmapHeader(spix, mpix->drawable.width,
- mpix->drawable.height,
- (pDest->format != 0) ? pDest->format : mpix->drawable.depth,
- 0, mpix->devKind, NULL);
- ret = slave->SetSharedPixmapBacking(spix, fd_handle);
- if (ret == FALSE) {
- ErrorF("failed to set pixmap backing store\n");
- return FALSE;
+ if (set_front) {
+ (*master->ReplaceScanoutPixmap)(pDraw, pPriv->redirectpixmap, TRUE);
}
#ifdef COMPOSITE
spix->screen_x = mpix->screen_x;
@@ -793,7 +821,6 @@ static void dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
else
(*ds->CopyRegion) (pDraw, pRegion, pDest, pSrc);
- ErrorF("prime id %d\n", pPriv->prime_id);
/* cause damage to the box */
if (pPriv->prime_id) {
BoxRec box;