renderer/native: Also wrap flip closures for EGLStreams

When using the EGLStream backend, the MetaRendererNative passed a
GClosure to KMS when using EGLStreams, but KMS flip callback event
handler in meta-gpu-kms.c expected a closure wrapped in a closure
container, meaning it'd instead crash when using EGLStreams. Make the
flip handler get what it expects also when using EGLStreams by wrapping
the flip closure in the container before handing it over to EGL.

https://bugzilla.gnome.org/show_bug.cgi?id=790316
(cherry picked from commit 8ee14a7cb7)
This commit is contained in:
Jonas Ådahl 2017-11-14 16:08:52 +08:00 committed by Ray Strode
parent 8eccb68687
commit 988f6e72fe
3 changed files with 44 additions and 14 deletions

View File

@ -47,6 +47,12 @@ typedef struct _MetaKmsSource
MetaGpuKms *gpu_kms; MetaGpuKms *gpu_kms;
} MetaKmsSource; } MetaKmsSource;
typedef struct _MetaGpuKmsFlipClosureContainer
{
GClosure *flip_closure;
MetaGpuKms *gpu_kms;
} MetaGpuKmsFlipClosureContainer;
struct _MetaGpuKms struct _MetaGpuKms
{ {
MetaGpu parent; MetaGpu parent;
@ -209,11 +215,26 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
return TRUE; return TRUE;
} }
typedef struct _GpuClosureContainer MetaGpuKmsFlipClosureContainer *
meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
GClosure *flip_closure)
{ {
GClosure *flip_closure; MetaGpuKmsFlipClosureContainer *closure_container;
MetaGpuKms *gpu_kms;
} GpuClosureContainer; closure_container = g_new0 (MetaGpuKmsFlipClosureContainer, 1);
*closure_container = (MetaGpuKmsFlipClosureContainer) {
.flip_closure = flip_closure,
.gpu_kms = gpu_kms
};
return closure_container;
}
void
meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container)
{
g_free (closure_container);
}
gboolean gboolean
meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms, meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
@ -239,14 +260,11 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
if (!gpu_kms->page_flips_not_supported) if (!gpu_kms->page_flips_not_supported)
{ {
GpuClosureContainer *closure_container; MetaGpuKmsFlipClosureContainer *closure_container;
int kms_fd = meta_gpu_kms_get_fd (gpu_kms); int kms_fd = meta_gpu_kms_get_fd (gpu_kms);
closure_container = g_new0 (GpuClosureContainer, 1); closure_container = meta_gpu_kms_wrap_flip_closure (gpu_kms,
*closure_container = (GpuClosureContainer) { flip_closure);
.flip_closure = flip_closure,
.gpu_kms = gpu_kms
};
ret = drmModePageFlip (kms_fd, ret = drmModePageFlip (kms_fd,
crtc->crtc_id, crtc->crtc_id,
@ -255,7 +273,7 @@ meta_gpu_kms_flip_crtc (MetaGpuKms *gpu_kms,
closure_container); closure_container);
if (ret != 0 && ret != -EACCES) if (ret != 0 && ret != -EACCES)
{ {
g_free (closure_container); meta_gpu_kms_flip_closure_container_free (closure_container);
g_warning ("Failed to flip: %s", strerror (-ret)); g_warning ("Failed to flip: %s", strerror (-ret));
gpu_kms->page_flips_not_supported = TRUE; gpu_kms->page_flips_not_supported = TRUE;
} }
@ -286,12 +304,12 @@ page_flip_handler (int fd,
unsigned int usec, unsigned int usec,
void *user_data) void *user_data)
{ {
GpuClosureContainer *closure_container = user_data; MetaGpuKmsFlipClosureContainer *closure_container = user_data;
GClosure *flip_closure = closure_container->flip_closure; GClosure *flip_closure = closure_container->flip_closure;
MetaGpuKms *gpu_kms = closure_container->gpu_kms; MetaGpuKms *gpu_kms = closure_container->gpu_kms;
invoke_flip_closure (flip_closure, gpu_kms); invoke_flip_closure (flip_closure, gpu_kms);
g_free (closure_container); meta_gpu_kms_flip_closure_container_free (closure_container);
} }
gboolean gboolean

View File

@ -40,6 +40,8 @@ GQuark meta_gpu_kms_error_quark (void);
#define META_TYPE_GPU_KMS (meta_gpu_kms_get_type ()) #define META_TYPE_GPU_KMS (meta_gpu_kms_get_type ())
G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu) G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu)
typedef struct _MetaGpuKmsFlipClosureContainer MetaGpuKmsFlipClosureContainer;
typedef struct _MetaKmsResources typedef struct _MetaKmsResources
{ {
drmModeRes *resources; drmModeRes *resources;
@ -94,4 +96,9 @@ gboolean meta_drm_mode_equal (const drmModeModeInfo *one,
float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *mode); float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *mode);
MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
GClosure *flip_closure);
void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container);
#endif /* META_GPU_KMS_H */ #endif /* META_GPU_KMS_H */

View File

@ -1286,6 +1286,7 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
MetaRendererNativeGpuData *renderer_gpu_data; MetaRendererNativeGpuData *renderer_gpu_data;
EGLDisplay *egl_display; EGLDisplay *egl_display;
MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
MetaGpuKmsFlipClosureContainer *closure_container;
EGLAttrib *acquire_attribs; EGLAttrib *acquire_attribs;
GError *error = NULL; GError *error = NULL;
@ -1295,9 +1296,12 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
if (renderer_gpu_data->egl.no_egl_output_drm_flip_event) if (renderer_gpu_data->egl.no_egl_output_drm_flip_event)
return FALSE; return FALSE;
closure_container =
meta_gpu_kms_wrap_flip_closure (onscreen_native->render_gpu, flip_closure);
acquire_attribs = (EGLAttrib[]) { acquire_attribs = (EGLAttrib[]) {
EGL_DRM_FLIP_EVENT_DATA_NV, EGL_DRM_FLIP_EVENT_DATA_NV,
(EGLAttrib) flip_closure, (EGLAttrib) closure_container,
EGL_NONE EGL_NONE
}; };
@ -1316,6 +1320,7 @@ flip_egl_stream (MetaOnscreenNative *onscreen_native,
renderer_gpu_data->egl.no_egl_output_drm_flip_event = TRUE; renderer_gpu_data->egl.no_egl_output_drm_flip_event = TRUE;
} }
g_error_free (error); g_error_free (error);
meta_gpu_kms_flip_closure_container_free (closure_container);
return FALSE; return FALSE;
} }