summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalman <salmanmalik@chromium.org>2022-12-20 19:31:08 +0000
committerMarge Bot <marge-bot@gnome.org>2023-04-06 23:09:43 +0000
commit43cee4b6b6bef88e74ef877439aa5696c95612b7 (patch)
tree40baf231bdaf23ec8c6390069d479b1ea05c257f
parentab36baa9b1e7859f6958e5389eb086581b174d6c (diff)
downloadmutter-43cee4b6b6bef88e74ef877439aa5696c95612b7.tar.gz
stage-impl: Do clipped redraws when drawing offscreen
This change allows clipped redraws for offscreen. The net effect of this change is to preserve the original redraw clip when possible (rather than overwriting it with the full view redraw) in the paint context. This eventually helps in retrieving the fine grained updated regions of the frame since last redraw and sending it to the pipewire client (as shown in a subsquent CL). Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2775>
-rw-r--r--src/backends/meta-stage-impl.c72
1 files changed, 51 insertions, 21 deletions
diff --git a/src/backends/meta-stage-impl.c b/src/backends/meta-stage-impl.c
index 31e07d965..db94c7e40 100644
--- a/src/backends/meta-stage-impl.c
+++ b/src/backends/meta-stage-impl.c
@@ -454,6 +454,46 @@ transform_swap_region_to_onscreen (ClutterStageView *stage_view,
return transformed_region;
}
+static gboolean
+should_use_clipped_redraw (gboolean is_full_redraw,
+ gboolean has_buffer_age,
+ gboolean buffer_has_valid_damage_history,
+ ClutterDrawDebugFlag paint_debug_flags,
+ CoglFramebuffer *framebuffer,
+ ClutterStageWindow *stage_window)
+{
+ gboolean can_blit_sub_buffer;
+ gboolean can_use_clipped_redraw;
+ gboolean is_warmed_up;
+
+ if (is_full_redraw)
+ return FALSE;
+
+ if (paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)
+ return FALSE;
+
+ if (COGL_IS_OFFSCREEN (framebuffer))
+ return TRUE;
+
+ if (!buffer_has_valid_damage_history)
+ {
+ meta_topic (META_DEBUG_BACKEND,
+ "Invalid back buffer age: forcing full redraw");
+ return FALSE;
+ }
+
+ can_blit_sub_buffer =
+ cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
+ can_use_clipped_redraw =
+ _clutter_stage_window_can_clip_redraws (stage_window) &&
+ (can_blit_sub_buffer || has_buffer_age);
+ /* Some drivers struggle to get going and produce some junk
+ * frames when starting up... */
+ is_warmed_up =
+ cogl_onscreen_get_frame_counter (COGL_ONSCREEN (framebuffer)) > 3;
+ return is_warmed_up && can_use_clipped_redraw;
+}
+
static void
meta_stage_impl_redraw_view_primary (MetaStageImpl *stage_impl,
ClutterStageView *stage_view,
@@ -465,8 +505,8 @@ meta_stage_impl_redraw_view_primary (MetaStageImpl *stage_impl,
CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (stage_view);
cairo_rectangle_int_t view_rect;
gboolean is_full_redraw;
- gboolean use_clipped_redraw = TRUE;
- gboolean can_blit_sub_buffer;
+ gboolean use_clipped_redraw;
+ gboolean buffer_has_valid_damage_history = FALSE;
gboolean has_buffer_age;
gboolean swap_with_damage;
cairo_region_t *redraw_clip;
@@ -484,10 +524,6 @@ meta_stage_impl_redraw_view_primary (MetaStageImpl *stage_impl,
fb_width = cogl_framebuffer_get_width (fb);
fb_height = cogl_framebuffer_get_height (fb);
- can_blit_sub_buffer =
- COGL_IS_ONSCREEN (onscreen) &&
- cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
-
has_buffer_age =
COGL_IS_ONSCREEN (onscreen) &&
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
@@ -505,26 +541,20 @@ meta_stage_impl_redraw_view_primary (MetaStageImpl *stage_impl,
if (has_buffer_age)
{
buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (onscreen));
- if (!clutter_damage_history_is_age_valid (damage_history, buffer_age))
- {
- meta_topic (META_DEBUG_BACKEND,
- "Invalid back buffer(age=%d): forcing full redraw",
- buffer_age);
- use_clipped_redraw = FALSE;
- }
+ buffer_has_valid_damage_history =
+ clutter_damage_history_is_age_valid (damage_history,
+ buffer_age);
}
meta_get_clutter_debug_flags (NULL, &paint_debug_flags, NULL);
use_clipped_redraw =
- use_clipped_redraw &&
- !(paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS) &&
- _clutter_stage_window_can_clip_redraws (stage_window) &&
- (can_blit_sub_buffer || has_buffer_age) &&
- !is_full_redraw &&
- /* some drivers struggle to get going and produce some junk
- * frames when starting up... */
- cogl_onscreen_get_frame_counter (COGL_ONSCREEN (onscreen)) > 3;
+ should_use_clipped_redraw (is_full_redraw,
+ has_buffer_age,
+ buffer_has_valid_damage_history,
+ paint_debug_flags,
+ onscreen,
+ stage_window);
if (use_clipped_redraw)
{