[PATCH] randr/prime: Don't stop on the first pipe when disabling ReplaceScanoutPixmap

Chris Wilson chris at chris-wilson.co.uk
Mon Oct 6 01:27:05 PDT 2014


As we define sizeFits based on whether a CRTC is active, and skip trying
to redirect the scanout on a disable pipe, we then attempt to undo it
later and fail because crtc->scanout_pixmap != DRI2_Pixmap and
!sizeFits. Paper over this failure by skipping unredirected CRTC when
disabling.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=84653
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Dave Airlie <airlied at redhat.com>
---
 randr/rrcrtc.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 69b3ecf..43ae653 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1667,23 +1667,24 @@ Bool
 RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
 {
     rrScrPriv(pDrawable->pScreen);
-    int i;
-    Bool size_fits = FALSE;
-    Bool changed = FALSE;
     Bool ret = TRUE;
+    int i;
 
     for (i = 0; i < pScrPriv->numCrtcs; i++) {
         RRCrtcPtr crtc = pScrPriv->crtcs[i];
+        Bool size_fits, changed;
 
         if (!crtc->mode && enable)
             continue;
+        if (!crtc->scanout_pixmap && !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;
+        size_fits = (crtc->mode &&
+                     crtc->x == pDrawable->x &&
+                     crtc->y == pDrawable->y &&
+                     crtc->mode->mode.width == pDrawable->width &&
+                     crtc->mode->mode.height == pDrawable->height);
 
         /* is the pixmap already set? */
         if (crtc->scanout_pixmap == pPixmap) {
@@ -1692,22 +1693,24 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
                 /* 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;
+            } else if (!size_fits) {
                 /* if the size no longer fits then drop off */
                 crtc->scanout_pixmap = NULL;
                 changed = TRUE;
                 ret = FALSE;
+            } else {
+                /* if the size fits then we are already setup */
             }
         } else {
-            if (!size_fits)
-                return FALSE;
-            if (enable) {
+            if (!size_fits) {
+                ret = FALSE;
+            } else if (enable) {
                 crtc->scanout_pixmap = pPixmap;
                 pScrPriv->rrCrtcSetScanoutPixmap(crtc, pPixmap);
                 changed = TRUE;
+            } else {
+                /* reject an attempt to disable someone else's scanout_pixmap */
+                ret = FALSE;
             }
         }
 
@@ -1718,5 +1721,7 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
                                     crtc->rotation, crtc->numOutputs, crtc->outputs);
         }
     }
+
+    /* XXX unwind failure? */
     return ret;
 }
-- 
1.9.1



More information about the xorg-devel mailing list