egl: Inform the client API when ancillary buffers may become undefined.
authorEric Anholt <eric@anholt.net>
Sun, 21 Dec 2014 19:51:33 +0000 (11:51 -0800)
committerEric Anholt <eric@anholt.net>
Tue, 6 Jan 2015 23:40:40 +0000 (15:40 -0800)
This is part of the EGL spec, and is useful for a tiled renderer to avoid
the memory bandwidth cost of storing the depth/stencil buffers.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
include/GL/internal/dri_interface.h
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h
src/egl/drivers/dri2/platform_android.c
src/egl/drivers/dri2/platform_drm.c
src/egl/drivers/dri2/platform_wayland.c
src/egl/drivers/dri2/platform_x11.c

index 8c5ceb98c289ca24e0d6390fcad2408ae6df02a1..1d670b1e0834727a9b4f4a4f8d4ad5338f737fe8 100644 (file)
@@ -279,6 +279,7 @@ struct __DRItexBufferExtensionRec {
 
 #define __DRI2_FLUSH_DRAWABLE (1 << 0) /* the drawable should be flushed. */
 #define __DRI2_FLUSH_CONTEXT  (1 << 1) /* glFlush should be called */
+#define __DRI2_FLUSH_INVALIDATE_ANCILLARY (1 << 2)
 
 enum __DRI2throttleReason {
    __DRI2_THROTTLE_SWAPBUFFER,
index 2a6811ce3f5c38f7473985d4c61688d6c19da5c5..86e5f248d1e952afdc27819307229cb0f0d26055 100644 (file)
@@ -1087,6 +1087,42 @@ dri2_swap_interval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
    return dri2_dpy->vtbl->swap_interval(drv, dpy, surf, interval);
 }
 
+/**
+ * Asks the client API to flush any rendering to the drawable so that we can
+ * do our swapbuffers.
+ */
+void
+dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+   if (dri2_dpy->flush) {
+      if (dri2_dpy->flush->base.version >= 4) {
+         /* We know there's a current context because:
+          *
+          *     "If surface is not bound to the calling thread’s current
+          *      context, an EGL_BAD_SURFACE error is generated."
+         */
+         _EGLContext *ctx = _eglGetCurrentContext();
+         struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+
+         /* From the EGL 1.4 spec (page 52):
+          *
+          *     "The contents of ancillary buffers are always undefined
+          *      after calling eglSwapBuffers."
+          */
+         dri2_dpy->flush->flush_with_flags(dri2_ctx->dri_context,
+                                           dri2_surf->dri_drawable,
+                                           __DRI2_FLUSH_DRAWABLE |
+                                           __DRI2_FLUSH_INVALIDATE_ANCILLARY,
+                                           __DRI2_THROTTLE_SWAPBUFFER);
+      } else {
+         dri2_dpy->flush->flush(dri2_surf->dri_drawable);
+      }
+   }
+}
+
 static EGLBoolean
 dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
 {
index 52f05fbfd3ccef95f56163f43052f773eab076ef..9efe1f733fd0a9235565b8d21093bdd5e773a549 100644 (file)
@@ -332,4 +332,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp);
 EGLBoolean
 dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp);
 
+void
+dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw);
+
 #endif /* EGL_DRI2_INCLUDED */
index 61a99ba68f1e446aa925f16debdafde672b0709d..f4825261badc502fe4ce85812f2aa2a437b28389 100644 (file)
@@ -311,7 +311,7 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
          dri2_drv->glFlush();
    }
 
-   (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+   dri2_flush_drawable_for_swapbuffers(disp, draw);
 
    if (dri2_surf->buffer)
       droid_window_enqueue_buffer(dri2_surf);
index 753c60f1426194db222a737cbfad081fe27b6da4..02e87f7771b2e9caff95945d237ac92690b8b536 100644 (file)
@@ -431,7 +431,7 @@ dri2_drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
          dri2_surf->back = NULL;
       }
 
-      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+      dri2_flush_drawable_for_swapbuffers(disp, draw);
       (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
    }
 
index ba0eb10163a0be2325e1a2f60452e6bed1eed924..e8b441316ee5caf15767b0a59ee627934eb4b5b3 100644 (file)
@@ -649,17 +649,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDriver *drv,
       }
    }
 
-   if (dri2_dpy->flush->base.version >= 4) {
-      ctx = _eglGetCurrentContext();
-      dri2_ctx = dri2_egl_context(ctx);
-      (*dri2_dpy->flush->flush_with_flags)(dri2_ctx->dri_context,
-                                           dri2_surf->dri_drawable,
-                                           __DRI2_FLUSH_DRAWABLE,
-                                           __DRI2_THROTTLE_SWAPBUFFER);
-   } else {
-      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
-   }
-
+   dri2_flush_drawable_for_swapbuffers(disp, draw);
    (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
 
    wl_surface_commit(dri2_surf->wl_win->surface);
index f8c4b707a29763d92fafd771683fd0c2693b3ec8..dd88e900e8dd6ad91cee29e3550e11fe29642595 100644 (file)
@@ -771,8 +771,7 @@ dri2_x11_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw,
    if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available)
       return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1;
 
-   if (dri2_dpy->flush)
-      (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+   dri2_flush_drawable_for_swapbuffers(disp, draw);
 
    cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable,
                   msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo);