From 6150bf1b3e7ad1a69ca297fec93ef9d3b93a8312 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 26 Jun 2012 10:00:21 +0100 Subject: dix/randr: add a hook into screen to replace scanout pixmap For DRI2 in some offload cases we need to set a new pixmap on the crtc, this hook allows dri2 to call into randr to do the necessary work to set a pixmap as the scanout pixmap for the crtc the drawable is currently on. This is really only to be used for unredirected full screen apps in composited environments. Signed-off-by: Dave Airlie --- include/scrnintstr.h | 3 +++ randr/randr.c | 2 +- randr/randrstr.h | 3 +++ randr/rrcrtc.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/include/scrnintstr.h b/include/scrnintstr.h index 80601b9f2..df7407391 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; @@ -510,6 +512,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 ae8116677..3050c54fe 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -324,7 +324,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 64c9afbb3..968cd3080 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -678,6 +678,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 949ae6028..1a6e59350 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -1641,3 +1641,61 @@ 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; + Bool ret = TRUE; + + for (i = 0; i < pScrPriv->numCrtcs; i++) { + RRCrtcPtr crtc = pScrPriv->crtcs[i]; + + if (!crtc->mode && enable) + continue; + + changed = FALSE; + if (crtc->mode && crtc->x == pDrawable->x && + crtc->y == pDrawable->y && + crtc->mode->mode.width == pDrawable->width && + crtc->mode->mode.height == pDrawable->height) + size_fits = TRUE; + + /* is the pixmap already set? */ + if (crtc->scanout_pixmap == pPixmap) { + /* if its a disable then don't care about size */ + if (enable == FALSE) { + /* set scanout to NULL */ + crtc->scanout_pixmap = NULL; + changed = TRUE; + } else { + /* if the size fits then we are already setup */ + if (size_fits) + return TRUE; + /* if the size no longer fits then drop off */ + crtc->scanout_pixmap = NULL; + changed = TRUE; + ret = FALSE; + } + } else { + if (!size_fits) + return FALSE; + if (enable) { + crtc->scanout_pixmap = pPixmap; + pScrPriv->rrCrtcSetScanoutPixmap(crtc, pPixmap); + changed = TRUE; + } + } + + if (changed && pScrPriv->rrCrtcSet) { + pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap); + + (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y, + crtc->rotation, crtc->numOutputs, crtc->outputs); + } + } + return ret; +} -- cgit v1.2.3