[PATCH xf86-video-ati] Wrap the whole miPointerScreenFuncRec, instead of only Set/MoveCursor

Michel Dänzer michel at daenzer.net
Wed Mar 7 17:39:50 UTC 2018


From: Michel Dänzer <michel.daenzer at amd.com>

We were clobbering entries in mi's global miSpritePointerFuncs struct,
which cannot work correctly with multiple primary screens. Instead,
assign a pointer to our own wrapper struct to PointPriv->spriteFuncs.

Fixes crashes with multiple primary screens.

Fixes: 1fe8ca75974c ("Keep track of how many SW cursors are visible on
                      each screen")
Reported-by: Mario Kleiner <mario.kleiner.de at gmail.com>
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/drmmode_display.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++-----
 src/drmmode_display.h |  7 +++---
 src/radeon.h          |  4 +---
 src/radeon_kms.c      | 14 ++++--------
 4 files changed, 63 insertions(+), 23 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index b1f5c4888..93261dc8d 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -37,6 +37,7 @@
 #include "inputstr.h"
 #include "list.h"
 #include "micmap.h"
+#include "mipointrst.h"
 #include "xf86cmap.h"
 #include "xf86Priv.h"
 #include "radeon.h"
@@ -2750,8 +2751,8 @@ static void drmmode_sprite_do_set_cursor(struct radeon_device_priv *device_priv,
 	info->sprites_visible += device_priv->sprite_visible - sprite_visible;
 }
 
-void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
-			       CursorPtr pCursor, int x, int y)
+static void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+				      CursorPtr pCursor, int x, int y)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
 	RADEONInfoPtr info = RADEONPTR(scrn);
@@ -2762,11 +2763,11 @@ void drmmode_sprite_set_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
 	device_priv->cursor = pCursor;
 	drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
 
-	info->SetCursor(pDev, pScreen, pCursor, x, y);
+	info->SpriteFuncs->SetCursor(pDev, pScreen, pCursor, x, y);
 }
 
-void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
-				int y)
+static void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+				       int x, int y)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
 	RADEONInfoPtr info = RADEONPTR(scrn);
@@ -2776,9 +2777,57 @@ void drmmode_sprite_move_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x,
 
 	drmmode_sprite_do_set_cursor(device_priv, scrn, x, y);
 
-	info->MoveCursor(pDev, pScreen, x, y);
+	info->SpriteFuncs->MoveCursor(pDev, pScreen, x, y);
 }
 
+static Bool drmmode_sprite_realize_realize_cursor(DeviceIntPtr pDev,
+						  ScreenPtr pScreen,
+						  CursorPtr pCursor)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+	RADEONInfoPtr info = RADEONPTR(scrn);
+
+	return info->SpriteFuncs->RealizeCursor(pDev, pScreen, pCursor);
+}
+
+static Bool drmmode_sprite_realize_unrealize_cursor(DeviceIntPtr pDev,
+						    ScreenPtr pScreen,
+						    CursorPtr pCursor)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+	RADEONInfoPtr info = RADEONPTR(scrn);
+
+	return info->SpriteFuncs->UnrealizeCursor(pDev, pScreen, pCursor);
+}
+
+static Bool drmmode_sprite_device_cursor_initialize(DeviceIntPtr pDev,
+						    ScreenPtr pScreen)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+	RADEONInfoPtr info = RADEONPTR(scrn);
+
+	return info->SpriteFuncs->DeviceCursorInitialize(pDev, pScreen);
+}
+
+static void drmmode_sprite_device_cursor_cleanup(DeviceIntPtr pDev,
+						 ScreenPtr pScreen)
+{
+	ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+	RADEONInfoPtr info = RADEONPTR(scrn);
+
+	info->SpriteFuncs->DeviceCursorCleanup(pDev, pScreen);
+}
+
+miPointerSpriteFuncRec drmmode_sprite_funcs = {
+	.RealizeCursor = drmmode_sprite_realize_realize_cursor,
+	.UnrealizeCursor = drmmode_sprite_realize_unrealize_cursor,
+	.SetCursor = drmmode_sprite_set_cursor,
+	.MoveCursor = drmmode_sprite_move_cursor,
+	.DeviceCursorInitialize = drmmode_sprite_device_cursor_initialize,
+	.DeviceCursorCleanup = drmmode_sprite_device_cursor_cleanup,
+};
+
+	
 void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo)
 {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 39d2d94a1..e0b97e721 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -206,10 +206,6 @@ 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,
@@ -249,5 +245,8 @@ Bool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type,
 			 uint64_t *ust, uint32_t *result_seq);
 
 
+miPointerSpriteFuncRec drmmode_sprite_funcs;
+
+
 #endif
 
diff --git a/src/radeon.h b/src/radeon.h
index 08e38c177..0815cd984 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -557,9 +557,7 @@ 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);
+    miPointerSpriteFuncPtr SpriteFuncs;
 
     /* Number of SW cursors currently visible on this screen */
     int sprites_visible;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 790d4be16..8c3d15eb0 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -2017,12 +2017,8 @@ static Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
 	    return FALSE;
 	}
 
-	if (PointPriv->spriteFuncs->SetCursor != drmmode_sprite_set_cursor) {
-	    info->SetCursor = PointPriv->spriteFuncs->SetCursor;
-	    info->MoveCursor = PointPriv->spriteFuncs->MoveCursor;
-	    PointPriv->spriteFuncs->SetCursor = drmmode_sprite_set_cursor;
-	    PointPriv->spriteFuncs->MoveCursor = drmmode_sprite_move_cursor;
-	}
+	info->SpriteFuncs = PointPriv->spriteFuncs;
+	PointPriv->spriteFuncs = &drmmode_sprite_funcs;
     }
 
     if (xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
@@ -2186,10 +2182,8 @@ static Bool RADEONCloseScreen_KMS(ScreenPtr pScreen)
 	miPointerScreenPtr PointPriv =
 	    dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
 
-	if (PointPriv->spriteFuncs->SetCursor == drmmode_sprite_set_cursor) {
-	    PointPriv->spriteFuncs->SetCursor = info->SetCursor;
-	    PointPriv->spriteFuncs->MoveCursor = info->MoveCursor;
-	}
+	if (PointPriv->spriteFuncs == &drmmode_sprite_funcs)
+	    PointPriv->spriteFuncs = info->SpriteFuncs;
     }
 
     pScreen->BlockHandler = info->BlockHandler;
-- 
2.16.2



More information about the amd-gfx mailing list