From f86e33e1ea32c4208809e8de33bed05ddbce9a4c Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Sun, 7 May 2017 03:00:10 +0200
Subject: [PATCH 1/3] compositor: Avoid changing pipeline/source if shadow is
not being painted
Avoids some context invalidations in cogl.
https://bugzilla.gnome.org/show_bug.cgi?id=782344
---
src/compositor/meta-shadow-factory.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/compositor/meta-shadow-factory.c b/src/compositor/meta-shadow-factory.c
index cd006008b..19147ca9f 100644
--- a/src/compositor/meta-shadow-factory.c
+++ b/src/compositor/meta-shadow-factory.c
@@ -220,9 +220,7 @@ meta_shadow_paint (MetaShadow *shadow,
int dest_x[4];
int dest_y[4];
int n_x, n_y;
-
- cogl_pipeline_set_color4ub (shadow->pipeline,
- opacity, opacity, opacity, opacity);
+ gboolean source_updated = FALSE;
cogl_set_source (shadow->pipeline);
@@ -300,6 +298,17 @@ meta_shadow_paint (MetaShadow *shadow,
else
overlap = CAIRO_REGION_OVERLAP_IN;
+ if (overlap == CAIRO_REGION_OVERLAP_OUT)
+ continue;
+
+ if (!source_updated)
+ {
+ cogl_pipeline_set_color4ub (shadow->pipeline,
+ opacity, opacity, opacity, opacity);
+ cogl_set_source (shadow->pipeline);
+ source_updated = TRUE;
+ }
+
/* There's quite a bit of overhead from allocating a new
* region in order to find an exact intersection and
* generating more geometry - we make the assumption that
--
2.23.0
From f530bc4c3391cabe2b084cd59def00d81c13286c Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Fri, 5 May 2017 14:15:30 +0200
Subject: [PATCH 2/3] clutter: Avoid rounding compensation when invalidating 2D
actors
This allows the redraw clip to be more constrained, so MetaCullable doesn't
end up rendering portions of window shadows, frame and background when a
window invalidates (part of) its contents.
https://bugzilla.gnome.org/show_bug.cgi?id=782344
---
clutter/clutter/clutter-paint-volume.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/clutter/clutter/clutter-paint-volume.c b/clutter/clutter/clutter-paint-volume.c
index b48f7f9d6..f3405138b 100644
--- a/clutter/clutter/clutter-paint-volume.c
+++ b/clutter/clutter/clutter-paint-volume.c
@@ -1166,6 +1166,21 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
_clutter_paint_volume_get_bounding_box (&projected_pv, box);
+ if (pv->is_2d && pv->actor &&
+ clutter_actor_get_z_position (pv->actor) == 0)
+ {
+ /* If the volume/actor are perfectly 2D, take the bounding box as
+ * good. We won't need to add any extra room for sub-pixel positioning
+ * in this case.
+ */
+ clutter_paint_volume_free (&projected_pv);
+ box->x1 = CLUTTER_NEARBYINT (box->x1);
+ box->y1 = CLUTTER_NEARBYINT (box->y1);
+ box->x2 = CLUTTER_NEARBYINT (box->x2);
+ box->y2 = CLUTTER_NEARBYINT (box->y2);
+ return;
+ }
+
/* The aim here is that for a given rectangle defined with floating point
* coordinates we want to determine a stable quantized size in pixels
* that doesn't vary due to the original box's sub-pixel position.
--
2.23.0
From 676369000658c6121d0c3b5e1286aa68dc79eb35 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 8 May 2017 15:10:58 +0200
Subject: [PATCH 3/3] 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 99ac2fba9..756e34dfe 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -193,6 +193,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 55b9e3756..6b105087d 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -117,6 +117,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);
@@ -268,6 +269,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);
@@ -415,6 +423,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 178269646..4f1f69f96 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
@@ -418,7 +418,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;
--
2.23.0