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

@ -245,7 +245,7 @@ maybe_record_frame_on_idle (gpointer user_data)
static void
before_stage_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
gpointer user_data)
{
@ -265,7 +265,7 @@ before_stage_painted (MetaStage *stage,
static void
stage_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
gpointer user_data)
{
@ -274,14 +274,12 @@ stage_painted (MetaStage *stage,
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

@ -149,7 +149,7 @@ maybe_record_frame_on_idle (gpointer user_data)
static void
stage_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
gpointer user_data)
{
@ -189,7 +189,7 @@ stage_painted (MetaStage *stage,
static void
before_stage_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
gpointer user_data)
{

View File

@ -196,16 +196,14 @@ uninhibit_hw_cursor (MetaScreenCastVirtualStreamSrc *virtual_src)
static void
actors_painted (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
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

@ -38,7 +38,7 @@ typedef enum
typedef void (* MetaStageWatchFunc) (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
gpointer user_data);

View File

@ -177,7 +177,7 @@ meta_stage_finalize (GObject *object)
static void
notify_watchers_for_mode (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
MetaStageWatchPhase watch_phase)
{
@ -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

@ -272,7 +272,7 @@ typedef struct
static void
on_after_paint (MetaStage *stage,
ClutterStageView *view,
ClutterPaintContext *paint_context,
const cairo_region_t *redraw_clip,
ClutterFrame *frame,
gpointer user_data)
{