egl/x11: implement ANGLE_sync_control_rate
authorYonggang Luo <luoyonggang@gmail.com>
Sat, 30 Jul 2022 09:59:33 +0000 (17:59 +0800)
committerMarge Bot <emma+marge@anholt.net>
Tue, 9 Aug 2022 21:02:50 +0000 (21:02 +0000)
Implement EGL_ANGLE_sync_control_rate for running Chromium Linux on Wayland with EGL backend.

Chromium works with this patch using(with videos playing smoothly):
/usr/bin/google-chrome-stable --use-gl=egl --enable-features=VaapiVideoDecoder --ignore-gpu-blocklist

Closes #2930

Signed-off-by: KJ Liew <liewkj@yahoo.com>
Signed-off-by: Térence Clastres <t.clastres@gmail.com>
Signed-off-by: Satadru Pramanik <satadru@gmail.com>
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
Acked-by: Eric Engestrom <eric@igalia.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17815>

meson.build
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h
src/egl/drivers/dri2/platform_x11.c
src/egl/drivers/dri2/platform_x11.h
src/egl/drivers/dri2/platform_x11_dri3.c
src/egl/meson.build

index 7c1a3a5..048020e 100644 (file)
@@ -2082,6 +2082,7 @@ if with_platform_x11
     dep_x11 = dependency('x11')
     dep_xext = dependency('xext')
     dep_xcb = dependency('xcb')
+    dep_xcb_xrandr = dependency('xcb-randr')
   elif with_glx == 'dri'
     dep_x11 = dependency('x11')
     dep_xext = dependency('xext')
index 79e1cbe..1b08a46 100644 (file)
@@ -2387,6 +2387,16 @@ dri2_get_sync_values_chromium(_EGLDisplay *disp, _EGLSurface *surf,
    return dri2_dpy->vtbl->get_sync_values(disp, surf, ust, msc, sbc);
 }
 
+static EGLBoolean
+dri2_get_msc_rate_angle(_EGLDisplay *disp, _EGLSurface *surf,
+                        EGLint *numerator, EGLint *denominator)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   if (!dri2_dpy->vtbl->get_msc_rate)
+      return EGL_FALSE;
+   return dri2_dpy->vtbl->get_msc_rate(disp, surf, numerator, denominator);
+}
+
 /**
  * Set the error code after a call to
  * dri2_egl_image::dri_image::createImageFromTexture.
@@ -3741,6 +3751,7 @@ const _EGLDriver _eglDriver = {
    .QueryWaylandBufferWL = dri2_query_wayland_buffer_wl,
 #endif
    .GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium,
+   .GetMscRateANGLE = dri2_get_msc_rate_angle,
    .CreateSyncKHR = dri2_create_sync,
    .ClientWaitSyncKHR = dri2_client_wait_sync,
    .SignalSyncKHR = dri2_signal_sync,
index 056bc2e..a3d848e 100644 (file)
@@ -34,6 +34,7 @@
 #ifdef HAVE_X11_PLATFORM
 #include <xcb/xcb.h>
 #include <xcb/dri2.h>
+#include <xcb/randr.h>
 #include <xcb/xfixes.h>
 #include <X11/Xlib-xcb.h>
 
@@ -160,6 +161,10 @@ struct dri2_egl_display_vtbl {
                                  EGLuint64KHR *ust, EGLuint64KHR *msc,
                                  EGLuint64KHR *sbc);
 
+   /* optional */
+   EGLBoolean (*get_msc_rate)(_EGLDisplay *display, _EGLSurface *surface,
+                              EGLint *numerator, EGLint *denominator);
+
    /* mandatory */
    __DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf);
 
index 4ef9a2e..b6fbd86 100644 (file)
@@ -1191,6 +1191,27 @@ dri2_x11_get_sync_values(_EGLDisplay *display, _EGLSurface *surface,
    return EGL_TRUE;
 }
 
