summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-07-15 10:15:51 +1000
committerHans de Goede <hdegoede@redhat.com>2016-09-13 10:27:19 +0200
commit7b634067c13045671685a9f00bfbac626ed68f94 (patch)
tree87e229967549b50c00b422d9d42f30c5b9932aca
parentdf88008f92f85ef96d9fe48ac509d027570424eb (diff)
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@nvidia.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> Reviewed-by: Keith Packard <keithp@keithp.com>
-rw-r--r--dix/dispatch.c10
-rw-r--r--hw/xfree86/ramdac/xf86Cursor.c2
-rw-r--r--hw/xfree86/ramdac/xf86HWCurs.c82
3 files changed, 88 insertions, 6 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c
index a3c2fbb31..0edcfeea8 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 623a65b33..afcce5353 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 1b85e6346..e8966ed35 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 =