xserver: Branch 'master' - 13 commits

Adam Jackson ajax at kemper.freedesktop.org
Tue Sep 13 15:05:25 UTC 2016


 dix/dispatch.c                          |   10 +++
 dix/privates.c                          |    9 +++
 glamor/glamor.c                         |   20 +++++++
 glamor/glamor.h                         |   20 +++++++
 glamor/glamor_egl.c                     |   10 +++
 hw/xfree86/drivers/modesetting/dri2.c   |    2 
 hw/xfree86/drivers/modesetting/driver.c |    3 -
 hw/xfree86/drivers/modesetting/driver.h |    2 
 hw/xfree86/drivers/modesetting/vblank.c |   23 ++------
 hw/xfree86/modes/xf86Cursors.c          |   55 ++++++++++++++-----
 hw/xfree86/ramdac/xf86Cursor.c          |   20 ++-----
 hw/xfree86/ramdac/xf86CursorPriv.h      |    1 
 hw/xfree86/ramdac/xf86HWCurs.c          |   90 ++++++++++++++++++++++++++++++--
 include/privates.h                      |    3 +
 randr/randrstr.h                        |    6 ++
 randr/rrcrtc.c                          |   21 +++++++
 16 files changed, 244 insertions(+), 51 deletions(-)

New commits:
commit 35c4e96ed1d372dd161480be8cddcd2d4549e449
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Sep 12 12:47:59 2016 +0200

    randr: Fix crtc_bounds when using rotation combined with reflection
    
    Before this commit crtc_bounds() did not take reflection into account,
    when using reflection with 0 / 180 degree rotation this was not an
    issue because of the default in the switch-case doing the right thing.
    
    But when using 90 / 270 degree rotation we would also end up in the
    default which is wrong in this case. This would lead to the cursor
    being constrained to a height x height area of the monitor.
    
    This commit masks out the reflection bits for the switch-case,
    making crtc_bounds return the correct bounds and fixing the
    problematic cursor constraining.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 7636591..5d404e8 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -281,7 +281,7 @@ crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
     *left = crtc->x;
     *top = crtc->y;
 
-    switch (crtc->rotation) {
+    switch (crtc->rotation & 0xf) {
     case RR_Rotate_0:
     case RR_Rotate_180:
     default:
commit 7b634067c13045671685a9f00bfbac626ed68f94
Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jul 15 10:15:51 2015 +1000

    xf86Cursor: Add hw cursor support for prime
    
    Currently with PRIME if we detect a secondary GPU,
    we switch to using SW cursors, this isn't optimal,
    esp for the intel/nvidia combinations, we have
    no choice for the USB offload devices.
    
    This patch checks on each slave screen if hw
    cursors are enabled, and also calls set cursor
    and move cursor on all screens.
    
    Cc: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/dispatch.c b/dix/dispatch.c
index a3c2fbb..0edcfee 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3965,6 +3965,16 @@ AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
 
     update_desktop_dimensions();
 
+    /*
+     * We cannot register the Screen PRIVATE_CURSOR key if cursors are already
+     * created, because dix/privates.c does not have relocation code for
+     * PRIVATE_CURSOR. Once this is fixed the if() can be removed and we can
+     * register the Screen PRIVATE_CURSOR key unconditionally.
+     */
+    if (!dixPrivatesCreated(PRIVATE_CURSOR))
+        dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen,
+                                    PRIVATE_CURSOR, 0);
+
     return i;
 }
 
diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 623a65b..afcce53 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -337,7 +337,7 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
             return;
         }
 
-        if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
+        if (infoPtr->pScrn->vtSema &&
             (ScreenPriv->ForceHWCursorCount ||
              xf86CheckHWCursor(pScreen, cursor, infoPtr))) {
 
diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c
index 1b85e63..e8966ed 100644
--- a/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/hw/xfree86/ramdac/xf86HWCurs.c
@@ -17,6 +17,7 @@
 #include "cursorstr.h"
 #include "mi.h"
 #include "mipointer.h"
+#include "randrstr.h"
 #include "xf86CursorPriv.h"
 
 #include "servermd.h"
@@ -119,8 +120,8 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
     return TRUE;
 }
 
