From 4139907a7e614c8ff4943c3bd50a55b1287b4761 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 8 May 2017 15:10:58 +0200 Subject: [PATCH] cogl: Ensure to only clear the depth buffer if depth testing is enabled The depth buffer is marked as invalid when 1) the framebuffer is just created, and 2) whenever GL_DEPTH_TEST is enabled on it. This will ensure the framebuffers attached depth buffer (if any) is properly cleared before it's actually used, while saving needless clears while depth testing is disabled (the default). https://bugzilla.gnome.org/show_bug.cgi?id=782344 --- cogl/cogl/cogl-framebuffer-private.h | 5 +++++ cogl/cogl/cogl-framebuffer.c | 11 +++++++++++ cogl/cogl/driver/gl/cogl-pipeline-opengl.c | 6 +++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h index d78bd408d..46a1d146d 100644 --- a/cogl/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl/cogl-framebuffer-private.h @@ -192,6 +192,11 @@ struct _CoglFramebuffer CoglFramebufferBits bits; int samples_per_pixel; + + /* Whether the depth buffer was enabled for this framebuffer, + * usually means it needs to be cleared before being reused next. + */ + CoglBool depth_buffer_clear_needed; }; typedef enum { diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c index f2df9c229..8660f910a 100644 --- a/cogl/cogl/cogl-framebuffer.c +++ b/cogl/cogl/cogl-framebuffer.c @@ -116,6 +116,7 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer, framebuffer->viewport_age_for_scissor_workaround = -1; framebuffer->dither_enabled = TRUE; framebuffer->depth_writing_enabled = TRUE; + framebuffer->depth_buffer_clear_needed = TRUE; framebuffer->modelview_stack = cogl_matrix_stack_new (ctx); framebuffer->projection_stack = cogl_matrix_stack_new (ctx); @@ -267,6 +268,13 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, int scissor_y1; CoglBool saved_viewport_scissor_workaround; + if (!framebuffer->depth_buffer_clear_needed && + (buffers & COGL_BUFFER_BIT_DEPTH)) + buffers &= ~(COGL_BUFFER_BIT_DEPTH); + + if (buffers == 0) + return; + _cogl_clip_stack_get_bounds (clip_stack, &scissor_x0, &scissor_y0, &scissor_x1, &scissor_y1); @@ -414,6 +422,9 @@ cleared: _cogl_framebuffer_mark_mid_scene (framebuffer); _cogl_framebuffer_mark_clear_clip_dirty (framebuffer); + if (buffers & COGL_BUFFER_BIT_DEPTH) + framebuffer->depth_buffer_clear_needed = FALSE; + if (buffers & COGL_BUFFER_BIT_COLOR && buffers & COGL_BUFFER_BIT_DEPTH) { /* For our fast-path for reading back a single pixel of simple diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c index 0e8f7c698..1de4b65eb 100644 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c @@ -378,7 +378,11 @@ flush_depth_state (CoglContext *ctx, if (ctx->depth_test_enabled_cache != depth_state->test_enabled) { if (depth_state->test_enabled == TRUE) - GE (ctx, glEnable (GL_DEPTH_TEST)); + { + GE (ctx, glEnable (GL_DEPTH_TEST)); + if (ctx->current_draw_buffer) + ctx->current_draw_buffer->depth_buffer_clear_needed = TRUE; + } else GE (ctx, glDisable (GL_DEPTH_TEST)); ctx->depth_test_enabled_cache = depth_state->test_enabled;