diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 82601ecf2c4..11c8d9db32f 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -799,7 +799,7 @@ struct __DRIuseInvalidateExtensionRec { * returns a reliable value. The X server requires v1 and uses v2. */ #define __DRI_CORE "DRI_Core" -#define __DRI_CORE_VERSION 2 +#define __DRI_CORE_VERSION 3 struct __DRIcoreExtensionRec { __DRIextension base; @@ -858,6 +858,8 @@ struct __DRIcoreExtensionRec { /* Used by the X server. */ int (*unbindContext)(__DRIcontext *ctx); + + void (*swapBuffersWithDamage)(__DRIdrawable *drawable, int nrects, const int *rects); }; /** diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 4e8b1348d9a..065d0dd1252 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -2504,7 +2504,8 @@ dri2_wl_swrast_put_image(__DRIdrawable *draw, int op, int x, int y, int w, } static EGLBoolean -dri2_wl_swrast_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) +dri2_wl_swrast_swap_buffers_with_damage(_EGLDisplay *disp, _EGLSurface *draw, + const EGLint *rects, EGLint n_rects) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); @@ -2512,7 +2513,10 @@ dri2_wl_swrast_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) if (!dri2_surf->wl_win) return _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_swap_buffers"); - dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); + if (n_rects) + dri2_dpy->core->swapBuffersWithDamage(dri2_surf->dri_drawable, n_rects, rects); + else + dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable); if (disp->Options.Zink) { dri2_surf->current = dri2_surf->back; dri2_surf->back = NULL; @@ -2520,6 +2524,13 @@ dri2_wl_swrast_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) return EGL_TRUE; } +static EGLBoolean +dri2_wl_swrast_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) +{ + dri2_wl_swrast_swap_buffers_with_damage(disp, draw, NULL, 0); + return EGL_TRUE; +} + static EGLint dri2_wl_swrast_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) { @@ -2585,6 +2596,7 @@ static const struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = { .destroy_surface = dri2_wl_destroy_surface, .create_image = dri2_create_image_khr, .swap_buffers = dri2_wl_swrast_swap_buffers, + .swap_buffers_with_damage = dri2_wl_swrast_swap_buffers_with_damage, .get_dri_drawable = dri2_surface_get_dri_drawable, .query_buffer_age = dri2_wl_swrast_query_buffer_age, }; diff --git a/src/gallium/frontends/dri/dri_drawable.h b/src/gallium/frontends/dri/dri_drawable.h index fc767f6bdb6..cac2602fdb6 100644 --- a/src/gallium/frontends/dri/dri_drawable.h +++ b/src/gallium/frontends/dri/dri_drawable.h @@ -112,6 +112,7 @@ struct dri_drawable struct dri_drawable *drawable); void (*swap_buffers)(struct dri_drawable *drawable); + void (*swap_buffers_with_damage)(struct dri_drawable *drawable, int nrects, const int *rects); }; /* Typecast the opaque pointer to our own type. */ diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c index 62debd6e1c2..6b808665b28 100644 --- a/src/gallium/frontends/dri/dri_util.c +++ b/src/gallium/frontends/dri/dri_util.c @@ -847,6 +847,16 @@ driGetAPIMask(__DRIscreen *screen) * DRI2 implements this inside the loader with only flushes handled by the * driver. */ +static void +driSwapBuffersWithDamage(__DRIdrawable *pdp, int nrects, const int *rects) +{ + struct dri_drawable *drawable = dri_drawable(pdp); + + assert(drawable->screen->swrast_loader); + + drawable->swap_buffers_with_damage(drawable, nrects, rects); +} + static void driSwapBuffers(__DRIdrawable *pdp) { @@ -876,6 +886,7 @@ const __DRIcoreExtension driCoreExtension = { .createNewDrawable = NULL, .destroyDrawable = driDestroyDrawable, .swapBuffers = driSwapBuffers, /* swrast */ + .swapBuffersWithDamage = driSwapBuffersWithDamage, /* swrast */ .createNewContext = driCreateNewContext, /* swrast */ .copyContext = driCopyContext, .destroyContext = driDestroyContext, diff --git a/src/gallium/frontends/dri/drisw.c b/src/gallium/frontends/dri/drisw.c index 1297744f720..999e5416ac3 100644 --- a/src/gallium/frontends/dri/drisw.c +++ b/src/gallium/frontends/dri/drisw.c @@ -219,7 +219,7 @@ drisw_copy_to_front(struct pipe_context *pipe, */ static void -drisw_swap_buffers(struct dri_drawable *drawable) +drisw_swap_buffers_with_damage(struct dri_drawable *drawable, int nrects, const int *rects) { struct dri_context *ctx = dri_get_current(); struct dri_screen *screen = drawable->screen; @@ -263,6 +263,12 @@ drisw_swap_buffers(struct dri_drawable *drawable) } } +static void +drisw_swap_buffers(struct dri_drawable *drawable) +{ + drisw_swap_buffers_with_damage(drawable, 0, NULL); +} + static void drisw_copy_sub_buffer(struct dri_drawable *drawable, int x, int y, int w, int h) @@ -536,6 +542,7 @@ drisw_create_drawable(struct dri_screen *screen, const struct gl_config * visual drawable->flush_frontbuffer = drisw_flush_frontbuffer; drawable->update_tex_buffer = drisw_update_tex_buffer; drawable->swap_buffers = drisw_swap_buffers; + drawable->swap_buffers_with_damage = drisw_swap_buffers_with_damage; return drawable; }