-Bool
-xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
+static Bool
+xf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
 {
     return
         (cursor->bits->argb && infoPtr->UseHWCursorARGB &&
@@ -132,7 +133,29 @@ xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr
 }
 
 Bool
-xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
+xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
+{
+    ScreenPtr pSlave;
+
+    if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr))
+        return FALSE;
+
+    /* ask each driver consuming a pixmap if it can support HW cursor */
+    xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
+        xf86CursorScreenPtr sPriv;
+
+        if (!RRHasScanoutPixmap(pSlave))
+            continue;
+
+        sPriv = dixLookupPrivate(&pSlave->devPrivates, xf86CursorScreenKey);
+        if (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+static Bool
+xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
 {
     xf86CursorScreenPtr ScreenPriv =
         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
@@ -145,6 +168,14 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
         return TRUE;
     }
 
+    /*
+     * Hot plugged GPU's do not have a CursorScreenKey, force sw cursor.
+     * This check can be removed once dix/privates.c gets relocation code for
+     * PRIVATE_CURSOR. Also see the related comment in AddGPUScreen().
+     */
+    if (!_dixGetScreenPrivateKey(CursorScreenKey, pScreen))
+        return FALSE;
+
     bits =
         dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen);
 
@@ -177,6 +208,31 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
     return TRUE;
 }
 
