screen-cast/stream: Pass redraw clip to stage watches instead of paint context

The virtual stream source with CURSOR_MODE_EMBEDDED uses
META_STAGE_WATCH_AFTER_PAINT as the callback for recording its frame. In
this stage of the paint though, there is no ClutterPaintContext anymore
(there only is a paint context during the paint, not afterwards).
The callback (actors_painted()) tries to get the redraw clip from the paint
context, and we end up with a NULL pointer crash.

We actually do still have a redraw clip at this point, so because everyone
uses the paint context to get the redraw clip anyway, just pass the redraw
clip to the stage watches directly.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3283>
This commit is contained in:
Jonas Dreßler 2023-09-15 18:54:37 +02:00 committed by Robert Mader
parent 03a5699abd
commit c4b9431bb2
6 changed files with 46 additions and 48 deletions

View File

@ -243,11 +243,11 @@ maybe_record_frame_on_idle (gpointer user_data)
} }
static void static void
before_stage_painted (MetaStage *stage, before_stage_painted (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
gpointer user_data) gpointer user_data)
{ {
MetaScreenCastAreaStreamSrc *area_src = MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (user_data); META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
@ -263,25 +263,23 @@ before_stage_painted (MetaStage *stage,
} }
static void static void
stage_painted (MetaStage *stage, stage_painted (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
gpointer user_data) gpointer user_data)
{ {
MetaScreenCastAreaStreamSrc *area_src = MetaScreenCastAreaStreamSrc *area_src =
META_SCREEN_CAST_AREA_STREAM_SRC (user_data); META_SCREEN_CAST_AREA_STREAM_SRC (user_data);
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (area_src);
MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src);
MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream); MetaScreenCastAreaStream *area_stream = META_SCREEN_CAST_AREA_STREAM (stream);
const cairo_region_t *redraw_clip;
MtkRectangle *area; MtkRectangle *area;
if (area_src->maybe_record_idle_id) if (area_src->maybe_record_idle_id)
return; return;
area = meta_screen_cast_area_stream_get_area (area_stream); area = meta_screen_cast_area_stream_get_area (area_stream);
redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
if (redraw_clip) if (redraw_clip)
{ {

View File

@ -147,11 +147,11 @@ maybe_record_frame_on_idle (gpointer user_data)
} }
static void static void
stage_painted (MetaStage *stage, stage_painted (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
gpointer user_data) gpointer user_data)
{ {
MetaScreenCastMonitorStreamSrc *monitor_src = MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data); META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data);
@ -187,11 +187,11 @@ stage_painted (MetaStage *stage,
} }
static void static void
before_stage_painted (MetaStage *stage, before_stage_painted (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
gpointer user_data) gpointer user_data)
{ {
MetaScreenCastMonitorStreamSrc *monitor_src = MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data); META_SCREEN_CAST_MONITOR_STREAM_SRC (user_data);

View File

@ -194,18 +194,16 @@ uninhibit_hw_cursor (MetaScreenCastVirtualStreamSrc *virtual_src)
} }
static void static void
actors_painted (MetaStage *stage, actors_painted (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
gpointer user_data) gpointer user_data)
{ {
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data); MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
MetaScreenCastRecordFlag flags; MetaScreenCastRecordFlag flags;
const cairo_region_t *redraw_clip = NULL;
flags = META_SCREEN_CAST_RECORD_FLAG_NONE; flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
meta_screen_cast_stream_src_maybe_record_frame (src, flags, redraw_clip); meta_screen_cast_stream_src_maybe_record_frame (src, flags, redraw_clip);
} }

View File

@ -36,11 +36,11 @@ typedef enum
META_STAGE_WATCH_AFTER_PAINT, META_STAGE_WATCH_AFTER_PAINT,
} MetaStageWatchPhase; } MetaStageWatchPhase;
typedef void (* MetaStageWatchFunc) (MetaStage *stage, typedef void (* MetaStageWatchFunc) (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
gpointer user_data); gpointer user_data);
ClutterActor *meta_stage_new (MetaBackend *backend); ClutterActor *meta_stage_new (MetaBackend *backend);

View File

@ -175,11 +175,11 @@ meta_stage_finalize (GObject *object)
} }
static void static void
notify_watchers_for_mode (MetaStage *stage, notify_watchers_for_mode (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
MetaStageWatchPhase watch_phase) MetaStageWatchPhase watch_phase)
{ {
GPtrArray *watchers; GPtrArray *watchers;
int i; int i;
@ -193,7 +193,7 @@ notify_watchers_for_mode (MetaStage *stage,
if (watch->view && view != watch->view) if (watch->view && view != watch->view)
continue; continue;
watch->callback (stage, view, paint_context, frame, watch->user_data); watch->callback (stage, view, redraw_clip, frame, watch->user_data);
} }
} }
@ -215,14 +215,16 @@ meta_stage_paint (ClutterActor *actor,
MetaStage *stage = META_STAGE (actor); MetaStage *stage = META_STAGE (actor);
ClutterStageView *view; ClutterStageView *view;
ClutterFrame *frame; ClutterFrame *frame;
const cairo_region_t *redraw_clip;
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context); CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context);
frame = clutter_paint_context_get_frame (paint_context); frame = clutter_paint_context_get_frame (paint_context);
view = clutter_paint_context_get_stage_view (paint_context); view = clutter_paint_context_get_stage_view (paint_context);
redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
if (view) if (view)
{ {
notify_watchers_for_mode (stage, view, paint_context, frame, notify_watchers_for_mode (stage, view, redraw_clip, frame,
META_STAGE_WATCH_AFTER_ACTOR_PAINT); META_STAGE_WATCH_AFTER_ACTOR_PAINT);
} }
@ -250,7 +252,7 @@ meta_stage_paint (ClutterActor *actor,
if (view) if (view)
{ {
notify_watchers_for_mode (stage, view, paint_context, frame, notify_watchers_for_mode (stage, view, redraw_clip, frame,
META_STAGE_WATCH_AFTER_OVERLAY_PAINT); META_STAGE_WATCH_AFTER_OVERLAY_PAINT);
} }
} }
@ -267,7 +269,7 @@ meta_stage_paint_view (ClutterStage *stage,
redraw_clip, redraw_clip,
frame); frame);
notify_watchers_for_mode (meta_stage, view, NULL, frame, notify_watchers_for_mode (meta_stage, view, redraw_clip, frame,
META_STAGE_WATCH_AFTER_PAINT); META_STAGE_WATCH_AFTER_PAINT);
} }

View File

@ -270,11 +270,11 @@ typedef struct
} CaptureViewData; } CaptureViewData;
static void static void
on_after_paint (MetaStage *stage, on_after_paint (MetaStage *stage,
ClutterStageView *view, ClutterStageView *view,
ClutterPaintContext *paint_context, const cairo_region_t *redraw_clip,
ClutterFrame *frame, ClutterFrame *frame,
gpointer user_data) gpointer user_data)
{ {
CaptureViewData *data = user_data; CaptureViewData *data = user_data;
MtkRectangle rect; MtkRectangle rect;