summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2018-03-07 17:51:25 +0100
committerMichel Dänzer <michel@daenzer.net>2018-03-07 17:53:31 +0100
commit29649652a08ece7e07741be161b067a4484455ca (patch)
tree1b7036f7ec6fe6ef40da2b50b78d9833a2cf71e0
parentb4a28bdcfa7089e1cf708490ddf048b7df4c7eed (diff)
Wrap the whole miPointerScreenFuncRec, instead of only Set/MoveCursor
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: 69e20839bfeb ("Keep track of how many SW cursors are visible on each screen") Reported-by: Mario Kleiner <mario.kleiner.de@gmail.com>
-rw-r--r--src/amdgpu_drv.h4
-rw-r--r--src/amdgpu_kms.c14
-rw-r--r--src/drmmode_display.c61
-rw-r--r--src/drmmode_display.h7
4 files changed, 63 insertions, 23 deletions
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 4015726..acf6977 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -281,9 +281,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/amdgpu_kms.c b/src/amdgpu_kms.c
index 90e1f25..b287fcc 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -1551,12 +1551,8 @@ static Bool AMDGPUCursorInit_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))
@@ -1733,10 +1729,8 @@ static Bool AMDGPUCloseScreen_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;
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 746e52a..3513c1f 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 "sarea.h"
@@ -2550,8 +2551,8 @@ static void drmmode_sprite_do_set_cursor(struct amdgpu_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);
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
@@ -2562,11 +2563,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);
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
@@ -2576,9 +2577,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);
+ AMDGPUInfoPtr info = AMDGPUPTR(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);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+
+ return info->SpriteFuncs->UnrealizeCursor(pDev, pScreen, pCursor);
+}
+
+static Bool drmmode_sprite_device_cursor_initialize(DeviceIntPtr pDev,
+ ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+ AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+
+ return info->SpriteFuncs->DeviceCursorInitialize(pDev, pScreen);
+}
+
+static void drmmode_sprite_device_cursor_cleanup(DeviceIntPtr pDev,
+ ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
+ AMDGPUInfoPtr info = AMDGPUPTR(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 amdgpu_buffer *bo)
{
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 4e6f707..2aa5672 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -198,10 +198,6 @@ extern int drmmode_page_flip_target_relative(AMDGPUEntPtr pAMDGPUEnt,
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 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 amdgpu_buffer *bo);
void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
@@ -239,4 +235,7 @@ Bool drmmode_wait_vblank(xf86CrtcPtr crtc, drmVBlankSeqType type,
uint64_t *ust, uint32_t *result_seq);
+miPointerSpriteFuncRec drmmode_sprite_funcs;
+
+
#endif