[PATCH 26/29] dix/randr: add a hook into screen to replace scanout pixmap

Dave Airlie airlied at gmail.com
Thu Jul 5 13:30:33 PDT 2012


From: Dave Airlie <airlied at redhat.com>

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 <airlied at redhat.com>
---
 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 80601b9..df74073 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 ae81166..3050c54 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 64c9afb..968cd30 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 949ae60..1a6e593 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;
+}
-- 
1.7.10.2



More information about the xorg-devel mailing list