diff options
Diffstat (limited to 'hw/xfree86/dri2/dri2.c')
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 67 |
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; |