summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drmmode_display.c51
-rw-r--r--src/drmmode_display.h4
-rw-r--r--src/radeon.h13
-rw-r--r--src/radeon_dri2.c2
-rw-r--r--src/radeon_kms.c28
-rw-r--r--src/radeon_present.c2
6 files changed, 98 insertions, 2 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 7ad3235a..f55677f6 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -34,6 +34,7 @@
#include <time.h>
#include "cursorstr.h"
#include "damagestr.h"
+#include "inputstr.h"
#include "list.h"
#include "micmap.h"
#include "xf86cmap.h"
@@ -2628,6 +2629,56 @@ Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo
}
+static void drmmode_sprite_do_set_cursor(struct radeon_device_priv *device_priv,
+ ScrnInfoPtr scrn, int x, int y)
+{
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ CursorPtr cursor = device_priv->cursor;
+ Bool sprite_visible = device_priv->sprite_visible;
+
+ if (cursor) {
+ x -= cursor->bits->xhot;
+ y -= cursor->bits->yhot;
+
+ device_priv->sprite_visible =
+ x < scrn->virtualX && y < scrn->virtualY &&
+ (x + cursor->bits->width > 0) &&
+ (y + cursor->bits->height > 0);
+ } else {
+ device_priv->sprite_visible = FALSE;
+ }
+
+ info->sprites_visible += device_priv->sprite_visible - sprite_visible;
+}
+
+void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+ CursorPtr pCursor, int x, int y)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ struct radeon_device_priv *device_priv =
+ dixLookupScreenPrivate(&pDev->devPrivates,
+ &radeon_device_private_key, pScreen);
+
+ device_priv->cursor = pCursor;
+ drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
+
+ info->SetCursor(pDev, pScreen, pCursor, x, y);
+}
+
+void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
+ int y)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+ RADEONInfoPtr info = RADEONPTR(scrn);
+ struct radeon_device_priv *device_priv =
+ dixLookupScreenPrivate(&pDev->devPrivates,
+ &radeon_device_private_key, pScreen);
+
+ drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
+
+ info->MoveCursor(pDev, pScreen, x, y);
+}
void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo)
{
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 8387279f..39d2d94a 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -206,6 +206,10 @@ extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp);
extern void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
+extern void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+ CursorPtr pCursor, int x, int y);
+extern void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
+ int y);
extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
diff --git a/src/radeon.h b/src/radeon.h
index cc5dc09f..9658e029 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -500,6 +500,13 @@ struct radeon_client_priv {
uint_fast32_t needs_flush;
};
+struct radeon_device_priv {
+ CursorPtr cursor;
+ Bool sprite_visible;
+};
+
+extern DevScreenPrivateKeyRec radeon_device_private_key;
+
typedef struct {
EntityInfoPtr pEnt;
pciVideoPtr PciInfo;
@@ -550,6 +557,12 @@ typedef struct {
CreateScreenResourcesProcPtr CreateScreenResources;
CreateWindowProcPtr CreateWindow;
WindowExposuresProcPtr WindowExposures;
+ void (*SetCursor) (DeviceIntPtr pDev, ScreenPtr pScreen,
+ CursorPtr pCursor, int x, int y);
+ void (*MoveCursor) (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
+
+ /* Number of SW cursors currently visible on this screen */
+ int sprites_visible;
Bool IsSecondary;
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index b569bb4f..8376848c 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -723,7 +723,7 @@ can_flip(xf86CrtcPtr crtc, DrawablePtr draw,
if (draw->type != DRAWABLE_WINDOW ||
!info->allowPageFlip ||
- info->hwcursor_disabled ||
+ info->sprites_visible > 0 ||
info->drmmode.present_flipping ||
!pScrn->vtSema ||
!DRI2CanFlip(draw))
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 602a8fb7..c1f885eb 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -38,6 +38,7 @@
#include "radeon_reg.h"
#include "radeon_probe.h"
#include "micmap.h"
+#include "mipointrst.h"
#include "radeon_version.h"
#include "shadow.h"
@@ -66,6 +67,7 @@
#include "radeon_vbo.h"
static DevScreenPrivateKeyRec radeon_client_private_key;
+DevScreenPrivateKeyRec radeon_device_private_key;
extern SymTabRec RADEONChipsets[];
static Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
@@ -1991,6 +1993,23 @@ static Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
/* Cursor setup */
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+ if (info->allowPageFlip) {
+ miPointerScreenPtr PointPriv =
+ dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ if (!dixRegisterScreenPrivateKey(&radeon_device_private_key, pScreen,
+ PRIVATE_DEVICE,
+ sizeof(struct radeon_device_priv))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "dixRegisterScreenPrivateKey failed\n");
+ return FALSE;
+ }
+
+ info->SetCursor = PointPriv->spriteFuncs->SetCursor;
+ info->MoveCursor = PointPriv->spriteFuncs->MoveCursor;
+ PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor;
+ PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor;
+ }
+
if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
return TRUE;
@@ -2147,6 +2166,15 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen)
pScrn->vtSema = FALSE;
xf86ClearPrimInitDone(info->pEnt->index);
+
+ if (info->allowPageFlip) {
+ miPointerScreenPtr PointPriv =
+ dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ PointPriv->spriteFuncs->SetCursor = info->SetCursor;
+ PointPriv->spriteFuncs->MoveCursor = info->MoveCursor;
+ }
+
pScreen->BlockHandler = info->BlockHandler;
pScreen->CloseScreen = info->CloseScreen;
return pScreen->CloseScreen(pScreen);
diff --git a/src/radeon_present.c b/src/radeon_present.c
index 176853d9..d734b9d4 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -289,7 +289,7 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
if (!info->allowPageFlip)
return FALSE;
- if (info->hwcursor_disabled)
+ if (info->sprites_visible > 0)
return FALSE;
if (info->drmmode.dri2_flipping)