+EGLBoolean
+dri2_x11_get_msc_rate(_EGLDisplay *display, _EGLSurface *surface,
+                      EGLint *numerator, EGLint *denominator)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(display);
+   xcb_randr_get_screen_info_cookie_t cookie;
+   xcb_randr_get_screen_info_reply_t *reply;
+
+   cookie = xcb_randr_get_screen_info_unchecked(dri2_dpy->conn, dri2_dpy->screen->root);
+   reply = xcb_randr_get_screen_info_reply(dri2_dpy->conn, cookie, NULL);
+
+   if (!reply)
+      return _eglError(EGL_BAD_ACCESS, "eglGetMscRateANGLE");
+
+   *numerator = reply->rate;
+   *denominator = 1;
+   free(reply);
+
+   return EGL_TRUE;
+}
+
 static EGLBoolean
 dri2_kopper_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval)
 {
@@ -1253,6 +1274,7 @@ static const struct dri2_egl_display_vtbl dri2_x11_swrast_display_vtbl = {
    .copy_buffers = dri2_x11_copy_buffers,
    /* XXX: should really implement this since X11 has pixmaps */
    .query_surface = dri2_query_surface,
+   .get_msc_rate = dri2_x11_get_msc_rate,
    .get_dri_drawable = dri2_surface_get_dri_drawable,
 };
 
@@ -1271,6 +1293,7 @@ static const struct dri2_egl_display_vtbl dri2_x11_kopper_display_vtbl = {
    .query_buffer_age = dri2_kopper_query_buffer_age,
    /* XXX: should really implement this since X11 has pixmaps */
    .query_surface = dri2_query_surface,
+   .get_msc_rate = dri2_x11_get_msc_rate,
    .get_dri_drawable = dri2_surface_get_dri_drawable,
 };
 
@@ -1288,6 +1311,7 @@ static const struct dri2_egl_display_vtbl dri2_x11_display_vtbl = {
    .copy_buffers = dri2_x11_copy_buffers,
    .query_surface = dri2_query_surface,
    .get_sync_values = dri2_x11_get_sync_values,
+   .get_msc_rate = dri2_x11_get_msc_rate,
    .get_dri_drawable = dri2_surface_get_dri_drawable,
 };
 
@@ -1454,6 +1478,7 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp)
    dri2_setup_screen(disp);
 
    if (disp->Options.Zink) {
+      /* kopper */
 #ifdef HAVE_WAYLAND_PLATFORM
       dri2_dpy->device_name = strdup("zink");
 #endif
@@ -1463,10 +1488,14 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp)
          disp->Extensions.KHR_image_pixmap = EGL_TRUE;
       disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
       disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
+      disp->Extensions.ANGLE_sync_control_rate = EGL_TRUE;
       disp->Extensions.EXT_buffer_age = EGL_TRUE;
       disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
 
       //dri2_set_WL_bind_wayland_display(disp);
+   } else {
+      /* swrast */
+      disp->Extensions.ANGLE_sync_control_rate = EGL_TRUE;
    }
 
    if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true))
@@ -1544,6 +1573,7 @@ dri2_initialize_x11_dri3(_EGLDisplay *disp)
       disp->Extensions.KHR_image_pixmap = EGL_TRUE;
    disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
    disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
+   disp->Extensions.ANGLE_sync_control_rate = EGL_TRUE;
    disp->Extensions.EXT_buffer_age = EGL_TRUE;
    disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
 
@@ -1656,6 +1686,7 @@ dri2_initialize_x11_dri2(_EGLDisplay *disp)
    disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
    disp->Extensions.NV_post_sub_buffer = EGL_TRUE;
    disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
+   disp->Extensions.ANGLE_sync_control_rate = EGL_TRUE;
 
    dri2_set_WL_bind_wayland_display(disp);
 
index b54781d..1882922 100644 (file)
@@ -12,4 +12,8 @@
 uint32_t
 dri2_format_for_depth(struct dri2_egl_display *dri2_dpy, uint32_t depth);
 
+EGLBoolean
+dri2_x11_get_msc_rate(_EGLDisplay *display, _EGLSurface *surface,
+                      EGLint *numerator, EGLint *denominator);
+
 #endif
index 3d7c2ae..c529f42 100644 (file)
@@ -527,6 +527,7 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
    .query_buffer_age = dri3_query_buffer_age,
    .query_surface = dri3_query_surface,
    .get_sync_values = dri3_get_sync_values,
+   .get_msc_rate = dri2_x11_get_msc_rate,
    .get_dri_drawable = dri3_get_dri_drawable,
    .close_screen_notify = dri3_close_screen_notify,
 };
index be55ac7..6420f85 100644 (file)
@@ -106,7 +106,7 @@ if with_dri2
       files_egl += files('drivers/dri2/platform_x11_dri3.c')
       link_for_egl += libloader_dri3_helper
     endif
-    deps_for_egl += [dep_x11_xcb, dep_xcb_dri2, dep_xcb_xfixes]
+    deps_for_egl += [dep_x11_xcb, dep_xcb_dri2, dep_xcb_xrandr, dep_xcb_xfixes]
   endif
   if with_gbm and not with_platform_android
     files_egl += files('drivers/dri2/platform_drm.c')