From 10a1b9808253dc67e19db2a0c4c360788b9e668e Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 30 Jun 2019 00:39:23 +0200 Subject: vo_gpu: x11egl: support Mesa OML sync extension Mesa supports the EGL_CHROMIUM_sync_control extension, and it's available out of the box with AMD drivers. In practice, this is exactly the same as GLX_OML_sync_control, but for EGL. The extension specification is separate from the GLX one though, and buried somewhere in the Chromium code. This appears to work, although I don't know if it really works. In theory, this could be useful for other EGL targets. Support code for it could have been added to egl_helpers.c to avoid some minor duplicated glue code if another EGL target were to provide this extension. I didn't bother with that. ANGLE on Windows can't support it, because the extension spec. explicitly requires POSIX timers. ANGLE on Linux/OSX is actively harmful for mpv and hopefully won't ever use it. Wayland uses EGL, but has its own fancy presentation feedback stuff (and besides, I don't think basic video player functionality works on Wayland at all). context_drm_egl maybe? But I think DRM has its own stuff. --- video/out/opengl/context_x11egl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'video/out') diff --git a/video/out/opengl/context_x11egl.c b/video/out/opengl/context_x11egl.c index 32530cc11d..b1aa0690d7 100644 --- a/video/out/opengl/context_x11egl.c +++ b/video/out/opengl/context_x11egl.c @@ -30,12 +30,18 @@ #include "video/out/x11_common.h" #include "context.h" #include "egl_helpers.h" +#include "oml_sync.h" +#include "utils.h" struct priv { GL gl; EGLDisplay egl_display; EGLContext egl_context; EGLSurface egl_surface; + + EGLBoolean (*GetSyncValues)(EGLDisplay, EGLSurface, + int64_t*, int64_t*, int64_t*); + struct oml_sync sync; }; static void mpegl_uninit(struct ra_ctx *ctx) @@ -79,6 +85,19 @@ static void mpegl_swap_buffers(struct ra_ctx *ctx) { struct priv *p = ctx->priv; eglSwapBuffers(p->egl_display, p->egl_surface); + + int64_t ust, msc, sbc; + if (!p->GetSyncValues || !p->GetSyncValues(p->egl_display, p->egl_surface, + &ust, &msc, &sbc)) + ust = msc = sbc = -1; + + oml_sync_swap(&p->sync, ust, msc, sbc); +} + +static void mpegl_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info) +{ + struct priv *p = ctx->priv; + oml_sync_get_info(&p->sync, info); } static bool mpegl_init(struct ra_ctx *ctx) @@ -142,11 +161,16 @@ static bool mpegl_init(struct ra_ctx *ctx) struct ra_gl_ctx_params params = { .swap_buffers = mpegl_swap_buffers, + .get_vsync = mpegl_get_vsync, }; if (!ra_gl_ctx_init(ctx, &p->gl, params)) goto uninit; + const char *exts = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS); + if (gl_check_extension(exts, "EGL_CHROMIUM_sync_control")) + p->GetSyncValues = (void *)eglGetProcAddress("eglGetSyncValuesCHROMIUM"); + ra_add_native_resource(ctx->ra, "x11", vo->x11->display); return true; -- cgit v1.2.3