onscreen/native: Release buffer before destroying EGLSurface

Destroying the EGLSurface frees the underlying container structs. When
we call gbm_surface_release_buffer() with a gbm_surface the EGLSurface
was created from, doing that after the EGLSurface was destroyed results
in attempts to access freed memory. Fix this by releasing any buffer
first, followed by destroying the EGLSurface, and lastly, the
gbm_surface.

This was not a problem prior to CoglOnscreen turning into a GObject, as
in that case, the dispose-chain was not setup correctly, and the
EGLSurface destruction was done in the native backend implementation.

This also changes a g_return_if_fail() to a g_warn_if_fail(), as if we
hit the unexpected case, we still need to call up to the parent dispose
vfunc to not cause critical issues.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1803>
This commit is contained in:
Jonas Ådahl 2021-03-25 16:22:33 +01:00 committed by Marge Bot
parent abbbe8f755
commit 60a998bdbc

View File

@ -2050,8 +2050,6 @@ meta_onscreen_native_dispose (GObject *object)
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
MetaRendererNativeGpuData *renderer_gpu_data;
G_OBJECT_CLASS (meta_onscreen_native_parent_class)->dispose (object);
renderer_gpu_data =
meta_renderer_native_get_gpu_data (renderer_native,
onscreen_native->render_gpu);
@ -2060,11 +2058,9 @@ meta_onscreen_native_dispose (GObject *object)
case META_RENDERER_NATIVE_MODE_GBM:
/* flip state takes a reference on the onscreen so there should
* never be outstanding flips when we reach here. */
g_return_if_fail (onscreen_native->gbm.next_fb == NULL);
g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
free_current_bo (onscreen);
g_clear_pointer (&onscreen_native->gbm.surface, gbm_surface_destroy);
break;
case META_RENDERER_NATIVE_MODE_SURFACELESS:
g_assert_not_reached ();
@ -2089,6 +2085,9 @@ meta_onscreen_native_dispose (GObject *object)
#endif /* HAVE_EGL_DEVICE */
}
G_OBJECT_CLASS (meta_onscreen_native_parent_class)->dispose (object);
g_clear_pointer (&onscreen_native->gbm.surface, gbm_surface_destroy);
g_clear_pointer (&onscreen_native->secondary_gpu_state,
secondary_gpu_state_free);
}