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>
This commit is contained in:
Dave Airlie 2015-07-15 10:15:51 +10:00 committed by Hans de Goede
parent df88008f92
commit 7b634067c1
3 changed files with 88 additions and 6 deletions

View File

@ -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;
}

View File

@ -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))) {

View File

@ -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,
@ -213,6 +269,22 @@ xf86MoveCursor(ScreenPtr pScreen, int x, int y)
(*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, 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)
{