1
0
Fork 0

onscreen/native: Return GErrors from secondary GPU updates

And return early from `swap_buffers_with_damage` if the error would have
led to flipping a NULL buffer.

This is also the perfect time to remove the `egl_context_changed` parameter
and move `_cogl_winsys_egl_ensure_current` closer to the code that actually
needs it.

Related: https://bugs.launchpad.net/bugs/2069565
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3817>
This commit is contained in:
Daniel van Vugt 2024-06-17 17:44:15 +08:00 committed by Marge Bot
parent 45a97a5e3f
commit e389178180

View file

@ -809,22 +809,24 @@ import_shared_framebuffer (CoglOnscreen *onscreen,
} }
static MetaDrmBuffer * static MetaDrmBuffer *
copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state, MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
MetaRendererNativeGpuData *renderer_gpu_data, MetaRendererNativeGpuData *renderer_gpu_data,
gboolean *egl_context_changed, MetaDrmBuffer *primary_gpu_fb,
MetaDrmBuffer *primary_gpu_fb) GError **error)
{ {
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
MetaGles3 *gles3 = meta_renderer_native_get_gles3 (renderer_native); MetaGles3 *gles3 = meta_renderer_native_get_gles3 (renderer_native);
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
MetaRenderDevice *render_device; MetaRenderDevice *render_device;
EGLDisplay egl_display; EGLDisplay egl_display;
GError *error = NULL;
gboolean use_modifiers; gboolean use_modifiers;
MetaDeviceFile *device_file; MetaDeviceFile *device_file;
MetaDrmBufferFlags flags; MetaDrmBufferFlags flags;
MetaDrmBufferGbm *buffer_gbm; MetaDrmBufferGbm *buffer_gbm = NULL;
struct gbm_bo *bo; struct gbm_bo *bo;
COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu, COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu,
@ -841,16 +843,12 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
secondary_gpu_state->egl_surface, secondary_gpu_state->egl_surface,
secondary_gpu_state->egl_surface, secondary_gpu_state->egl_surface,
renderer_gpu_data->secondary.egl_context, renderer_gpu_data->secondary.egl_context,
&error)) error))
{ {
g_warning ("Failed to make current: %s", error->message); g_prefix_error (error, "Failed to make current: ");
g_error_free (error); goto done;
return NULL;
} }
*egl_context_changed = TRUE;
buffer_gbm = META_DRM_BUFFER_GBM (primary_gpu_fb); buffer_gbm = META_DRM_BUFFER_GBM (primary_gpu_fb);
bo = meta_drm_buffer_gbm_get_bo (buffer_gbm); bo = meta_drm_buffer_gbm_get_bo (buffer_gbm);
if (!meta_renderer_native_gles3_blit_shared_bo (egl, if (!meta_renderer_native_gles3_blit_shared_bo (egl,
@ -859,21 +857,19 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
renderer_gpu_data->secondary.egl_context, renderer_gpu_data->secondary.egl_context,
secondary_gpu_state->egl_surface, secondary_gpu_state->egl_surface,
bo, bo,
&error)) error))
{ {
g_warning ("Failed to blit shared framebuffer: %s", error->message); g_prefix_error (error, "Failed to blit shared framebuffer: ");
g_error_free (error); goto done;
return NULL;
} }
if (!meta_egl_swap_buffers (egl, if (!meta_egl_swap_buffers (egl,
egl_display, egl_display,
secondary_gpu_state->egl_surface, secondary_gpu_state->egl_surface,
&error)) error))
{ {
g_warning ("Failed to swap buffers: %s", error->message); g_prefix_error (error, "Failed to swap buffers: ");
g_error_free (error); goto done;
return NULL;
} }
use_modifiers = meta_renderer_native_use_modifiers (renderer_native); use_modifiers = meta_renderer_native_use_modifiers (renderer_native);
@ -887,13 +883,11 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
meta_drm_buffer_gbm_new_lock_front (device_file, meta_drm_buffer_gbm_new_lock_front (device_file,
secondary_gpu_state->gbm.surface, secondary_gpu_state->gbm.surface,
flags, flags,
&error); error);
if (!buffer_gbm) if (!buffer_gbm)
{ {
g_warning ("meta_drm_buffer_gbm_new_lock_front failed: %s", g_prefix_error (error, "meta_drm_buffer_gbm_new_lock_front failed: ");
error->message); goto done;
g_error_free (error);
return NULL;
} }
g_object_set_qdata_full (G_OBJECT (buffer_gbm), g_object_set_qdata_full (G_OBJECT (buffer_gbm),
@ -901,7 +895,10 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
g_object_ref (primary_gpu_fb), g_object_ref (primary_gpu_fb),
g_object_unref); g_object_unref);
return META_DRM_BUFFER (buffer_gbm); done:
_cogl_winsys_egl_ensure_current (cogl_display);
return buffer_gbm ? META_DRM_BUFFER (buffer_gbm) : NULL;
} }
static MetaDrmBufferDumb * static MetaDrmBufferDumb *
@ -1154,10 +1151,10 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
} }
static MetaDrmBuffer * static MetaDrmBuffer *
acquire_front_buffer (CoglOnscreen *onscreen, acquire_front_buffer (CoglOnscreen *onscreen,
gboolean *egl_context_changed, MetaDrmBuffer *primary_gpu_fb,
MetaDrmBuffer *primary_gpu_fb, MetaDrmBuffer *secondary_gpu_fb,
MetaDrmBuffer *secondary_gpu_fb) GError **error)
{ {
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaRendererNative *renderer_native = onscreen_native->renderer_native; MetaRendererNative *renderer_native = onscreen_native->renderer_native;
@ -1195,8 +1192,8 @@ acquire_front_buffer (CoglOnscreen *onscreen,
return copy_shared_framebuffer_gpu (onscreen, return copy_shared_framebuffer_gpu (onscreen,
secondary_gpu_state, secondary_gpu_state,
renderer_gpu_data, renderer_gpu_data,
egl_context_changed, primary_gpu_fb,
primary_gpu_fb); error);
} }
g_assert_not_reached (); g_assert_not_reached ();
@ -1262,7 +1259,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
CoglRenderer *cogl_renderer = cogl_context->display->renderer; CoglRenderer *cogl_renderer = cogl_context->display->renderer;
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
@ -1280,7 +1276,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
MetaKmsUpdate *kms_update; MetaKmsUpdate *kms_update;
CoglOnscreenClass *parent_class; CoglOnscreenClass *parent_class;
gboolean create_timestamp_query = TRUE; gboolean create_timestamp_query = TRUE;
gboolean egl_context_changed = FALSE;
MetaPowerSave power_save_mode; MetaPowerSave power_save_mode;
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
MetaDrmBufferFlags buffer_flags; MetaDrmBufferFlags buffer_flags;
@ -1349,9 +1344,15 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
primary_gpu_fb = META_DRM_BUFFER (g_steal_pointer (&buffer_gbm)); primary_gpu_fb = META_DRM_BUFFER (g_steal_pointer (&buffer_gbm));
buffer = acquire_front_buffer (onscreen, buffer = acquire_front_buffer (onscreen,
&egl_context_changed,
primary_gpu_fb, primary_gpu_fb,
secondary_gpu_fb); secondary_gpu_fb,
&error);
if (buffer == NULL)
{
g_warning ("Failed to acquire front buffer: %s", error->message);
goto swap_failed;
}
meta_frame_native_set_buffer (frame_native, buffer); meta_frame_native_set_buffer (frame_native, buffer);
if (!meta_drm_buffer_ensure_fb_id (buffer, &error)) if (!meta_drm_buffer_ensure_fb_id (buffer, &error))
@ -1373,15 +1374,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
g_warn_if_fail (!onscreen_native->next_frame); g_warn_if_fail (!onscreen_native->next_frame);
onscreen_native->next_frame = clutter_frame_ref (frame); onscreen_native->next_frame = clutter_frame_ref (frame);
/*
* If we changed EGL context, cogl will have the wrong idea about what is
* current, making it fail to set it when it needs to. Avoid that by making
* EGL_NO_CONTEXT current now, making cogl eventually set the correct
* context.
*/
if (egl_context_changed)
_cogl_winsys_egl_ensure_current (cogl_display);
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc)); kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
kms_device = meta_kms_crtc_get_device (kms_crtc); kms_device = meta_kms_crtc_get_device (kms_crtc);