[cogl/wip/framebuffer-discard: 2/2] framebuffer: Add explicit buffer discard API



commit 7663cddfc3d30753299e6ae54af738e826314112
Author: Robert Bragg <robert linux intel com>
Date:   Fri Aug 19 15:53:59 2011 +0100

    framebuffer: Add explicit buffer discard API
    
    This adds cogl_framebuffer_discard_buffers API that allows applications
    to explicitly discard color, depth and stencil buffers which really
    helps with deferred rendering GPUs that can potentially avoid the need
    to save and restore the results of depth and stencil buffer changes
    between frames and these can instead be handled directly with on-chip
    memory instead.
    
    The semantics for cogl_framebuffer_swap_buffers are now documented to
    include an implicit discard of all buffers.
    
    We would recommend that all offscreen rendering to a CoglOffscreen
    framebuffer should be followed by a call like:
    cogl_framebuffer_discard_buffers (fb,
                                      COGL_BUFFER_BIT_COLOR|
                                      COGL_BUFFER_BIT_DEPTH|
                                      COGL_BUFFER_BIT_STENCIL);

 cogl/cogl-ext-functions.h |   11 +++++++++
 cogl/cogl-framebuffer.c   |   51 +++++++++++++++++++++++++++++++++++++++-----
 cogl/cogl-framebuffer.h   |   42 +++++++++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 6 deletions(-)
---
diff --git a/cogl/cogl-ext-functions.h b/cogl/cogl-ext-functions.h
index 47d5192..0adbc93 100644
--- a/cogl/cogl-ext-functions.h
+++ b/cogl/cogl-ext-functions.h
@@ -647,3 +647,14 @@ COGL_EXT_FUNCTION (void, glEGLImageTargetRenderbufferStorage,
                    (GLenum           target,
                     GLeglImageOES    image))
 COGL_EXT_END ()
+
+COGL_EXT_BEGIN (framebuffer_discard, 255, 255,
+                0, /* not in either GLES */
+                "EXT\0",
+                "framebuffer_discard\0")
+COGL_EXT_FUNCTION (void, glDiscardFramebuffer,
+                   (GLenum           target,
+                    GLsizei          numAttachments,
+                    const GLenum    *attachments))
+COGL_EXT_END ()
+
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 4a45e75..5645d0b 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -1652,16 +1652,55 @@ _cogl_blit_framebuffer (unsigned int src_x,
 }
 
 void
+cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer,
+                                  unsigned long buffers)
+{
+#ifdef GL_EXT_framebuffer_discard
+  CoglContext *ctx = framebuffer->context;
+  if (ctx->glDiscardFramebuffer)
+    {
+      GLenum attachments[3];
+      int i = 0;
+
+      if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+        {
+          if (buffers & COGL_BUFFER_BIT_COLOR)
+            attachments[i++] = GL_COLOR_EXT;
+          if (buffers & COGL_BUFFER_BIT_DEPTH)
+            attachments[i++] = GL_DEPTH_EXT;
+          if (buffers & COGL_BUFFER_BIT_STENCIL)
+            attachments[i++] = GL_STENCIL_EXT;
+        }
+      else
+        {
+          if (buffers & COGL_BUFFER_BIT_COLOR)
+            attachments[i++] = GL_COLOR_ATTACHMENT0;
+          if (buffers & COGL_BUFFER_BIT_DEPTH)
+            attachments[i++] = GL_DEPTH_ATTACHMENT;
+          if (buffers & COGL_BUFFER_BIT_STENCIL)
+            attachments[i++] = GL_STENCIL_ATTACHMENT;
+        }
+
+      GE (ctx, glDiscardFramebuffer (GL_FRAMEBUFFER, i, attachments));
+    }
+#endif
+}
+
+void
 cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer)
 {
+  const CoglWinsysVtable *winsys;
+
+  g_return_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
+
   /* FIXME: we shouldn't need to flush *all* journals here! */
   cogl_flush ();
-  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
-    {
-      const CoglWinsysVtable *winsys =
-        _cogl_framebuffer_get_winsys (framebuffer);
-      winsys->onscreen_swap_buffers (COGL_ONSCREEN (framebuffer));
-    }
+  winsys = _cogl_framebuffer_get_winsys (framebuffer);
+  winsys->onscreen_swap_buffers (COGL_ONSCREEN (framebuffer));
+  cogl_framebuffer_discard_buffers (framebuffer,
+                                    COGL_BUFFER_BIT_COLOR |
+                                    COGL_BUFFER_BIT_DEPTH |
+                                    COGL_BUFFER_BIT_STENCIL);
 }
 
 void
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index fb69da4..1b7301e 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -326,7 +326,49 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
                           float blue,
                           float alpha);
 
+/* XXX: Should we take an n_buffers + buffer id array instead of using
+ * the CoglBufferBits type which doesn't seem future proof? */
+#define cogl_framebuffer_discard_buffers cogl_framebuffer_discard_buffers_EXP
+/**
+ * cogl_framebuffer_discard_buffers:
+ * @framebuffer: A #CoglFramebuffer
+ *
+ * Declares that the specified buffers no longer need to be referenced
+ * by any further rendering commands. This can be an important
+ * optimization to avoid subsequent frames of rendering depending on
+ * the results of a previous frame.
+ *
+ * For example; some GPUs are able to avoid allocating and accessing
+ * system memory for the depth and stencil buffer so long as these
+ * buffers are not required as input for subsequent frames and that
+ * can save a significant amount of memory bandwidth used to save and
+ * restore their contents to system memory between frames.
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
+void
+cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer,
+                                  unsigned long buffers);
+
+/* XXX: Actually should this be renamed too cogl_onscreen_swap_buffers()? */
 #define cogl_framebuffer_swap_buffers cogl_framebuffer_swap_buffers_EXP
+/**
+ * cogl_framebuffer_swap_buffers:
+ * @framebuffer: A #CoglFramebuffer
+ *
+ * Swaps the current back buffer being rendered too, to the front for
+ * display. This function also implicitly discards the contents of the
+ * color, depth and stencil buffers as if
+ * cogl_framebuffer_discard_buffers() were called with
+ * COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH |
+ * COGL_BUFFER_BIT_STENCIL. The significance of the discard is that
+ * you should not expect to be able to start a new frame that
+ * incrementally builds on the contents of the previous frame.
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
 void
 cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]