+Bool
+xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
+{
+    ScreenPtr pSlave;
+
+    if (!xf86ScreenSetCursor(pScreen, pCurs, x, y))
+        return FALSE;
+
+    /* ask each slave driver to set the cursor. */
+    xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
+        if (!RRHasScanoutPixmap(pSlave))
+            continue;
+
+        if (!xf86ScreenSetCursor(pSlave, pCurs, x, y)) {
+            /*
+             * hide the master (and successfully set slave) cursors,
+             * otherwise both the hw and sw cursor will show.
+             */
+            xf86SetCursor(pScreen, NullCursor, x, y);
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
 void
 xf86SetTransparentCursor(ScreenPtr pScreen)
 {
@@ -199,8 +255,8 @@ xf86SetTransparentCursor(ScreenPtr pScreen)
     (*infoPtr->ShowCursor) (infoPtr->pScrn);
 }
 
-void
-xf86MoveCursor(ScreenPtr pScreen, int x, int y)
+static void
+xf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y)
 {
     xf86CursorScreenPtr ScreenPriv =
         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
@@ -214,6 +270,22 @@ xf86MoveCursor(ScreenPtr pScreen, int x, int y)
 }
 
 void
+xf86MoveCursor(ScreenPtr pScreen, int x, int y)
+{
+    ScreenPtr pSlave;
+
+    xf86ScreenMoveCursor(pScreen, x, y);
+
+    /* ask each slave driver to move the cursor */
+    xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
+        if (!RRHasScanoutPixmap(pSlave))
+            continue;
+
+        xf86ScreenMoveCursor(pSlave, x, y);
+    }
+}
+
+void
 xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
 {
     xf86CursorScreenPtr ScreenPriv =
commit df88008f92f85ef96d9fe48ac509d027570424eb
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Sep 6 11:48:31 2016 +0200

    xf86Cursor: Deal with rotation on GPU screens using a hw-cursor
    
    When a slave-output is rotated the transformation is done on the blit
    from master to slave GPU, so crtc->transform_in_use is not set, but we
    still need to adjust the mouse position for things to work.
    
    This commit modifies xf86_crtc_transform_cursor_position to not rely
    on crtc->f_framebuffer_to_crtc, so that it can be used with GPU screens
    too and always calls it for crtcs with any form of rotation.
    
    Note not using crtc->f_framebuffer_to_crtc means that crtc->transform
    will not be taken into account, that is ok, because when we've a transform
    active hw-cursors are not used and xf86_crtc_transform_cursor_position
    will never get called.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index c836534..1bc2b27 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -367,16 +367,45 @@ xf86_crtc_transform_cursor_position(xf86CrtcPtr crtc, int *x, int *y)
     xf86CursorScreenPtr ScreenPriv =
         (xf86CursorScreenPtr) dixLookupPrivate(&screen->devPrivates,
                                                xf86CursorScreenKey);
-    struct pict_f_vector v;
-    int dx, dy;
-
-    v.v[0] = (*x + ScreenPriv->HotX) + 0.5;
-    v.v[1] = (*y + ScreenPriv->HotY) + 0.5;
-    v.v[2] = 1;
-    pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v);
-    /* cursor will have 0.5 added to it already so floor is sufficent */
-    *x = floor(v.v[0]);
-    *y = floor(v.v[1]);
+    int dx, dy, t;
+    Bool swap_reflection = FALSE;
+
+    *x = *x - crtc->x + ScreenPriv->HotX;
+    *y = *y - crtc->y + ScreenPriv->HotY;
+
+    switch (crtc->rotation & 0xf) {
+    case RR_Rotate_0:
+        break;
+    case RR_Rotate_90:
+        t = *x;
+        *x = *y;
+        *y = crtc->mode.VDisplay - t - 1;
+        swap_reflection = TRUE;
+        break;
+    case RR_Rotate_180:
+        *x = crtc->mode.HDisplay - *x - 1;
+        *y = crtc->mode.VDisplay - *y - 1;
+        break;
+    case RR_Rotate_270:
+        t = *x;
+        *x = crtc->mode.HDisplay - *y - 1;
+        *y = t;
+        swap_reflection = TRUE;
+        break;
+    }
+
+    if (swap_reflection) {
+        if (crtc->rotation & RR_Reflect_Y)
+            *x = crtc->mode.HDisplay - *x - 1;
+        if (crtc->rotation & RR_Reflect_X)
+            *y = crtc->mode.VDisplay - *y - 1;
+    } else {
+        if (crtc->rotation & RR_Reflect_X)
+            *x = crtc->mode.HDisplay - *x - 1;
+        if (crtc->rotation & RR_Reflect_Y)
+            *y = crtc->mode.VDisplay - *y - 1;
+    }
+
     /*
      * Transform position of cursor upper left corner
      */
@@ -399,7 +428,7 @@ xf86_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
     /*
      * Transform position of cursor on screen
      */
