summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cogl/cogl-ext-functions.h11
-rw-r--r--cogl/cogl-framebuffer.c51
-rw-r--r--cogl/cogl-framebuffer.h42
3 files changed, 98 insertions, 6 deletions
diff --git a/cogl/cogl-ext-functions.h b/cogl/cogl-ext-functions.h
index 47d5192f..0adbc934 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 4a45e756..5645d0bf 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 fb69da4e..1b7301ec 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);