diff options
author | Dave Airlie <airlied@redhat.com> | 2012-06-21 11:43:09 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-06-21 13:54:48 +0100 |
commit | f74509960ecb379012ce134c2a48d53a5fb04ec7 (patch) | |
tree | 1b3d3a49b00d0c30d99bc08ee4dbfa1ee12ba0ce | |
parent | c4fe8d073993922f477900ebc337d04e7af171f6 (diff) |
dri2/randr: add new way to force a front pixmapprime-dri2-hack
After ickle disliked part of my previous attempt this tries to do things
via the server and the current modesetting channels.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | dix/pixmap.c | 28 | ||||
-rw-r--r-- | hw/xfree86/dri2/dri2.c | 67 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.h | 2 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86RandR12.c | 3 | ||||
-rw-r--r-- | include/pixmap.h | 2 | ||||
-rw-r--r-- | include/scrnintstr.h | 3 | ||||
-rw-r--r-- | randr/randr.c | 2 | ||||
-rw-r--r-- | randr/randrstr.h | 3 | ||||
-rw-r--r-- | randr/rrcrtc.c | 64 |
9 files changed, 137 insertions, 37 deletions
diff --git a/dix/pixmap.c b/dix/pixmap.c index c5c277449..804038f41 100644 --- a/dix/pixmap.c +++ b/dix/pixmap.c @@ -220,3 +220,31 @@ Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region) pScreen->SourceValidate = SourceValidate; return TRUE; } + +PixmapPtr PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave) +{ + PixmapPtr spix; + int ret; + int fd_handle; + ScreenPtr master = pixmap->drawable.pScreen; + int depth = pixmap->drawable.depth; + + ret = master->SharePixmapBacking(pixmap, &fd_handle); + if (ret == FALSE) + return NULL; + + spix = slave->CreatePixmap(slave, 0, 0, depth, + CREATE_PIXMAP_USAGE_SHARED); + slave->ModifyPixmapHeader(spix, pixmap->drawable.width, + pixmap->drawable.height, depth, 0, + pixmap->devKind, NULL); + + ret = slave->SetSharedPixmapBacking(spix, fd_handle); + if (ret == FALSE) { + slave->DestroyPixmap(spix); + return NULL; + } + + spix->master_pixmap = pixmap; + return spix; +} 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; diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index 662157bdc..5686a1e2f 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -377,6 +377,8 @@ struct _xf86Crtc { * Added in ABI version 4 */ Bool driverIsPerformingTransform; + + PixmapPtr current_scanout; }; typedef struct _xf86OutputFuncs { diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 26223cb4f..3a36ade88 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -1157,6 +1157,8 @@ xf86RandR12CrtcSet(ScreenPtr pScreen, if (rotation != crtc->rotation) changed = TRUE; + if (crtc->current_scanout != randr_crtc->scanout_pixmap) + changed = TRUE; transform = RRCrtcGetTransform(randr_crtc); if ((transform != NULL) != crtc->transformPresent) changed = TRUE; @@ -1218,6 +1220,7 @@ xf86RandR12CrtcSet(ScreenPtr pScreen, */ crtc->desiredMode = mode; crtc->desiredRotation = rotation; + crtc->current_scanout = randr_crtc->scanout_pixmap; if (transform) { crtc->desiredTransform = *transform; crtc->desiredTransformPresent = TRUE; diff --git a/include/pixmap.h b/include/pixmap.h index 6c85a2e5f..413c51c55 100644 --- a/include/pixmap.h +++ b/include/pixmap.h @@ -125,4 +125,6 @@ PixmapStopDirtyTracking(PixmapPtr src, PixmapPtr slave_dst); extern _X_EXPORT Bool PixmapSyncDirtyHelper(PixmapDirtyUpdatePtr dirty, RegionPtr dirty_region); +extern _X_EXPORT PixmapPtr +PixmapShareToSlave(PixmapPtr pixmap, ScreenPtr slave); #endif /* PIXMAP_H */ diff --git a/include/scrnintstr.h b/include/scrnintstr.h index a65b09ec8..e602017df 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -351,6 +351,8 @@ typedef Bool (*StartPixmapTrackingProcPtr)(PixmapPtr, PixmapPtr, typedef Bool (*StopPixmapTrackingProcPtr)(PixmapPtr, PixmapPtr); +typedef Bool (*ReplaceScanoutPixmapProcPtr)(DrawablePtr, PixmapPtr, Bool); + typedef struct _Screen { int myNum; /* index of this instance in Screens[] */ ATOM id; @@ -508,6 +510,7 @@ typedef struct _Screen { struct xorg_list offload_slave_list; struct xorg_list offload_head; + ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap; } ScreenRec; static inline RegionPtr diff --git a/randr/randr.c b/randr/randr.c index 215974852..c2d4c444a 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -295,7 +295,7 @@ RRScreenInit(ScreenPtr pScreen) wrap(pScrPriv, pScreen, CloseScreen, RRCloseScreen); pScreen->ConstrainCursorHarder = RRConstrainCursorHarder; - + pScreen->ReplaceScanoutPixmap = RRReplaceScanoutPixmap; pScrPriv->numOutputs = 0; pScrPriv->outputs = NULL; pScrPriv->numCrtcs = 0; diff --git a/randr/randrstr.h b/randr/randrstr.h index 93d74e8f9..dd87feb30 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -668,6 +668,9 @@ extern _X_EXPORT void extern _X_EXPORT void RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc); +extern _X_EXPORT Bool + RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable); + /* * Crtc dispatch */ diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 1ca33a4b8..ba3ff8f0b 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -423,26 +423,12 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height, if (!mpix) return FALSE; - ret = master->SharePixmapBacking(mpix, &fd_handle); - if (ret == FALSE) { + spix = PixmapShareToSlave(mpix, crtc->pScreen); + if (spix == NULL) { master->DestroyPixmap(mpix); return FALSE; } - spix = crtc->pScreen->CreatePixmap(crtc->pScreen, 0, 0, depth, - CREATE_PIXMAP_USAGE_SHARED); - crtc->pScreen->ModifyPixmapHeader(spix, width, height, depth, 0, - mpix->devKind, NULL); - - ret = crtc->pScreen->SetSharedPixmapBacking(spix, fd_handle); - if (ret == FALSE) { - ErrorF("failed to slave pixmap\n"); - crtc->pScreen->DestroyPixmap(spix); - master->DestroyPixmap(mpix); - return FALSE; - } - - spix->master_pixmap = mpix; ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix); if (ret == FALSE) { ErrorF("failed to set shadow slave pixmap\n"); @@ -1658,3 +1644,49 @@ RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, return; } } + +Bool +RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable) +{ + rrScrPriv(pDrawable->pScreen); + int i; + Bool size_fits = FALSE; + Bool changed = FALSE; + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + + if (!crtc->mode) + continue; + + changed = FALSE; + if (crtc->x == pDrawable->x && + crtc->y == pDrawable->y && + crtc->mode->mode.width == pDrawable->width && + crtc->mode->mode.height == pDrawable->height) + size_fits = TRUE; + + if (crtc->scanout_pixmap == pPixmap) { + if (size_fits) + return; + if (enable == FALSE) { + pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); + crtc->scanout_pixmap = NULL; + changed = TRUE; + } + } else { + if (!size_fits) + return; + if (enable) { + crtc->scanout_pixmap = pPixmap; + pScrPriv->rrCrtcSetScanoutPixmap(crtc, pPixmap); + changed = TRUE; + } + } + + if (changed && pScrPriv->rrCrtcSet) { + (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y, + crtc->rotation, crtc->numOutputs, crtc->outputs); + + } + } +} |