-    if (crtc->transform_in_use)
+    if (crtc->rotation != RR_Rotate_0)
         xf86_crtc_transform_cursor_position(crtc, &crtc_x, &crtc_y);
     else {
         crtc_x -= crtc->x;
commit f82fd47016628e8bcdcba3aab506a919fe8c49d8
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Sep 6 11:50:50 2016 +0200

    xf86Cursor: Fix xf86_crtc_rotate_coord using width/height wrongly
    
    xf86_crtc_rotate_coord should be the exact inverse operation of
    xf86_crtc_rotate_coord_back, but when calculating x / y for 90 / 270
    degrees rotation it was using height to calculate x / width to calculate y,
    instead of the otherway around.
    
    This was likely not noticed before since xf86_crtc_rotate_coord
    until now was only used with cursor_info->MaxWidth and
    cursor_info->MaxHeight, which are usally the same.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index d1e3302..c836534 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -74,7 +74,7 @@ xf86_crtc_rotate_coord(Rotation rotation,
         break;
     case RR_Rotate_90:
         t = x_dst;
-        x_dst = height - y_dst - 1;
+        x_dst = width - y_dst - 1;
         y_dst = t;
         break;
     case RR_Rotate_180:
@@ -84,7 +84,7 @@ xf86_crtc_rotate_coord(Rotation rotation,
     case RR_Rotate_270:
         t = x_dst;
         x_dst = y_dst;
-        y_dst = width - t - 1;
+        y_dst = height - t - 1;
         break;
     }
     if (rotation & RR_Reflect_X)
commit b0b04cb266a62675dd7cde97111ebe7c1552db9a
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Sep 6 13:14:35 2016 +0200

    xf86Cursor: Fix xf86CurrentCursor to work on slave GPU Screens
    
    The CurrentCursor is always attached to the master GPU.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 0c5d6c9..623a65b 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -458,9 +458,12 @@ xf86ForceHWCursor(ScreenPtr pScreen, Bool on)
 CursorPtr
 xf86CurrentCursor(ScreenPtr pScreen)
 {
-    xf86CursorScreenPtr ScreenPriv =
-        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
-                                               xf86CursorScreenKey);
+    xf86CursorScreenPtr ScreenPriv;
+
+    if (pScreen->is_output_slave)
+        pScreen = pScreen->current_master;
+
+    ScreenPriv = dixLookupPrivate(&pScreen->devPrivates, xf86CursorScreenKey);
     return ScreenPriv->CurrentCursor;
 }
 
commit 71fecc84e9ceb11ff61c912bdaa3fc959ec36bef
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Sep 6 13:02:32 2016 +0200

    xf86Cursor: Add xf86CheckHWCursor() helper function
    
    This is a preparation patch for adding prime hw-cursor support.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index dda4349..0c5d6c9 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -339,14 +339,7 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
 
         if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
             (ScreenPriv->ForceHWCursorCount ||
-             ((
-               cursor->bits->argb &&
-               infoPtr->UseHWCursorARGB &&
-               (*infoPtr->UseHWCursorARGB)(pScreen, cursor)) ||
-              (cursor->bits->argb == 0 &&
-               (cursor->bits->height <= infoPtr->MaxHeight) &&
-               (cursor->bits->width <= infoPtr->MaxWidth) &&
-               (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, cursor)))))) {
+             xf86CheckHWCursor(pScreen, cursor, infoPtr))) {
 
             if (ScreenPriv->SWCursor)   /* remove the SW cursor */
                 (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
diff --git a/hw/xfree86/ramdac/xf86CursorPriv.h b/hw/xfree86/ramdac/xf86CursorPriv.h
index f34c1c7..397d2a1 100644
--- a/hw/xfree86/ramdac/xf86CursorPriv.h
+++ b/hw/xfree86/ramdac/xf86CursorPriv.h
@@ -43,6 +43,7 @@ void xf86MoveCursor(ScreenPtr pScreen, int x, int y);
 void xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed);
 Bool xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr);
 
+Bool xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr);
 extern _X_EXPORT DevPrivateKeyRec xf86CursorScreenKeyRec;
 
 #define xf86CursorScreenKey (&xf86CursorScreenKeyRec)
diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c
index 84febe0..1b85e63 100644
--- a/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/hw/xfree86/ramdac/xf86HWCurs.c
@@ -120,6 +120,18 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
 }
 
 Bool
+xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
+{
+    return
+        (cursor->bits->argb && infoPtr->UseHWCursorARGB &&
+         infoPtr->UseHWCursorARGB(pScreen, cursor)) ||
+        (cursor->bits->argb == 0 &&
+         cursor->bits->height <= infoPtr->MaxHeight &&
+         cursor->bits->width <= infoPtr->MaxWidth &&
+         (!infoPtr->UseHWCursor || infoPtr->UseHWCursor(pScreen, cursor)));
+}
+
+Bool
 xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
 {
     xf86CursorScreenPtr ScreenPriv =
commit 2eefb53f58854ef9d34859583207ec37d3c3047a
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Sep 6 13:15:36 2016 +0200

    randr: Add RRHasScanoutPixmap helper function
    
    This is a preparation patch for adding prime hw-cursor support.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/randr/randrstr.h b/randr/randrstr.h
index 1baa912..706e9a7 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -726,6 +726,12 @@ extern _X_EXPORT Bool
  RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable);
 
 /*
+ * Return if the screen has any scanout_pixmap's attached
+ */
+extern _X_EXPORT Bool
+ RRHasScanoutPixmap(ScreenPtr pScreen);
+
+/*
  * Crtc dispatch
  */
 
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 8fb2bca..7636591 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1945,3 +1945,22 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
 
     return ret;
 }
