cursor-renderer/native: Clear active CRTC gbm_bo when destroyed

When we freed the cursor GPU state including the gbm_bo objects attached
to it, we didn't unset the cursor renderer private of the CRTCs of the
associated GPU. This means that HW cursor invalidation could potentially
break if a new gbm_bo happened to be allocated at the same memory
address as the previous one.

To avoid this, iterate through the CRTCs of the GPU of which the cursor
data is freed, and unset the cursor renderer private if it was the one
destroyed.

https://gitlab.gnome.org/GNOME/mutter/issues/199
This commit is contained in:
Jonas Ådahl 2019-02-08 19:33:09 +01:00
parent 22a296f971
commit 944a4763f6

View File

@ -104,6 +104,7 @@ typedef enum _MetaCursorGbmBoState
typedef struct _MetaCursorNativeGpuState typedef struct _MetaCursorNativeGpuState
{ {
MetaGpu *gpu;
guint active_bo; guint active_bo;
MetaCursorGbmBoState pending_bo_state; MetaCursorGbmBoState pending_bo_state;
struct gbm_bo *bos[HW_CURSOR_BUFFER_COUNT]; struct gbm_bo *bos[HW_CURSOR_BUFFER_COUNT];
@ -746,10 +747,30 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
!meta_cursor_sprite_get_cogl_texture (cursor_sprite)); !meta_cursor_sprite_get_cogl_texture (cursor_sprite));
} }
static void
unset_crtc_cursor_renderer_privates (MetaGpu *gpu,
struct gbm_bo *bo)
{
GList *l;
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
{
MetaCrtc *crtc = l->data;
if (bo == crtc->cursor_renderer_private)
crtc->cursor_renderer_private = NULL;
}
}
static void static void
cursor_gpu_state_free (MetaCursorNativeGpuState *cursor_gpu_state) cursor_gpu_state_free (MetaCursorNativeGpuState *cursor_gpu_state)
{ {
int i; int i;
struct gbm_bo *active_bo;
active_bo = get_active_cursor_sprite_gbm_bo (cursor_gpu_state);
if (active_bo)
unset_crtc_cursor_renderer_privates (cursor_gpu_state->gpu, active_bo);
for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++) for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++)
g_clear_pointer (&cursor_gpu_state->bos[i], gbm_bo_destroy); g_clear_pointer (&cursor_gpu_state->bos[i], gbm_bo_destroy);
@ -774,6 +795,7 @@ ensure_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
return cursor_gpu_state; return cursor_gpu_state;
cursor_gpu_state = g_new0 (MetaCursorNativeGpuState, 1); cursor_gpu_state = g_new0 (MetaCursorNativeGpuState, 1);
cursor_gpu_state->gpu = META_GPU (gpu_kms);
g_hash_table_insert (cursor_priv->gpu_states, gpu_kms, cursor_gpu_state); g_hash_table_insert (cursor_priv->gpu_states, gpu_kms, cursor_gpu_state);
return cursor_gpu_state; return cursor_gpu_state;