From 753066598ff83fa9bdbd1be23d1e22663ae59297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 12 Sep 2019 11:28:50 +0200 Subject: [PATCH] clutter/view: Make it possible to assign a temporary direct scanout Make it possible to cause the next frame to scan out directly from the passed CoglScannout. This makes it possible to completely bypass compositing for the following frame. https://gitlab.gnome.org/GNOME/mutter/merge_requests/798 --- clutter/clutter/clutter-mutter.h | 4 +++ clutter/clutter/clutter-stage-view-private.h | 2 ++ clutter/clutter/clutter-stage-view.c | 24 +++++++++++++++++ clutter/clutter/cogl/clutter-stage-cogl.c | 28 +++++++++++++++++++- cogl/cogl/cogl-onscreen.h | 2 +- 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h index e51ccba98..5c652a4e3 100644 --- a/clutter/clutter/clutter-mutter.h +++ b/clutter/clutter/clutter-mutter.h @@ -57,6 +57,10 @@ void clutter_stage_thaw_updates (ClutterStage *stage); CLUTTER_EXPORT void clutter_stage_update_resource_scales (ClutterStage *stage); +CLUTTER_EXPORT +void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view, + CoglScanout *scanout); + CLUTTER_EXPORT gboolean clutter_actor_has_damage (ClutterActor *actor); diff --git a/clutter/clutter/clutter-stage-view-private.h b/clutter/clutter/clutter-stage-view-private.h index 3b0d419fc..2e5ad4c53 100644 --- a/clutter/clutter/clutter-stage-view-private.h +++ b/clutter/clutter/clutter-stage-view-private.h @@ -43,4 +43,6 @@ const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *vi cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view); +CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view); + #endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */ diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c index d93cf573f..b7413be7c 100644 --- a/clutter/clutter/clutter-stage-view.c +++ b/clutter/clutter/clutter-stage-view.c @@ -24,6 +24,8 @@ #include #include "clutter/clutter-private.h" +#include "clutter/clutter-mutter.h" +#include "cogl/cogl.h" enum { @@ -52,6 +54,8 @@ typedef struct _ClutterStageViewPrivate CoglOffscreen *shadowfb; CoglPipeline *shadowfb_pipeline; + CoglScanout *next_scanout; + gboolean has_redraw_clip; cairo_region_t *redraw_clip; @@ -407,6 +411,26 @@ clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *vie cogl_matrix_init_identity (matrix); } +void +clutter_stage_view_assign_next_scanout (ClutterStageView *view, + CoglScanout *scanout) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + g_clear_object (&priv->next_scanout); + priv->next_scanout = scanout; +} + +CoglScanout * +clutter_stage_view_take_scanout (ClutterStageView *view) +{ + ClutterStageViewPrivate *priv = + clutter_stage_view_get_instance_private (view); + + return g_steal_pointer (&priv->next_scanout); +} + static void clutter_stage_view_get_property (GObject *object, guint prop_id, diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index d48e97641..533d68154 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -959,6 +959,20 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, } } +static void +clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl, + ClutterStageView *view, + CoglScanout *scanout) +{ + CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view); + CoglOnscreen *onscreen; + + g_return_if_fail (cogl_is_onscreen (framebuffer)); + + onscreen = COGL_ONSCREEN (framebuffer); + cogl_onscreen_direct_scanout (onscreen, scanout); +} + static void clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) { @@ -971,11 +985,23 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window) for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next) { ClutterStageView *view = l->data; + g_autoptr (CoglScanout) scanout = NULL; if (!clutter_stage_view_has_redraw_clip (view)) continue; - swap_event |= clutter_stage_cogl_redraw_view (stage_window, view); + scanout = clutter_stage_view_take_scanout (view); + if (scanout) + { + clutter_stage_cogl_scanout_view (stage_cogl, + view, + scanout); + swap_event = TRUE; + } + else + { + swap_event |= clutter_stage_cogl_redraw_view (stage_window, view); + } } _clutter_stage_emit_after_paint (stage_cogl->wrapper); diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h index fd95edd82..845470350 100644 --- a/cogl/cogl/cogl-onscreen.h +++ b/cogl/cogl/cogl-onscreen.h @@ -289,7 +289,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, /** * cogl_onscreen_direct_scanout: (skip) */ -void +COGL_EXPORT void cogl_onscreen_direct_scanout (CoglOnscreen *onscreen, CoglScanout *scanout);