+
+Bool
+RRHasScanoutPixmap(ScreenPtr pScreen)
+{
+    rrScrPriv(pScreen);
+    int i;
+
+    if (!pScreen->is_output_slave)
+        return FALSE;
+
+    for (i = 0; i < pScrPriv->numCrtcs; i++) {
+        RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+        if (crtc->scanout_pixmap)
+            return TRUE;
+    }
+    
+    return FALSE;
+}
commit a52530a655438f03919d47f6edd11287efff47bb
Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Sep 6 12:50:14 2016 +0200

    dix: Add dixPrivatesCreated helper function
    
    This is a preparation patch for adding prime hw-cursor support.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/dix/privates.c b/dix/privates.c
index 969d014..478f52c 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -783,3 +783,12 @@ dixResetPrivates(void)
         global_keys[t].allocated = 0;
     }
 }
+
+Bool
+dixPrivatesCreated(DevPrivateType type)
+{
+    if (global_keys[type].created)
+        return TRUE;
+    else
+        return FALSE;
+}
diff --git a/include/privates.h b/include/privates.h
index 7d1461c..a2bb1a4 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -252,6 +252,9 @@ dixFreeScreenSpecificPrivates(ScreenPtr pScreen);
 extern void
 dixInitScreenSpecificPrivates(ScreenPtr pScreen);
 
+/* is this private created - so hotplug can avoid crashing */
+Bool dixPrivatesCreated(DevPrivateType type);
+
 extern _X_EXPORT void *
 _dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
                                      unsigned size,
commit 3fe4107643ba029dd48e3d12ec9bc97d07112300
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Sep 8 09:30:31 2016 +0200

    glamor: Fix crash when master gpu is using glamor and another gpu is hotplugged
    
    When a GPU gets hotplugged while X is already running, glamor_egl_init()
    gets called and changes the current egl context, without updating
    lastGLContext, potentially causing the next glamor call on another GPU to
    run in the wrong context.
    
    This causes glamor to e.g. crash in the next glamor_create_pixmap() call
    (called through the master's screen->CreatePixmap), note this is not the
    only troublesome entry point I've seen other backtraces when using a
    compositing window manager.
    
    Set lastGLContext to NULL to force the next glamor_make_current() call
    to set the right context.
    
    Note that we cannot use glamor_make_current() here to replace the
    eglMakeCurrent() call and update lastGLContext for us because
    glamor_make_current takes a glamor_priv struct as argument and that
    has not been created yet when glamor_egl_init() gets called.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 16a20a7..2b9e0e1 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -703,6 +703,11 @@ static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl)
     if (glamor_egl->display != EGL_NO_DISPLAY) {
         eglMakeCurrent(glamor_egl->display,
                        EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        /*
+         * Force the next glamor_make_current call to update the context
+         * (on hot unplug another GPU may still be using glamor)
+         */
+        lastGLContext = NULL;
         eglTerminate(glamor_egl->display);
     }
 #ifdef GLAMOR_HAS_GBM
@@ -831,6 +836,11 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
                    "Failed to make EGL context current\n");
         goto error;
     }
