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

View File

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

View File

@ -194,18 +194,16 @@ uninhibit_hw_cursor (MetaScreenCastVirtualStreamSrc *virtual_src)
}
static void
actors_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
ClutterFrame *frame,
gpointer user_data)
actors_painted (MetaStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
gpointer user_data)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
MetaScreenCastRecordFlag flags;
const cairo_region_t *redraw_clip = NULL;
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);
}

View File

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

View File

@ -175,11 +175,11 @@ meta_stage_finalize (GObject *object)
}
static void
notify_watchers_for_mode (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
ClutterFrame *frame,
MetaStageWatchPhase watch_phase)
notify_watchers_for_mode (MetaStage *stage,
ClutterStageView *view,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
MetaStageWatchPhase watch_phase)
{
GPtrArray *watchers;
int i;
@ -193,7 +193,7 @@ notify_watchers_for_mode (MetaStage *stage,
if (watch->view && view != watch->view)
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);
ClutterStageView *view;
ClutterFrame *frame;
const cairo_region_t *redraw_clip;
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor, paint_context);
frame = clutter_paint_context_get_frame (paint_context);
view = clutter_paint_context_get_stage_view (paint_context);
redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
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);
}
@ -250,7 +252,7 @@ meta_stage_paint (ClutterActor *actor,
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);
}
}
@ -267,7 +269,7 @@ meta_stage_paint_view (ClutterStage *stage,
redraw_clip,
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);
}

View File

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