summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@gmail.com>2015-06-09 15:52:02 +1000
committerDave Airlie <airlied@gmail.com>2016-02-09 09:56:45 +1000
commit72fef0c10e975659aa0b38a5e1361819bc51acd5 (patch)
tree71e8af90c876ed5b520f92449155db879de37b79
parenta722d617a092f08f69086630f5cfb598d4a21cc7 (diff)
cursor: 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. Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--dix/dispatch.c2
-rw-r--r--hw/xfree86/ramdac/xf86Cursor.c12
-rw-r--r--hw/xfree86/ramdac/xf86CursorPriv.h1
-rw-r--r--hw/xfree86/ramdac/xf86HWCurs.c92
4 files changed, 94 insertions, 13 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 53032dc64..10c54ca02 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3924,6 +3924,8 @@ AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
update_desktop_dimensions();
+ dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR,
+ 0);
return i;
}
diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 2a54571cb..175bed75d 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -337,17 +337,9 @@ 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 ||
- ((
- 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,
NullCursor, x, y);
diff --git a/hw/xfree86/ramdac/xf86CursorPriv.h b/hw/xfree86/ramdac/xf86CursorPriv.h
index f34c1c7fc..397d2a14b 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 84febe0df..84d1ff787 100644
--- a/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/hw/xfree86/ramdac/xf86HWCurs.c
@@ -119,8 +119,52 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
return TRUE;
}
+static Bool
+xf86CursorScreenCheckHW(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)
+xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
+{
+ ScreenPtr pSlave;
+ PixmapDirtyUpdatePtr ent;
+ Bool ret;
+ ret = xf86CursorScreenCheckHW(pScreen, cursor, infoPtr);
+ if (ret == FALSE)
+ return FALSE;
+
+ if (xorg_list_is_empty(&pScreen->pixmap_dirty_list))
+ return TRUE;
+
+ /* ask each driver consuming a pixmap if it can support HW cursor */
+ xorg_list_for_each_entry(ent, &pScreen->pixmap_dirty_list, ent) {
+ xf86CursorScreenPtr ScreenPriv;
+ xf86CursorInfoPtr slaveInfoPtr;
+
+ pSlave = ent->slave_dst->drawable.pScreen;
+
+ ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pSlave->devPrivates,
+ xf86CursorScreenKey);
+ slaveInfoPtr = ScreenPriv->CursorInfoPtr;
+ ret = xf86CursorScreenCheckHW(pSlave, cursor, slaveInfoPtr);
+ if (ret == FALSE)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static Bool
+xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
{
xf86CursorScreenPtr ScreenPriv =
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
@@ -165,6 +209,30 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
return TRUE;
}
+Bool
+xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
+{
+ ScreenPtr pSlave;
+ PixmapDirtyUpdatePtr ent;
+ Bool ret;
+
+ ret = xf86ScreenSetCursor(pScreen, pCurs, x, y);
+ if (ret == FALSE)
+ return FALSE;
+
+ if (xorg_list_is_empty(&pScreen->pixmap_dirty_list))
+ return TRUE;
+
+ /* ask each driver consuming a pixmap if it can support HW cursor */
+ xorg_list_for_each_entry(ent, &pScreen->pixmap_dirty_list, ent) {
+ pSlave = ent->slave_dst->drawable.pScreen;
+ ret = xf86ScreenSetCursor(pSlave, pCurs, x, y);
+ if (ret == FALSE)
+ return ret;
+ }
+ return TRUE;
+}
+
void
xf86SetTransparentCursor(ScreenPtr pScreen)
{
@@ -187,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,
@@ -202,6 +270,24 @@ xf86MoveCursor(ScreenPtr pScreen, int x, int y)
}
void
+xf86MoveCursor(ScreenPtr pScreen, int x, int y)
+{
+ ScreenPtr pSlave;
+ PixmapDirtyUpdatePtr ent;
+
+ xf86ScreenMoveCursor(pScreen, x, y);
+
+ if (xorg_list_is_empty(&pScreen->pixmap_dirty_list))
+ return;
+
+ /* ask each driver consuming a pixmap if it can support HW cursor */
+ xorg_list_for_each_entry(ent, &pScreen->pixmap_dirty_list, ent) {
+ pSlave = ent->slave_dst->drawable.pScreen;
+ xf86ScreenMoveCursor(pSlave, x, y);
+ }
+}
+
+void
xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
{
xf86CursorScreenPtr ScreenPriv =