screen-cast: Only check queued-redraw on the relevant views

We'd check if there was any queued redraw on the stage, but this is
inappropriate for two reasons:

1) A monitor and area screen cast source only cares about damage on a
   subset of the stage.
2) The global pending-redraw is going away when paint scheduling will be
   more view centric.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
This commit is contained in:
Jonas Ådahl 2020-04-01 11:06:13 +02:00
parent feb444402e
commit b9a52ecfdf
4 changed files with 50 additions and 11 deletions

View File

@ -2951,14 +2951,15 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
#undef _DEG_TO_RAD #undef _DEG_TO_RAD
/** /**
* clutter_stage_is_redraw_queued: (skip) * clutter_stage_is_redraw_queued_on_view: (skip)
*/ */
gboolean gboolean
clutter_stage_is_redraw_queued (ClutterStage *stage) clutter_stage_is_redraw_queued_on_view (ClutterStage *stage,
ClutterStageView *view)
{ {
ClutterStagePrivate *priv = stage->priv; clutter_stage_maybe_finish_queue_redraws (stage);
return priv->redraw_pending; return clutter_stage_view_has_redraw_clip (view);
} }
void void

View File

@ -197,7 +197,8 @@ CLUTTER_EXPORT
void clutter_stage_ensure_viewport (ClutterStage *stage); void clutter_stage_ensure_viewport (ClutterStage *stage);
CLUTTER_EXPORT CLUTTER_EXPORT
gboolean clutter_stage_is_redraw_queued (ClutterStage *stage); gboolean clutter_stage_is_redraw_queued_on_view (ClutterStage *stage,
ClutterStageView *view);
#ifdef CLUTTER_ENABLE_EXPERIMENTAL_API #ifdef CLUTTER_ENABLE_EXPERIMENTAL_API
CLUTTER_EXPORT CLUTTER_EXPORT

View File

@ -149,16 +149,32 @@ is_cursor_in_stream (MetaScreenCastAreaStreamSrc *area_src)
} }
} }
static gboolean
is_redraw_queued (MetaScreenCastAreaStreamSrc *area_src)
{
ClutterStage *stage = get_stage (area_src);
GList *l;
for (l = clutter_stage_peek_stage_views (stage); l; l = l->next)
{
ClutterStageView *view = l->data;
if (clutter_stage_is_redraw_queued_on_view (stage, view))
return TRUE;
}
return FALSE;
}
static void static void
sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src) sync_cursor_state (MetaScreenCastAreaStreamSrc *area_src)
{ {
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
ClutterStage *stage = get_stage (area_src);
if (!is_cursor_in_stream (area_src)) if (!is_cursor_in_stream (area_src))
return; return;
if (clutter_stage_is_redraw_queued (stage)) if (is_redraw_queued (area_src))
return; return;
meta_screen_cast_stream_src_maybe_record_frame (src); meta_screen_cast_stream_src_maybe_record_frame (src);

View File

@ -176,16 +176,37 @@ is_cursor_in_stream (MetaScreenCastMonitorStreamSrc *monitor_src)
} }
} }
static gboolean
is_redraw_queued (MetaScreenCastMonitorStreamSrc *monitor_src)
{
MetaBackend *backend = get_backend (monitor_src);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
ClutterStage *stage = get_stage (monitor_src);
MetaMonitor *monitor = get_monitor (monitor_src);
g_autoptr (GList) views = NULL;
GList *l;
views = meta_renderer_get_views_for_monitor (renderer, monitor);
for (l = views; l; l = l->next)
{
MetaRendererView *view = l->data;
if (clutter_stage_is_redraw_queued_on_view (stage, CLUTTER_STAGE_VIEW (view)))
return TRUE;
}
return FALSE;
}
static void static void
sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src) sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
{ {
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
ClutterStage *stage = get_stage (monitor_src);
if (!is_cursor_in_stream (monitor_src)) if (!is_cursor_in_stream (monitor_src))
return; return;
if (clutter_stage_is_redraw_queued (stage)) if (is_redraw_queued (monitor_src))
return; return;
meta_screen_cast_stream_src_maybe_record_frame (src); meta_screen_cast_stream_src_maybe_record_frame (src);
@ -371,12 +392,12 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
MetaMonitor *monitor; MetaMonitor *monitor;
MetaLogicalMonitor *logical_monitor; MetaLogicalMonitor *logical_monitor;
stage = get_stage (monitor_src); if (!is_redraw_queued (monitor_src))
if (!clutter_stage_is_redraw_queued (stage))
return FALSE; return FALSE;
monitor = get_monitor (monitor_src); monitor = get_monitor (monitor_src);
logical_monitor = meta_monitor_get_logical_monitor (monitor); logical_monitor = meta_monitor_get_logical_monitor (monitor);
stage = get_stage (monitor_src);
clutter_stage_capture_into (stage, FALSE, &logical_monitor->rect, data); clutter_stage_capture_into (stage, FALSE, &logical_monitor->rect, data);
return TRUE; return TRUE;