+    /*
+     * Force the next glamor_make_current call to set the right context
+     * (in case of multiple GPUs using glamor)
+     */
+    lastGLContext = NULL;
 #ifdef GLAMOR_HAS_GBM
     if (epoxy_has_egl_extension(glamor_egl->display,
                                 "EGL_KHR_gl_texture_2D_image") &&
commit 1075af8a6c26009c04db30a6d6d1f10070568ab1
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Aug 15 11:10:15 2016 +0200

    modesetting: Remove some dead code
    
    The "if (pixmap) ..." block this commit removes is inside an
    "if (pixmap == NULL) ..." block, so it will never execute.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>

diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 65f2ecf..cbef2e6 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -193,8 +193,6 @@ ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
                                       pixmap_cpp,
                                       0);
         if (pixmap == NULL) {
-            if (pixmap)
-                screen->DestroyPixmap(pixmap);
             free(private);
             free(buffer);
             return NULL;
commit dfa295b29c20b174f80ab823eef41e5211a6a921
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Aug 24 14:13:19 2016 +0200

    modesetting: ms_covering_crtc: Remove unused arguments, make static
    
    Remove unused arguments from ms_covering_crtc, make it static as it is
    only used in vblank.c.
    
    While at it also change its first argument from a ScrnInfoPtr to a
    ScreenPtr, this makes the next patch in this patch-set cleaner.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 761490a..aa00d05 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -137,8 +137,6 @@ void ms_drm_abort_seq(ScrnInfoPtr scrn, uint32_t seq);
 Bool ms_crtc_on(xf86CrtcPtr crtc);
 
 xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
-xf86CrtcPtr ms_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
-                             xf86CrtcPtr desired, BoxPtr crtc_box_ret);
 
 int ms_get_crtc_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
 
diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index d5a9ded..6547d9d 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -92,14 +92,13 @@ ms_crtc_on(xf86CrtcPtr crtc)
 
 /*
  * Return the crtc covering 'box'. If two crtcs cover a portion of
- * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
- * with greater coverage
+ * 'box', then prefer the crtc with greater coverage.
  */
 
