diff options
-rw-r--r-- | cogl/cogl-ext-functions.h | 11 | ||||
-rw-r--r-- | cogl/cogl-framebuffer.c | 51 | ||||
-rw-r--r-- | 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 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); |