egl/x11_dri3: implement EGL_KHR_swap_buffers_with_damage
authorEric Engestrom <eric@engestrom.ch>
Fri, 22 May 2020 23:45:42 +0000 (01:45 +0200)
committerMarge Bot <eric+marge@anholt.net>
Wed, 19 Aug 2020 12:47:58 +0000 (12:47 +0000)
Passes all of `dEQP-EGL.functional.swap_buffers_with_damage.*`:

    Passed:        36/54 (66.7%)
    Failed:        0/54 (0.0%)
    Not supported: 18/54 (33.3%)
    Warnings:      0/54 (0.0%)
    Waived:        0/54 (0.0%)

The "not supported" ones are the `preserve_buffer_*` tests, which is not
supported on X11/DRI3.

Cc: 20.2 <mesa-stable>
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3030
Signed-off-by: Eric Engestrom <eric@engestrom.ch>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6132>

docs/relnotes/new_features.txt
src/egl/drivers/dri2/platform_x11.c
src/egl/drivers/dri2/platform_x11_dri3.c
src/glx/dri3_glx.c
src/loader/loader_dri3_helper.c
src/loader/loader_dri3_helper.h
src/loader/meson.build

index 868da1dcf202be3bcc6dc357d3f02d8ab9feaf68..ef48b8ab45db9400fe1c728db515b1b9c5dccea6 100644 (file)
@@ -1,2 +1,3 @@
 GL 4.5 on llvmpipe
 GL_NV_half_float
+EGL_KHR_swap_buffers_with_damage on X11 (DRI3)
index 605035581d137e695d64e855e11495786d6135cb..96a8a88d725da7a58b11cc482c489968be3ad433 100644 (file)
@@ -1386,6 +1386,7 @@ dri2_initialize_x11_dri3(_EGLDisplay *disp)
    disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
    disp->Extensions.CHROMIUM_sync_control = 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);
 
index 5c69a3b981e4a0f50ad9c82fccaddc9ce5cb3fd8..40d203c9ec1b906b3ff0a7af69ff8cad0466fc82 100644 (file)
@@ -413,15 +413,23 @@ const __DRIimageLoaderExtension dri3_image_loader_extension = {
 };
 
 static EGLBoolean
-dri3_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
+dri3_swap_buffers_with_damage(_EGLDisplay *disp, _EGLSurface *draw,
+                              const EGLint *rects, EGLint n_rects)
 {
    struct dri3_egl_surface *dri3_surf = dri3_egl_surface(draw);
 
    return loader_dri3_swap_buffers_msc(&dri3_surf->loader_drawable,
                                        0, 0, 0, 0,
+                                       rects, n_rects,
                                        draw->SwapBehavior == EGL_BUFFER_PRESERVED) != -1;
 }
 
+static EGLBoolean
+dri3_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
+{
+   return dri3_swap_buffers_with_damage(disp, draw, NULL, 0);
+}
+
 static EGLBoolean
 dri3_copy_buffers(_EGLDisplay *disp, _EGLSurface *surf, void *native_pixmap_target)
 {
@@ -488,6 +496,7 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
    .create_image = dri3_create_image_khr,
    .swap_interval = dri3_set_swap_interval,
    .swap_buffers = dri3_swap_buffers,
+   .swap_buffers_with_damage = dri3_swap_buffers_with_damage,
    .copy_buffers = dri3_copy_buffers,
    .query_buffer_age = dri3_query_buffer_age,
    .query_surface = dri3_query_surface,
index a0929316778b9cf51555053c1ec89533d5ff2cad..fc8e8157618ff258be45a600604b7d08368bd30a 100644 (file)
@@ -593,7 +593,7 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
 
    return loader_dri3_swap_buffers_msc(&priv->loader_drawable,
                                        target_msc, divisor, remainder,
-                                       flags, false);
+                                       flags, NULL, 0, false);
 }
 
 static int
index 425faba8f640a8ac770895a92262dcc695348edd..cba3dfe2695d121a0301391f0e3baf49a1e6da62 100644 (file)
@@ -30,6 +30,7 @@
 #include <xcb/xcb.h>
 #include <xcb/dri3.h>
 #include <xcb/present.h>
+#include <xcb/xfixes.h>
 
 #include <X11/Xlib-xcb.h>
 
@@ -908,6 +909,7 @@ int64_t
 loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
                              int64_t target_msc, int64_t divisor,
                              int64_t remainder, unsigned flush_flags,
+                             const int *rects, int n_rects,
                              bool force_copy)
 {
    struct loader_dri3_buffer *back;
@@ -1006,12 +1008,29 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
 #endif
       back->busy = 1;
       back->last_swap = draw->send_sbc;
+
+      xcb_xfixes_region_t region = 0;
+      xcb_rectangle_t xcb_rects[64];
+
+      if (n_rects > 0 && n_rects <= ARRAY_SIZE(xcb_rects)) {
+         for (int i = 0; i < n_rects; i++) {
+            const int *rect = &rects[i * 4];
+            xcb_rects[i].x = rect[0];
+            xcb_rects[i].y = draw->height - rect[1] - rect[3];
+            xcb_rects[i].width = rect[2];
+            xcb_rects[i].height = rect[3];
+         }
+
+         region = xcb_generate_id(draw->conn);
+         xcb_xfixes_create_region(draw->conn, region, n_rects, xcb_rects);
+      }
+
       xcb_present_pixmap(draw->conn,
                          draw->drawable,
                          back->pixmap,
                          (uint32_t) draw->send_sbc,
                          0,                                    /* valid */
-                         0,                                    /* update */
+                         region,                               /* update */
                          0,                                    /* x_off */
                          0,                                    /* y_off */
                          None,                                 /* target_crtc */
@@ -1023,6 +1042,9 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
                          remainder, 0, NULL);
       ret = (int64_t) draw->send_sbc;
 
+      if (region)
+         xcb_xfixes_destroy_region(draw->conn, region);
+
       /* Schedule a server-side back-preserving blit if necessary.
        * This happens iff all conditions below are satisfied:
        * a) We have a fake front,
index c314e4c5a9dee1a4dec32992c1c459f0b180e045..af5fdbc4193da2caa35117fc5377c7562fab001e 100644 (file)
@@ -205,6 +205,7 @@ int64_t
 loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
                              int64_t target_msc, int64_t divisor,
                              int64_t remainder, unsigned flush_flags,
+                             const int *rects, int n_rects,
                              bool force_copy);
 
 int
index ec8d668813b1edf28f8c88cbe6b1bfe3c9eb51c9..34a43e33f095ebf46ebd59613f683d7fb23c5ad6 100644 (file)
@@ -28,6 +28,7 @@ if with_platform_x11 and with_dri3
     include_directories : [inc_include, inc_src],
     dependencies : [
       dep_libdrm, dep_xcb_dri3, dep_xcb_present, dep_xcb_sync, dep_xshmfence,
+      dep_xcb_xfixes,
     ],
     build_by_default : false,
   )