diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2018-03-07 17:51:25 +0100 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2018-03-07 17:53:31 +0100 |
commit | 29649652a08ece7e07741be161b067a4484455ca (patch) | |
tree | 1b7036f7ec6fe6ef40da2b50b78d9833a2cf71e0 | |
parent | b4a28bdcfa7089e1cf708490ddf048b7df4c7eed (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.h | 4 | ||||
-rw-r--r-- | src/amdgpu_kms.c | 14 | ||||
-rw-r--r-- | src/drmmode_display.c | 61 | ||||
-rw-r--r-- | src/drmmode_display.h | 7 |
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 |