Skip to content
Commits on Source (42)
3.36.4
======
* Fix crash on area screenshots with fractional scaling [Sebastian; !1320]
* Do not paint textures of fully obscured windows [Robert; !1326]
* Turn off CRTCs as well when enabling DPMS [Michel; !1240]
* Improve selection support
[Robert, Carlos, Sebastian; !1330, !1193, !1253, !1255, !1293, !1350]
* Use a more appropriate combine function on opaque areas [Daniel; !1331]
* Fix remote desktop being broken without screencast session [Olivier; #1307]
* Fix popovers disappearing on wayland and HiDPI [Robert; #1312]
* Fixed crashes [Jonas Å.; !1317]
* Plugged memory leaks [Jonas Å.; !1283]
* Misc. bug fixes and cleanups
[Corentin, Sebastian, Jonas Å., Jonas D.; !1314, !1321, !1295, !1333]
Contributors:
Jonas Dreßler, Michel Dänzer, Olivier Fourdan, Carlos Garnacho,
Sebastian Keller, Robert Mader, Corentin Noël, Daniel van Vugt, Jonas Ådahl
3.36.3
======
* Broadcast clipboard/primary offers [Carlos; !1262]
......
......@@ -475,8 +475,10 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
ClutterActor *child;
gint n_children = 0;
gfloat minimum, natural;
float largest_min_size, largest_nat_size;
minimum = natural = 0;
largest_min_size = largest_nat_size = 0;
clutter_actor_iter_init (&iter, container);
while (clutter_actor_iter_next (&iter, &child))
......@@ -491,8 +493,22 @@ get_preferred_size_for_orientation (ClutterBoxLayout *self,
get_child_size (child, priv->orientation,
for_size, &child_min, &child_nat);
minimum += child_min;
natural += child_nat;
if (priv->is_homogeneous)
{
largest_min_size = MAX (largest_min_size, child_min);
largest_nat_size = MAX (largest_nat_size, child_nat);
}
else
{
minimum += child_min;
natural += child_nat;
}
}
if (priv->is_homogeneous)
{
minimum = largest_min_size * n_children;
natural = largest_nat_size * n_children;
}
if (n_children > 1)
......@@ -623,6 +639,8 @@ get_preferred_size_for_opposite_orientation (ClutterBoxLayout *self,
}
else
{
size -= (nvis_children - 1) * priv->spacing;
/* Bring children up to size first */
if (isnormal (size) || size == 0)
{
......
......@@ -24,7 +24,7 @@ typedef enum _ClutterPaintFlag
{
CLUTTER_PAINT_FLAG_NONE = 0,
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 0,
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 1,
} ClutterPaintFlag;
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
......
......@@ -4526,8 +4526,8 @@ clutter_stage_paint_to_buffer (ClutterStage *stage,
CoglFramebuffer *framebuffer;
CoglBitmap *bitmap;
texture_width = (int) ceilf (rect->width * scale);
texture_height = (int) ceilf (rect->height * scale);
texture_width = (int) roundf (rect->width * scale);
texture_height = (int) roundf (rect->height * scale);
texture = cogl_texture_2d_new_with_size (cogl_context,
texture_width,
texture_height);
......
mutter (3.36.4-0ubuntu0.20.04.1) focal; urgency=medium
* New upstream stable release (LP: #1887998)
- Fix crash on area screenshots with fractional scaling
- Do not paint textures of fully obscured windows
- Turn off CRTCs as well when enabling DPMS
- Improve selection support
- Use a more appropriate combine function on opaque areas
- Fix remote desktop being broken without screencast session
- Fix popovers disappearing on wayland and HiDPI
- Fixed crashes (LP: #1870867, LP: #1857947)
- Plugged memory leaks
* d/p/screen-cast-Let-the-reason-for-recording-determine-what-t.patch,
d/p/screen-cast-src-Add-flag-to-maybe_record.patch,
d/p/screen-cast-src-Fix-signedness-of-timestamp-field.patch,
d/p/screen-cast-src-Make-record-functions-return-an-error-whe.patch,
d/p/screen-cast-src-Make-the-two-record-vfuncs-more-similarly.patch,
d/p/screen-cast-src-Record-follow-up-frame-after-timeout.patch,
d/p/screen-cast-src-Remove-follow-up-timeout-source-on-disabl.patch,
d/p/screen-cast-src-Use-G_USEC_PER_SEC-instead-of-1000000.patch,
d/p/screen-cast-window-stream-src-Fix-indentation.patch:
- Import more fixes for screencasting and remote desktop
* d/p/x11-Add-support-for-fractional-scaling-using-Randr.patch:
- Don't export patch-only private symbol
* debian/libmutter-6-0.symbols:
- Remove ubuntu-only private symbol
-- Marco Trevisan (Treviño) <marco@ubuntu.com> Mon, 20 Jul 2020 16:16:36 +0200
mutter (3.36.3-0ubuntu0.20.04.2) focal; urgency=medium
* debian/control:
......
......@@ -238,7 +238,6 @@ libmutter-6.so.0 libmutter-6-0 #MINVER#
meta_monitor_config_manager_assign@Base 3.28.2
meta_monitor_config_manager_clear_history@Base 3.28.2
meta_monitor_config_manager_create_fallback@Base 3.28.2
meta_monitor_config_manager_create_for_layout@Base 3.36.3-0ubuntu0.20.04.2
meta_monitor_config_manager_create_for_orientation@Base 3.28.2
meta_monitor_config_manager_create_for_rotate_monitor@Base 3.28.2
meta_monitor_config_manager_create_for_switch_config@Base 3.28.2
......
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 16:52:43 +0200
Subject: screen-cast: Let the reason for recording determine what to record
E.g. we'll have pointer movement that, if no painting is already
scheduled, should only send new cursor metadata without any new pixel
buffer. When this happens, tell next step to not record the pixels if
this was the case, instead of having it rediscover this itself.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-monitor-stream-src.c | 5 +--
src/backends/meta-screen-cast-stream-src.c | 51 ++++++++++++----------
src/backends/meta-screen-cast-stream-src.h | 1 +
src/backends/meta-screen-cast-window-stream-src.c | 4 +-
4 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
index 70edb22..17aa7ae 100644
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
@@ -191,7 +191,7 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
if (clutter_stage_is_redraw_queued (stage))
return;
- flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
@@ -376,9 +376,6 @@ meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *s
MetaLogicalMonitor *logical_monitor;
stage = get_stage (monitor_src);
- if (!clutter_stage_is_redraw_queued (stage))
- return FALSE;
-
monitor = get_monitor (monitor_src);
logical_monitor = meta_monitor_get_logical_monitor (monitor);
clutter_stage_capture_into (stage, FALSE, &logical_monitor->rect, data);
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 7f124bf..463d316 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -472,34 +472,41 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
return;
}
- if (do_record_frame (src, spa_buffer, data))
+ if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
{
- struct spa_meta_region *spa_meta_video_crop;
+ if (do_record_frame (src, spa_buffer, data))
+ {
+ struct spa_meta_region *spa_meta_video_crop;
- spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
- spa_buffer->datas[0].chunk->stride = priv->video_stride;
+ spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
+ spa_buffer->datas[0].chunk->stride = priv->video_stride;
- /* Update VideoCrop if needed */
- spa_meta_video_crop =
- spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
- sizeof (*spa_meta_video_crop));
- if (spa_meta_video_crop)
- {
- if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
- {
- spa_meta_video_crop->region.position.x = crop_rect.x;
- spa_meta_video_crop->region.position.y = crop_rect.y;
- spa_meta_video_crop->region.size.width = crop_rect.width;
- spa_meta_video_crop->region.size.height = crop_rect.height;
- }
- else
+ /* Update VideoCrop if needed */
+ spa_meta_video_crop =
+ spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
+ sizeof (*spa_meta_video_crop));
+ if (spa_meta_video_crop)
{
- spa_meta_video_crop->region.position.x = 0;
- spa_meta_video_crop->region.position.y = 0;
- spa_meta_video_crop->region.size.width = priv->stream_width;
- spa_meta_video_crop->region.size.height = priv->stream_height;
+ if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
+ {
+ spa_meta_video_crop->region.position.x = crop_rect.x;
+ spa_meta_video_crop->region.position.y = crop_rect.y;
+ spa_meta_video_crop->region.size.width = crop_rect.width;
+ spa_meta_video_crop->region.size.height = crop_rect.height;
+ }
+ else
+ {
+ spa_meta_video_crop->region.position.x = 0;
+ spa_meta_video_crop->region.position.y = 0;
+ spa_meta_video_crop->region.size.width = priv->stream_width;
+ spa_meta_video_crop->region.size.height = priv->stream_height;
+ }
}
}
+ else
+ {
+ spa_buffer->datas[0].chunk->size = 0;
+ }
}
else
{
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
index 6c73d05..87054ee 100644
--- a/src/backends/meta-screen-cast-stream-src.h
+++ b/src/backends/meta-screen-cast-stream-src.h
@@ -40,6 +40,7 @@ typedef struct _MetaScreenCastStream MetaScreenCastStream;
typedef enum _MetaScreenCastRecordFlag
{
META_SCREEN_CAST_RECORD_FLAG_NONE = 0,
+ META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY = 1 << 0,
} MetaScreenCastRecordFlag;
#define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ())
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
index b321733..dfc5baa 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -329,7 +329,7 @@ screen_cast_window_damaged (MetaWindowActor *actor,
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
MetaScreenCastRecordFlag flags;
- flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
@@ -375,7 +375,7 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
if (meta_screen_cast_window_has_damage (window_src->screen_cast_window))
return;
- flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 16:48:52 +0200
Subject: screen-cast/src: Add flag to maybe_record()
Will later be used to make recording avoid recording actual pixel
content if e.g. only the cursor moved.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-monitor-stream-src.c | 8 ++++++--
src/backends/meta-screen-cast-stream-src.c | 3 ++-
src/backends/meta-screen-cast-stream-src.h | 8 +++++++-
src/backends/meta-screen-cast-window-stream-src.c | 12 +++++++++---
4 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
index 4b72416..70edb22 100644
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
@@ -121,8 +121,10 @@ stage_painted (MetaStage *stage,
gpointer user_data)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
+ MetaScreenCastRecordFlag flags;
- meta_screen_cast_stream_src_maybe_record_frame (src);
+ flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static MetaBackend *
@@ -181,6 +183,7 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
ClutterStage *stage = get_stage (monitor_src);
+ MetaScreenCastRecordFlag flags;
if (!is_cursor_in_stream (monitor_src))
return;
@@ -188,7 +191,8 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
if (clutter_stage_is_redraw_queued (stage))
return;
- meta_screen_cast_stream_src_maybe_record_frame (src);
+ flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 2454f93..7f124bf 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -437,7 +437,8 @@ do_record_frame (MetaScreenCastStreamSrc *src,
}
void
-meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
+meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
+ MetaScreenCastRecordFlag flags)
{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
index 0eda02f..6c73d05 100644
--- a/src/backends/meta-screen-cast-stream-src.h
+++ b/src/backends/meta-screen-cast-stream-src.h
@@ -37,6 +37,11 @@
typedef struct _MetaScreenCastStream MetaScreenCastStream;
+typedef enum _MetaScreenCastRecordFlag
+{
+ META_SCREEN_CAST_RECORD_FLAG_NONE = 0,
+} MetaScreenCastRecordFlag;
+
#define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStreamSrc,
meta_screen_cast_stream_src,
@@ -63,7 +68,8 @@ struct _MetaScreenCastStreamSrcClass
struct spa_meta_cursor *spa_meta_cursor);
};
-void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src);
+void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
+ MetaScreenCastRecordFlag flags);
MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src);
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
index 3f141d2..b321733 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -327,8 +327,10 @@ screen_cast_window_damaged (MetaWindowActor *actor,
MetaScreenCastWindowStreamSrc *window_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
+ MetaScreenCastRecordFlag flags;
- meta_screen_cast_stream_src_maybe_record_frame (src);
+ flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
@@ -365,6 +367,7 @@ static void
sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
{
MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
+ MetaScreenCastRecordFlag flags;
if (!is_cursor_in_stream (window_src))
return;
@@ -372,7 +375,8 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
if (meta_screen_cast_window_has_damage (window_src->screen_cast_window))
return;
- meta_screen_cast_stream_src_maybe_record_frame (src);
+ flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
@@ -401,6 +405,7 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
MetaWindowActor *window_actor;
MetaScreenCastStream *stream;
+ MetaScreenCastRecordFlag flags;
window_actor = meta_window_actor_from_window (get_window (window_src));
if (!window_actor)
@@ -438,7 +443,8 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
break;
}
- meta_screen_cast_stream_src_maybe_record_frame (src);
+ flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
static void
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 23:50:28 +0200
Subject: screen-cast/src: Fix signedness of timestamp field
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-stream-src.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 4b79119..9921681 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -91,7 +91,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
struct spa_video_info_raw video_format;
int video_stride;
- uint64_t last_frame_timestamp_us;
+ int64_t last_frame_timestamp_us;
GHashTable *dmabuf_handles;
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 16:57:01 +0200
Subject: screen-cast/src: Make record functions return an error when failing
Now that we don't use the record function to early out depending on
implicit state (don't record pixels if only cursor moved for example),
let it simply report an error when it fails, as we should no longer ever
return without pixels if nothing failed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-monitor-stream-src.c | 19 ++++++-------
src/backends/meta-screen-cast-stream-src.c | 32 ++++++++++++++--------
src/backends/meta-screen-cast-stream-src.h | 10 ++++---
src/backends/meta-screen-cast-window-stream-src.c | 16 +++++++----
4 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
index 17aa7ae..570f16b 100644
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
@@ -366,8 +366,9 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
}
static gboolean
-meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
- uint8_t *data)
+meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
+ uint8_t *data,
+ GError **error)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
@@ -384,8 +385,9 @@ meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *s
}
static gboolean
-meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer)
+meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer,
+ GError **error)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
@@ -409,7 +411,6 @@ meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamS
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
ClutterStageView *view = CLUTTER_STAGE_VIEW (l->data);
- g_autoptr (GError) error = NULL;
CoglFramebuffer *view_framebuffer;
MetaRectangle view_layout;
int x, y;
@@ -430,12 +431,8 @@ meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamS
x, y,
cogl_framebuffer_get_width (view_framebuffer),
cogl_framebuffer_get_height (view_framebuffer),
- &error))
- {
- g_warning ("Error blitting view into DMABuf framebuffer: %s",
- error->message);
- return FALSE;
- }
+ error))
+ return FALSE;
}
cogl_framebuffer_finish (framebuffer);
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 463d316..4b79119 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -135,23 +135,25 @@ meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src,
}
static gboolean
-meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
- uint8_t *data)
+meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
+ uint8_t *data,
+ GError **error)
{
MetaScreenCastStreamSrcClass *klass =
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
- return klass->record_to_buffer (src, data);
+ return klass->record_to_buffer (src, data, error);
}
static gboolean
-meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer)
+meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer,
+ GError **error)
{
MetaScreenCastStreamSrcClass *klass =
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
- return klass->record_to_framebuffer (src, framebuffer);
+ return klass->record_to_framebuffer (src, framebuffer, error);
}
static void
@@ -409,9 +411,10 @@ maybe_record_cursor (MetaScreenCastStreamSrc *src,
}
static gboolean
-do_record_frame (MetaScreenCastStreamSrc *src,
- struct spa_buffer *spa_buffer,
- uint8_t *data)
+do_record_frame (MetaScreenCastStreamSrc *src,
+ struct spa_buffer *spa_buffer,
+ uint8_t *data,
+ GError **error)
{
MetaScreenCastStreamSrcPrivate *priv =
meta_screen_cast_stream_src_get_instance_private (src);
@@ -419,7 +422,7 @@ do_record_frame (MetaScreenCastStreamSrc *src,
if (spa_buffer->datas[0].data ||
spa_buffer->datas[0].type == SPA_DATA_MemFd)
{
- return meta_screen_cast_stream_src_record_to_buffer (src, data);
+ return meta_screen_cast_stream_src_record_to_buffer (src, data, error);
}
else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf)
{
@@ -430,9 +433,12 @@ do_record_frame (MetaScreenCastStreamSrc *src,
cogl_dma_buf_handle_get_framebuffer (dmabuf_handle);
return meta_screen_cast_stream_src_record_to_framebuffer (src,
- dmabuf_fbo);
+ dmabuf_fbo,
+ error);
}
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Unknown SPA buffer type %u", spa_buffer->datas[0].type);
return FALSE;
}
@@ -447,6 +453,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
struct spa_buffer *spa_buffer;
uint8_t *data = NULL;
uint64_t now_us;
+ g_autoptr (GError) error = NULL;
now_us = g_get_monotonic_time ();
if (priv->video_format.max_framerate.num > 0 &&
@@ -474,7 +481,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
{
- if (do_record_frame (src, spa_buffer, data))
+ if (do_record_frame (src, spa_buffer, data, &error))
{
struct spa_meta_region *spa_meta_video_crop;
@@ -505,6 +512,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
}
else
{
+ g_warning ("Failed to record screen cast frame: %s", error->message);
spa_buffer->datas[0].chunk->size = 0;
}
}
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
index 87054ee..152790e 100644
--- a/src/backends/meta-screen-cast-stream-src.h
+++ b/src/backends/meta-screen-cast-stream-src.h
@@ -59,10 +59,12 @@ struct _MetaScreenCastStreamSrcClass
float *frame_rate);
void (* enable) (MetaScreenCastStreamSrc *src);
void (* disable) (MetaScreenCastStreamSrc *src);
- gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src,
- uint8_t *data);
- gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer);
+ gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src,
+ uint8_t *data,
+ GError **error);
+ gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer,
+ GError **error);
gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
MetaRectangle *crop_rect);
void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
index dfc5baa..a504bd1 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -457,8 +457,9 @@ meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src)
}
static gboolean
-meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
- uint8_t *data)
+meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
+ uint8_t *data,
+ GError **error)
{
MetaScreenCastWindowStreamSrc *window_src =
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
@@ -469,8 +470,9 @@ meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *sr
}
static gboolean
-meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer)
+meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer,
+ GError **error)
{
MetaScreenCastWindowStreamSrc *window_src =
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
@@ -485,7 +487,11 @@ meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSr
if (!meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window,
&stream_rect,
framebuffer))
- return FALSE;
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to blit window content to framebuffer");
+ return FALSE;
+ }
stream = meta_screen_cast_stream_src_get_stream (src);
switch (meta_screen_cast_stream_get_cursor_mode (stream))
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 16:42:45 +0200
Subject: screen-cast-src: Make the two record vfuncs more similarly named
Both do more or less the same but with different methods - one puts
pixels into a buffer using the CPU, the other puts pixels into a buffer
using the GPU.
However, they are behaving slightly different, which they shouldn't.
Lets first address the misleading disconnect in naming, and later we'll
make them behave more similarly.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-monitor-stream-src.c | 15 ++++++++-------
src/backends/meta-screen-cast-stream-src.c | 17 +++++++++--------
src/backends/meta-screen-cast-stream-src.h | 8 ++++----
src/backends/meta-screen-cast-window-stream-src.c | 15 ++++++++-------
4 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
index 9d1d212..4b72416 100644
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
@@ -362,8 +362,8 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
}
static gboolean
-meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
- uint8_t *data)
+meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
+ uint8_t *data)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
@@ -383,8 +383,8 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
}
static gboolean
-meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer)
+meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer)
{
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
@@ -562,9 +562,10 @@ meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcCl
src_class->get_specs = meta_screen_cast_monitor_stream_src_get_specs;
src_class->enable = meta_screen_cast_monitor_stream_src_enable;
src_class->disable = meta_screen_cast_monitor_stream_src_disable;
- src_class->record_frame = meta_screen_cast_monitor_stream_src_record_frame;
- src_class->blit_to_framebuffer =
- meta_screen_cast_monitor_stream_src_blit_to_framebuffer;
+ src_class->record_to_buffer =
+ meta_screen_cast_monitor_stream_src_record_to_buffer;
+ src_class->record_to_framebuffer =
+ meta_screen_cast_monitor_stream_src_record_to_framebuffer;
src_class->set_cursor_metadata =
meta_screen_cast_monitor_stream_src_set_cursor_metadata;
}
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 5ec3c04..2454f93 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -135,23 +135,23 @@ meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src,
}
static gboolean
-meta_screen_cast_stream_src_record_frame (MetaScreenCastStreamSrc *src,
- uint8_t *data)
+meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
+ uint8_t *data)
{
MetaScreenCastStreamSrcClass *klass =
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
- return klass->record_frame (src, data);
+ return klass->record_to_buffer (src, data);
}
static gboolean
-meta_screen_cast_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer)
+meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer)
{
MetaScreenCastStreamSrcClass *klass =
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
- return klass->blit_to_framebuffer (src, framebuffer);
+ return klass->record_to_framebuffer (src, framebuffer);
}
static void
@@ -419,7 +419,7 @@ do_record_frame (MetaScreenCastStreamSrc *src,
if (spa_buffer->datas[0].data ||
spa_buffer->datas[0].type == SPA_DATA_MemFd)
{
- return meta_screen_cast_stream_src_record_frame (src, data);
+ return meta_screen_cast_stream_src_record_to_buffer (src, data);
}
else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf)
{
@@ -429,7 +429,8 @@ do_record_frame (MetaScreenCastStreamSrc *src,
CoglFramebuffer *dmabuf_fbo =
cogl_dma_buf_handle_get_framebuffer (dmabuf_handle);
- return meta_screen_cast_stream_src_blit_to_framebuffer (src, dmabuf_fbo);
+ return meta_screen_cast_stream_src_record_to_framebuffer (src,
+ dmabuf_fbo);
}
return FALSE;
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
index 3f6a1af..0eda02f 100644
--- a/src/backends/meta-screen-cast-stream-src.h
+++ b/src/backends/meta-screen-cast-stream-src.h
@@ -53,10 +53,10 @@ struct _MetaScreenCastStreamSrcClass
float *frame_rate);
void (* enable) (MetaScreenCastStreamSrc *src);
void (* disable) (MetaScreenCastStreamSrc *src);
- gboolean (* record_frame) (MetaScreenCastStreamSrc *src,
- uint8_t *data);
- gboolean (* blit_to_framebuffer) (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer);
+ gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src,
+ uint8_t *data);
+ gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer);
gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
MetaRectangle *crop_rect);
void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
index b1221ad..5d1bfde 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -451,8 +451,8 @@ meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src)
}
static gboolean
-meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
- uint8_t *data)
+meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
+ uint8_t *data)
{
MetaScreenCastWindowStreamSrc *window_src =
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
@@ -463,8 +463,8 @@ meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
}
static gboolean
-meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
- CoglFramebuffer *framebuffer)
+meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
+ CoglFramebuffer *framebuffer)
{
MetaScreenCastWindowStreamSrc *window_src =
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
@@ -580,9 +580,10 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
src_class->get_specs = meta_screen_cast_window_stream_src_get_specs;
src_class->enable = meta_screen_cast_window_stream_src_enable;
src_class->disable = meta_screen_cast_window_stream_src_disable;
- src_class->record_frame = meta_screen_cast_window_stream_src_record_frame;
- src_class->blit_to_framebuffer =
- meta_screen_cast_window_stream_src_blit_to_framebuffer;
+ src_class->record_to_buffer =
+ meta_screen_cast_window_stream_src_record_to_buffer;
+ src_class->record_to_framebuffer =
+ meta_screen_cast_window_stream_src_record_to_framebuffer;
src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
}
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 23:57:31 +0200
Subject: screen-cast/src: Record follow up frame after timeout
During animation or other things that cause multiple frames in a row
being painted, we might skip recording frames if the max framerate is
reached.
Doing so means we might end up skipping the last frame in a series,
ending with the last frame we sent was not the last one, making things
appear to get stuck sometimes.
Handle this by creating a timeout if we ever throttle, and at the time
the timeout callback is triggered, make sure we eventually send an up to
date frame.
This is handle differently depending on the source type. A monitor
source type reports 1x1 pixel damage on each view its monitor overlaps,
while a window source type simply records a frame from the surface
directly, except without recording a timestamp, so that timestamps
always refer to when damage actually happened.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-monitor-stream-src.c | 43 ++++++++++++
src/backends/meta-screen-cast-stream-src.c | 77 ++++++++++++++++++++--
src/backends/meta-screen-cast-stream-src.h | 4 ++
src/backends/meta-screen-cast-window-stream-src.c | 11 ++++
4 files changed, 130 insertions(+), 5 deletions(-)
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
index 570f16b..c902e98 100644
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
@@ -191,6 +191,9 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
if (clutter_stage_is_redraw_queued (stage))
return;
+ if (meta_screen_cast_stream_src_pending_follow_up_frame (src))
+ return;
+
flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
meta_screen_cast_stream_src_maybe_record_frame (src, flags);
}
@@ -440,6 +443,44 @@ meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamS
return TRUE;
}
+static void
+meta_screen_cast_monitor_stream_record_follow_up (MetaScreenCastStreamSrc *src)
+{
+ MetaScreenCastMonitorStreamSrc *monitor_src =
+ META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
+ MetaBackend *backend = get_backend (monitor_src);
+ MetaRenderer *renderer = meta_backend_get_renderer (backend);
+ ClutterStage *stage = get_stage (monitor_src);
+ MetaMonitor *monitor;
+ MetaLogicalMonitor *logical_monitor;
+ MetaRectangle logical_monitor_layout;
+ GList *l;
+
+ monitor = get_monitor (monitor_src);
+ logical_monitor = meta_monitor_get_logical_monitor (monitor);
+ logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor);
+
+ for (l = meta_renderer_get_views (renderer); l; l = l->next)
+ {
+ MetaRendererView *view = l->data;
+ MetaRectangle view_layout;
+ MetaRectangle damage;
+
+ clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
+
+ if (!meta_rectangle_overlap (&logical_monitor_layout, &view_layout))
+ continue;
+
+ damage = (cairo_rectangle_int_t) {
+ .x = view_layout.x,
+ .y = view_layout.y,
+ .width = 1,
+ .height = 1,
+ };
+ clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &damage);
+ }
+}
+
static void
meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor)
@@ -564,6 +605,8 @@ meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcCl
meta_screen_cast_monitor_stream_src_record_to_buffer;
src_class->record_to_framebuffer =
meta_screen_cast_monitor_stream_src_record_to_framebuffer;
+ src_class->record_follow_up =
+ meta_screen_cast_monitor_stream_record_follow_up;
src_class->set_cursor_metadata =
meta_screen_cast_monitor_stream_src_set_cursor_metadata;
}
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 9921681..8412642 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -92,6 +92,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
int video_stride;
int64_t last_frame_timestamp_us;
+ guint follow_up_frame_source_id;
GHashTable *dmabuf_handles;
@@ -109,6 +110,12 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStreamSrc,
meta_screen_cast_stream_src_init_initable_iface)
G_ADD_PRIVATE (MetaScreenCastStreamSrc))
+static inline uint32_t
+us2ms (uint64_t us)
+{
+ return (uint32_t) (us / 1000);
+}
+
static void
meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src,
int *width,
@@ -156,6 +163,15 @@ meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src
return klass->record_to_framebuffer (src, framebuffer, error);
}
+static void
+meta_screen_cast_stream_src_record_follow_up (MetaScreenCastStreamSrc *src)
+{
+ MetaScreenCastStreamSrcClass *klass =
+ META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
+
+ klass->record_follow_up (src);
+}
+
static void
meta_screen_cast_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor)
@@ -442,6 +458,43 @@ do_record_frame (MetaScreenCastStreamSrc *src,
return FALSE;
}
+gboolean
+meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src)
+{
+ MetaScreenCastStreamSrcPrivate *priv =
+ meta_screen_cast_stream_src_get_instance_private (src);
+
+ return priv->follow_up_frame_source_id != 0;
+}
+
+static gboolean
+follow_up_frame_cb (gpointer user_data)
+{
+ MetaScreenCastStreamSrc *src = user_data;
+ MetaScreenCastStreamSrcPrivate *priv =
+ meta_screen_cast_stream_src_get_instance_private (src);
+
+ priv->follow_up_frame_source_id = 0;
+ meta_screen_cast_stream_src_record_follow_up (src);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+maybe_schedule_follow_up_frame (MetaScreenCastStreamSrc *src,
+ int64_t timeout_us)
+{
+ MetaScreenCastStreamSrcPrivate *priv =
+ meta_screen_cast_stream_src_get_instance_private (src);
+
+ if (priv->follow_up_frame_source_id)
+ return;
+
+ priv->follow_up_frame_source_id = g_timeout_add (us2ms (timeout_us),
+ follow_up_frame_cb,
+ src);
+}
+
void
meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
MetaScreenCastRecordFlag flags)
@@ -457,11 +510,24 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
now_us = g_get_monotonic_time ();
if (priv->video_format.max_framerate.num > 0 &&
- priv->last_frame_timestamp_us != 0 &&
- (now_us - priv->last_frame_timestamp_us <
- ((1000000 * priv->video_format.max_framerate.denom) /
- priv->video_format.max_framerate.num)))
- return;
+ priv->last_frame_timestamp_us != 0)
+ {
+ int64_t min_interval_us;
+ int64_t time_since_last_frame_us;
+
+ min_interval_us = ((1000000 * priv->video_format.max_framerate.denom) /
+ priv->video_format.max_framerate.num);
+
+ time_since_last_frame_us = now_us - priv->last_frame_timestamp_us;
+ if (time_since_last_frame_us < min_interval_us)
+ {
+ int64_t timeout_us;
+
+ timeout_us = min_interval_us - time_since_last_frame_us;
+ maybe_schedule_follow_up_frame (src, timeout_us);
+ return;
+ }
+ }
if (!priv->pipewire_stream)
return;
@@ -481,6 +547,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
{
+ g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
if (do_record_frame (src, spa_buffer, data, &error))
{
struct spa_meta_region *spa_meta_video_crop;
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
index 152790e..81ea20b 100644
--- a/src/backends/meta-screen-cast-stream-src.h
+++ b/src/backends/meta-screen-cast-stream-src.h
@@ -65,6 +65,8 @@ struct _MetaScreenCastStreamSrcClass
gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
CoglFramebuffer *framebuffer,
GError **error);
+ void (* record_follow_up) (MetaScreenCastStreamSrc *src);
+
gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
MetaRectangle *crop_rect);
void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
@@ -74,6 +76,8 @@ struct _MetaScreenCastStreamSrcClass
void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
MetaScreenCastRecordFlag flags);
+gboolean meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src);
+
MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src);
gboolean meta_screen_cast_stream_src_draw_cursor_into (MetaScreenCastStreamSrc *src,
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
index a504bd1..e80cd5e 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -509,6 +509,15 @@ meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSr
return TRUE;
}
+static void
+meta_screen_cast_window_stream_record_follow_up (MetaScreenCastStreamSrc *src)
+{
+ MetaScreenCastRecordFlag flags;
+
+ flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
+ meta_screen_cast_stream_src_maybe_record_frame (src, flags);
+}
+
static void
meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
struct spa_meta_cursor *spa_meta_cursor)
@@ -596,6 +605,8 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
meta_screen_cast_window_stream_src_record_to_buffer;
src_class->record_to_framebuffer =
meta_screen_cast_window_stream_src_record_to_framebuffer;
+ src_class->record_follow_up =
+ meta_screen_cast_window_stream_record_follow_up;
src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
}
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 10 Jul 2020 07:06:33 +0000
Subject: screen-cast/src: Remove follow up timeout source on disable
We failed to remove the timeout source when disabling, meaning that if a
follow up was scheduled, and shortly after we disabled the source, the
timeout would be invoked after the source was freed causing
use-after-free bugs.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1337
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1365
(cherry picked from commit d67ba3ea65717ceab3e0c91267191c6ed2aac2c2)
Origin: https://gitlab.gnome.org/GNOME/mutter/-/commit/1fd53c480f9bb5
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1337
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-stream-src.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 070c67a..fce2b84 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -624,6 +624,8 @@ meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src)
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->disable (src);
+ g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
+
priv->is_enabled = FALSE;
}
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 8 Jul 2020 15:08:23 +0200
Subject: screen-cast/src: Use G_USEC_PER_SEC instead of 1000000
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-stream-src.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index 8412642..070c67a 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -515,8 +515,9 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src,
int64_t min_interval_us;
int64_t time_since_last_frame_us;
- min_interval_us = ((1000000 * priv->video_format.max_framerate.denom) /
- priv->video_format.max_framerate.num);
+ min_interval_us =
+ ((G_USEC_PER_SEC * priv->video_format.max_framerate.denom) /
+ priv->video_format.max_framerate.num);
time_since_last_frame_us = now_us - priv->last_frame_timestamp_us;
if (time_since_last_frame_us < min_interval_us)
From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
Date: Fri, 3 Jul 2020 16:46:44 +0200
Subject: screen-cast/window-stream-src: Fix indentation
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Origin: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
Bug-GNOME: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
Applied-Upstream: 3.36.5
---
src/backends/meta-screen-cast-window-stream-src.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
index 5d1bfde..3f141d2 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -477,8 +477,8 @@ meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSr
stream_rect.height = get_stream_height (window_src);
if (!meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window,
- &stream_rect,
- framebuffer))
+ &stream_rect,
+ framebuffer))
return FALSE;
stream = meta_screen_cast_stream_src_get_stream (src);
screen-cast-src-Make-the-two-record-vfuncs-more-similarly.patch
screen-cast-window-stream-src-Fix-indentation.patch
screen-cast-src-Add-flag-to-maybe_record.patch
screen-cast-Let-the-reason-for-recording-determine-what-t.patch
screen-cast-src-Make-record-functions-return-an-error-whe.patch
screen-cast-src-Fix-signedness-of-timestamp-field.patch
screen-cast-src-Record-follow-up-frame-after-timeout.patch
screen-cast-src-Use-G_USEC_PER_SEC-instead-of-1000000.patch
screen-cast-src-Remove-follow-up-timeout-source-on-disabl.patch
theme-use-gtk_render_icon_suface-to-paint-button-icon.patch
theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch
meson-add-back-default_driver-option.patch
......
......@@ -13,7 +13,7 @@ Forwarded: No, forwarding is in progress and planned though
data/org.gnome.mutter.x11.gschema.xml.in | 30 ++
src/backends/meta-crtc.h | 1 +
src/backends/meta-monitor-config-manager.c | 180 +++++++-
src/backends/meta-monitor-config-manager.h | 6 +
src/backends/meta-monitor-config-manager.h | 5 +
src/backends/meta-monitor-config-migration.c | 15 +-
src/backends/meta-monitor-config-store.c | 17 +
src/backends/meta-monitor-manager-dummy.c | 24 +-
......@@ -31,13 +31,13 @@ Forwarded: No, forwarding is in progress and planned though
src/backends/x11/meta-monitor-manager-xrandr.c | 564 +++++++++++++++++++------
src/backends/x11/meta-monitor-manager-xrandr.h | 4 +-
src/backends/x11/meta-output-xrandr.c | 5 +-
src/compositor/meta-compositor-x11.c | 98 +++-
src/compositor/meta-compositor-x11.c | 98 ++++-
src/core/boxes-private.h | 4 +
src/core/boxes.c | 21 +
src/core/window.c | 19 +
src/org.gnome.Mutter.DisplayConfig.xml | 5 +
src/tests/meta-monitor-manager-test.c | 13 +-
29 files changed, 1772 insertions(+), 271 deletions(-)
29 files changed, 1771 insertions(+), 271 deletions(-)
create mode 100644 data/org.gnome.mutter.x11.gschema.xml.in
diff --git a/data/meson.build b/data/meson.build
......@@ -501,14 +501,13 @@ index 6a7c807..d8646fa 100644
expected_mode_width = roundf (expected_mode_width *
logical_monitor_config->scale);
diff --git a/src/backends/meta-monitor-config-manager.h b/src/backends/meta-monitor-config-manager.h
index 3875e04..6941cb7 100644
index 3875e04..c337a34 100644
--- a/src/backends/meta-monitor-config-manager.h
+++ b/src/backends/meta-monitor-config-manager.h
@@ -110,6 +110,11 @@ MetaMonitorsConfig * meta_monitor_config_manager_create_for_orientation (MetaMon
@@ -110,6 +110,10 @@ MetaMonitorsConfig * meta_monitor_config_manager_create_for_orientation (MetaMon
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_create_for_rotate_monitor (MetaMonitorConfigManager *config_manager);
+META_EXPORT_TEST
+MetaMonitorsConfig * meta_monitor_config_manager_create_for_layout (MetaMonitorConfigManager *config_manager,
+ MetaMonitorsConfig *config,
+ MetaLogicalMonitorLayoutMode layout_mode);
......@@ -516,7 +515,7 @@ index 3875e04..6941cb7 100644
META_EXPORT_TEST
MetaMonitorsConfig * meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager *config_manager,
MetaMonitorSwitchConfigType config_type);
@@ -191,6 +196,7 @@ META_EXPORT_TEST
@@ -191,6 +195,7 @@ META_EXPORT_TEST
gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
MetaLogicalMonitorLayoutMode layout_mode,
MetaMonitorManager *monitor_manager,
......
project('mutter', 'c',
version: '3.36.3',
version: '3.36.4',
meson_version: '>= 0.50.0',
license: 'GPLv2+'
)
......
......@@ -273,14 +273,6 @@ meta_remote_desktop_session_check_can_notify (MetaRemoteDesktopSession *session,
return FALSE;
}
if (!session->screen_cast_session)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"No screen cast active");
return FALSE;
}
return TRUE;
}
......@@ -591,6 +583,15 @@ handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton,
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
return TRUE;
if (!session->screen_cast_session)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"No screen cast active");
return TRUE;
}
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
stream_path);
if (!stream)
......@@ -628,6 +629,14 @@ handle_notify_touch_down (MetaDBusRemoteDesktopSession *skeleton,
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
return TRUE;
if (!session->screen_cast_session)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"No screen cast active");
return TRUE;
}
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
stream_path);
if (!stream)
......@@ -666,6 +675,15 @@ handle_notify_touch_motion (MetaDBusRemoteDesktopSession *skeleton,
if (!meta_remote_desktop_session_check_can_notify (session, invocation))
return TRUE;
if (!session->screen_cast_session)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED,
"No screen cast active");
return TRUE;
}
stream = meta_screen_cast_session_get_stream (session->screen_cast_session,
stream_path);
if (!stream)
......
......@@ -232,14 +232,28 @@ meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
uint64_t state,
MetaKmsUpdate *kms_update)
{
MetaGpu *gpu = META_GPU (gpu_kms);
GList *l;
for (l = meta_gpu_get_outputs (META_GPU (gpu_kms)); l; l = l->next)
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
{
MetaOutput *output = l->data;
meta_output_kms_set_power_save_mode (output, state, kms_update);
}
if (state != META_POWER_SAVE_ON)
{
/* Turn off CRTCs for DPMS */
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
{
MetaCrtc *crtc = META_CRTC (l->data);
meta_kms_update_mode_set (kms_update,
meta_crtc_kms_get_kms_crtc (crtc),
NULL, NULL);
}
}
}
gboolean
......