-xf86CrtcPtr
-ms_covering_crtc(ScrnInfoPtr scrn,
-                 BoxPtr box, xf86CrtcPtr desired, BoxPtr crtc_box_ret)
+static xf86CrtcPtr
+ms_covering_crtc(ScreenPtr pScreen, BoxPtr box)
 {
+    ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CrtcPtr crtc, best_crtc;
     int coverage, best_coverage;
@@ -108,10 +107,6 @@ ms_covering_crtc(ScrnInfoPtr scrn,
 
     best_crtc = NULL;
     best_coverage = 0;
-    crtc_box_ret->x1 = 0;
-    crtc_box_ret->x2 = 0;
-    crtc_box_ret->y1 = 0;
-    crtc_box_ret->y2 = 0;
     for (c = 0; c < xf86_config->num_crtc; c++) {
         crtc = xf86_config->crtc[c];
 
@@ -122,12 +117,7 @@ ms_covering_crtc(ScrnInfoPtr scrn,
         ms_crtc_box(crtc, &crtc_box);
         ms_box_intersect(&cover_box, &crtc_box, box);
         coverage = ms_box_area(&cover_box);
-        if (coverage && crtc == desired) {
-            *crtc_box_ret = crtc_box;
-            return crtc;
-        }
         if (coverage > best_coverage) {
-            *crtc_box_ret = crtc_box;
             best_crtc = crtc;
             best_coverage = coverage;
         }
@@ -139,15 +129,14 @@ xf86CrtcPtr
 ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
 {
     ScreenPtr pScreen = pDraw->pScreen;
-    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
-    BoxRec box, crtcbox;
+    BoxRec box;
 
     box.x1 = pDraw->x;
     box.y1 = pDraw->y;
     box.x2 = box.x1 + pDraw->width;
     box.y2 = box.y1 + pDraw->height;
 
-    return ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
+    return ms_covering_crtc(pScreen, &box);
 }
 
 static Bool
commit cb7b145a25452de8b549e8c8e9ec3bcc752e55dc
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Aug 17 12:03:41 2016 +0200

    modesetting: Fix msSharePixmapBacking returning a non-linear bo
    
    glamor_fd_from_pixmap() may return a tiled bo, which is not suitable
    for sharing with another GPU as tiling usually is GPU specific.
    
    Switch to glamor_shareable_fd_from_pixmap(), which always returns a
    linear bo. This fixes mis-rendering when running the mode setting
    driver on the master gpu in a dual-gpu setup and running an opengl
    app with DRI_PRIME=1.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 5ebb394..a8e83b2 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1382,7 +1382,8 @@ msSharePixmapBacking(PixmapPtr ppix, ScreenPtr screen, void **handle)
     int ret;
     CARD16 stride;
     CARD32 size;
-    ret = glamor_fd_from_pixmap(ppix->drawable.pScreen, ppix, &stride, &size);
+    ret = glamor_shareable_fd_from_pixmap(ppix->drawable.pScreen, ppix,
+                                          &stride, &size);
     if (ret == -1)
         return FALSE;
 
commit a74d553cb97d545148bd2f81b7bd021cca94e076
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Tue Aug 23 12:18:56 2016 +0200

    glamor: Add glamor_shareable_fd_from_pixmap()
    
    Add glamor_shareable_fd_from_pixmap function to get dma-buf fds suitable
    for sharing across GPUs (not using GPU specific tiling).
    
    This is necessary for the modesetting driver to correctly implement
    the DRI2 SharePixmapBacking callback.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 5ba440c..903f6bd 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -821,6 +821,26 @@ glamor_fd_from_pixmap(ScreenPtr screen,
     return -1;
 }
 
+_X_EXPORT int
+glamor_shareable_fd_from_pixmap(ScreenPtr screen,
+                                PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
+{
+    unsigned orig_usage_hint = pixmap->usage_hint;
+    int ret;
+
+    /*
+     * The actual difference between a sharable and non sharable buffer
+     * is decided 4 call levels deep in glamor_make_pixmap_exportable()
+     * based on pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED
+     * 2 of those calls are also exported API, so we cannot just add a flag.
+     */
+    pixmap->usage_hint = CREATE_PIXMAP_USAGE_SHARED;
+    ret = glamor_fd_from_pixmap(screen, pixmap, stride, size);
+    pixmap->usage_hint = orig_usage_hint;
+
+    return ret;
+}
+
 int
 glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
 {
diff --git a/glamor/glamor.h b/glamor/glamor.h
index e27033a..bdd2374 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -181,6 +181,26 @@ extern _X_EXPORT int glamor_fd_from_pixmap(ScreenPtr screen,
                                            PixmapPtr pixmap,
                                            CARD16 *stride, CARD32 *size);
 
+/* @glamor_shareable_fd_from_pixmap: Get a dma-buf fd suitable for sharing
+ *				     with other GPUs from a pixmap.
+ *
+ * @screen: Current screen pointer.
+ * @pixmap: The pixmap from which we want the fd.
+ * @stride, @size: Pointers to fill the stride and size of the
+ * 		   buffer associated to the fd.
+ *
+ * The returned fd will point to a buffer which is suitable for sharing
+ * across GPUs (not using GPU specific tiling).
+ * The pixmap and the buffer associated by the fd will share the same
+ * content.
+ * The pixmap's stride may be modified by this function.
+ * Returns the fd on success, -1 on error.
+ * */
+extern _X_EXPORT int glamor_shareable_fd_from_pixmap(ScreenPtr screen,
+                                                     PixmapPtr pixmap,
+                                                     CARD16 *stride,
+                                                     CARD32 *size);
+
 /**
  * @glamor_name_from_pixmap: Gets a gem name from a pixmap.
  *


More information about the xorg-commit mailing list