kathenas / rpms / mutter

Forked from rpms/mutter 5 years ago
Clone

Blame SOURCES/cursor-move-only-screen-cast-fixes.patch

99364f
From 30caca0cb389dcbbab3d7ba72b92fce8e243b30b Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 3 Jul 2020 16:42:45 +0200
99364f
Subject: [PATCH 1/9] screen-cast-src: Make the two record vfuncs more
99364f
 similarly named
99364f
99364f
Both do more or less the same but with different methods - one puts
99364f
pixels into a buffer using the CPU, the other puts pixels into a buffer
99364f
using the GPU.
99364f
99364f
However, they are behaving slightly different, which they shouldn't.
99364f
Lets first address the misleading disconnect in naming, and later we'll
99364f
make them behave more similarly.
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit d07335cd4ca094d790eac75e75cff01a28fda827)
99364f
---
99364f
 .../meta-screen-cast-monitor-stream-src.c       | 15 ++++++++-------
99364f
 src/backends/meta-screen-cast-stream-src.c      | 17 +++++++++--------
99364f
 src/backends/meta-screen-cast-stream-src.h      |  8 ++++----
99364f
 .../meta-screen-cast-window-stream-src.c        | 15 ++++++++-------
99364f
 4 files changed, 29 insertions(+), 26 deletions(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
index 655b682610..a1a98eb05b 100644
99364f
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
@@ -347,8 +347,8 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
99364f
-                                                  uint8_t                 *data)
99364f
+meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
99364f
+                                                      uint8_t                 *data)
99364f
 {
99364f
   MetaScreenCastMonitorStreamSrc *monitor_src =
99364f
     META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
99364f
@@ -368,8 +368,8 @@ meta_screen_cast_monitor_stream_src_record_frame (MetaScreenCastStreamSrc *src,
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_monitor_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
-                                                         CoglFramebuffer         *framebuffer)
99364f
+meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
+                                                           CoglFramebuffer         *framebuffer)
99364f
 {
99364f
   MetaScreenCastMonitorStreamSrc *monitor_src =
99364f
     META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
99364f
@@ -551,9 +551,10 @@ meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcCl
99364f
   src_class->get_specs = meta_screen_cast_monitor_stream_src_get_specs;
99364f
   src_class->enable = meta_screen_cast_monitor_stream_src_enable;
99364f
   src_class->disable = meta_screen_cast_monitor_stream_src_disable;
99364f
-  src_class->record_frame = meta_screen_cast_monitor_stream_src_record_frame;
99364f
-  src_class->blit_to_framebuffer =
99364f
-    meta_screen_cast_monitor_stream_src_blit_to_framebuffer;
99364f
+  src_class->record_to_buffer =
99364f
+    meta_screen_cast_monitor_stream_src_record_to_buffer;
99364f
+  src_class->record_to_framebuffer =
99364f
+    meta_screen_cast_monitor_stream_src_record_to_framebuffer;
99364f
   src_class->set_cursor_metadata =
99364f
     meta_screen_cast_monitor_stream_src_set_cursor_metadata;
99364f
 }
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index b77186415f..bafb82388d 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -133,23 +133,23 @@ meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src,
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_stream_src_record_frame (MetaScreenCastStreamSrc *src,
99364f
-                                          uint8_t                 *data)
99364f
+meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
99364f
+                                              uint8_t                 *data)
99364f
 {
99364f
   MetaScreenCastStreamSrcClass *klass =
99364f
     META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
99364f
 
99364f
-  return klass->record_frame (src, data);
99364f
+  return klass->record_to_buffer (src, data);
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
-                                                 CoglFramebuffer         *framebuffer)
99364f
+meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
+                                                   CoglFramebuffer         *framebuffer)
99364f
 {
99364f
   MetaScreenCastStreamSrcClass *klass =
99364f
     META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
99364f
 
99364f
-  return klass->blit_to_framebuffer (src, framebuffer);
99364f
+  return klass->record_to_framebuffer (src, framebuffer);
99364f
 }
99364f
 
99364f
 static void
99364f
@@ -417,7 +417,7 @@ do_record_frame (MetaScreenCastStreamSrc *src,
99364f
   if (spa_buffer->datas[0].data ||
99364f
       spa_buffer->datas[0].type == SPA_DATA_MemFd)
99364f
     {
99364f
-      return meta_screen_cast_stream_src_record_frame (src, data);
99364f
+      return meta_screen_cast_stream_src_record_to_buffer (src, data);
99364f
     }
99364f
   else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf)
99364f
     {
99364f
@@ -427,7 +427,8 @@ do_record_frame (MetaScreenCastStreamSrc *src,
99364f
       CoglFramebuffer *dmabuf_fbo =
99364f
         cogl_dma_buf_handle_get_framebuffer (dmabuf_handle);
99364f
 
99364f
-      return meta_screen_cast_stream_src_blit_to_framebuffer (src, dmabuf_fbo);
99364f
+      return meta_screen_cast_stream_src_record_to_framebuffer (src,
99364f
+                                                                dmabuf_fbo);
99364f
     }
99364f
 
99364f
   return FALSE;
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
99364f
index 3f6a1af2bb..0eda02f717 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.h
99364f
+++ b/src/backends/meta-screen-cast-stream-src.h
99364f
@@ -53,10 +53,10 @@ struct _MetaScreenCastStreamSrcClass
99364f
                       float                   *frame_rate);
99364f
   void (* enable) (MetaScreenCastStreamSrc *src);
99364f
   void (* disable) (MetaScreenCastStreamSrc *src);
99364f
-  gboolean (* record_frame) (MetaScreenCastStreamSrc *src,
99364f
-                             uint8_t                 *data);
99364f
-  gboolean (* blit_to_framebuffer) (MetaScreenCastStreamSrc *src,
99364f
-                                    CoglFramebuffer         *framebuffer);
99364f
+  gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src,
99364f
+                                 uint8_t                 *data);
99364f
+  gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
99364f
+                                      CoglFramebuffer         *framebuffer);
99364f
   gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
99364f
                               MetaRectangle           *crop_rect);
99364f
   void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
99364f
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
99364f
index c252b4356b..281df5e7b2 100644
99364f
--- a/src/backends/meta-screen-cast-window-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-window-stream-src.c
99364f
@@ -462,8 +462,8 @@ meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src)
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
99364f
-                                                 uint8_t                 *data)
99364f
+meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
99364f
+                                                     uint8_t                 *data)
99364f
 {
99364f
   MetaScreenCastWindowStreamSrc *window_src =
99364f
     META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
99364f
@@ -474,8 +474,8 @@ meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
-                                                        CoglFramebuffer         *framebuffer)
99364f
+meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
+                                                          CoglFramebuffer         *framebuffer)
99364f
 {
99364f
   MetaScreenCastWindowStreamSrc *window_src =
99364f
     META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
99364f
@@ -591,9 +591,10 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
99364f
   src_class->get_specs = meta_screen_cast_window_stream_src_get_specs;
99364f
   src_class->enable = meta_screen_cast_window_stream_src_enable;
99364f
   src_class->disable = meta_screen_cast_window_stream_src_disable;
99364f
-  src_class->record_frame = meta_screen_cast_window_stream_src_record_frame;
99364f
-  src_class->blit_to_framebuffer =
99364f
-    meta_screen_cast_window_stream_src_blit_to_framebuffer;
99364f
+  src_class->record_to_buffer =
99364f
+    meta_screen_cast_window_stream_src_record_to_buffer;
99364f
+  src_class->record_to_framebuffer =
99364f
+    meta_screen_cast_window_stream_src_record_to_framebuffer;
99364f
   src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
99364f
   src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
99364f
 }
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From ddc2094222fb55143922364cd4887cb18f856628 Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 3 Jul 2020 16:46:44 +0200
99364f
Subject: [PATCH 2/9] screen-cast/window-stream-src: Fix indentation
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit b1d45820efc5c9136f12d8a3b97a573a2eede9e7)
99364f
---
99364f
 src/backends/meta-screen-cast-window-stream-src.c | 4 ++--
99364f
 1 file changed, 2 insertions(+), 2 deletions(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
99364f
index 281df5e7b2..abdc791575 100644
99364f
--- a/src/backends/meta-screen-cast-window-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-window-stream-src.c
99364f
@@ -488,8 +488,8 @@ meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSr
99364f
   stream_rect.height = get_stream_height (window_src);
99364f
 
99364f
   if (!meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window,
99364f
-                                                     &stream_rect,
99364f
-                                                     framebuffer))
99364f
+                                                    &stream_rect,
99364f
+                                                    framebuffer))
99364f
     return FALSE;
99364f
 
99364f
   stream = meta_screen_cast_stream_src_get_stream (src);
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From 59382848840aeb5c6491412742f474a3fb61639e Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 3 Jul 2020 16:48:52 +0200
99364f
Subject: [PATCH 3/9] screen-cast/src: Add flag to maybe_record()
99364f
99364f
Will later be used to make recording avoid recording actual pixel
99364f
content if e.g. only the cursor moved.
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit 92db8902d9c3229a13d104bba71dd74f14d6dfac)
99364f
---
99364f
 src/backends/meta-screen-cast-monitor-stream-src.c |  8 ++++++--
99364f
 src/backends/meta-screen-cast-stream-src.c         |  3 ++-
99364f
 src/backends/meta-screen-cast-stream-src.h         |  8 +++++++-
99364f
 src/backends/meta-screen-cast-window-stream-src.c  | 12 +++++++++---
99364f
 4 files changed, 24 insertions(+), 7 deletions(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
index a1a98eb05b..8d57fafc0f 100644
99364f
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
@@ -120,8 +120,10 @@ stage_painted (MetaStage        *stage,
99364f
                gpointer          user_data)
99364f
 {
99364f
   MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (user_data);
99364f
+  MetaScreenCastRecordFlag flags;
99364f
 
99364f
-  meta_screen_cast_stream_src_maybe_record_frame (src);
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
 static MetaBackend *
99364f
@@ -180,6 +182,7 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
99364f
 {
99364f
   MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (monitor_src);
99364f
   ClutterStage *stage = get_stage (monitor_src);
99364f
+  MetaScreenCastRecordFlag flags;
99364f
 
99364f
   if (!is_cursor_in_stream (monitor_src))
99364f
     return;
99364f
@@ -187,7 +190,8 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
99364f
   if (clutter_stage_is_redraw_queued (stage))
99364f
     return;
99364f
 
99364f
-  meta_screen_cast_stream_src_maybe_record_frame (src);
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
 static void
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index bafb82388d..303c030be7 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -435,7 +435,8 @@ do_record_frame (MetaScreenCastStreamSrc *src,
99364f
 }
99364f
 
99364f
 void
99364f
-meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src)
99364f
+meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
+                                                MetaScreenCastRecordFlag  flags)
99364f
 {
99364f
   MetaScreenCastStreamSrcPrivate *priv =
99364f
     meta_screen_cast_stream_src_get_instance_private (src);
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
99364f
index 0eda02f717..6c73d05c1d 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.h
99364f
+++ b/src/backends/meta-screen-cast-stream-src.h
99364f
@@ -37,6 +37,11 @@
99364f
 
99364f
 typedef struct _MetaScreenCastStream MetaScreenCastStream;
99364f
 
99364f
+typedef enum _MetaScreenCastRecordFlag
99364f
+{
99364f
+  META_SCREEN_CAST_RECORD_FLAG_NONE = 0,
99364f
+} MetaScreenCastRecordFlag;
99364f
+
99364f
 #define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ())
99364f
 G_DECLARE_DERIVABLE_TYPE (MetaScreenCastStreamSrc,
99364f
                           meta_screen_cast_stream_src,
99364f
@@ -63,7 +68,8 @@ struct _MetaScreenCastStreamSrcClass
99364f
                                 struct spa_meta_cursor  *spa_meta_cursor);
99364f
 };
99364f
 
99364f
-void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc *src);
99364f
+void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
+                                                     MetaScreenCastRecordFlag  flags);
99364f
 
99364f
 MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src);
99364f
 
99364f
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
99364f
index abdc791575..f64d00860a 100644
99364f
--- a/src/backends/meta-screen-cast-window-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-window-stream-src.c
99364f
@@ -338,8 +338,10 @@ screen_cast_window_damaged (MetaWindowActor               *actor,
99364f
                             MetaScreenCastWindowStreamSrc *window_src)
99364f
 {
99364f
   MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
99364f
+  MetaScreenCastRecordFlag flags;
99364f
 
99364f
-  meta_screen_cast_stream_src_maybe_record_frame (src);
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
 static void
99364f
@@ -376,6 +378,7 @@ static void
99364f
 sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
99364f
 {
99364f
   MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
99364f
+  MetaScreenCastRecordFlag flags;
99364f
 
99364f
   if (!is_cursor_in_stream (window_src))
99364f
     return;
99364f
@@ -383,7 +386,8 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
99364f
   if (meta_screen_cast_window_has_damage (window_src->screen_cast_window))
99364f
     return;
99364f
 
99364f
-  meta_screen_cast_stream_src_maybe_record_frame (src);
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
 static void
99364f
@@ -412,6 +416,7 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
99364f
   MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
99364f
   MetaWindowActor *window_actor;
99364f
   MetaScreenCastStream *stream;
99364f
+  MetaScreenCastRecordFlag flags;
99364f
 
99364f
   window_actor = meta_window_actor_from_window (get_window (window_src));
99364f
   if (!window_actor)
99364f
@@ -449,7 +454,8 @@ meta_screen_cast_window_stream_src_enable (MetaScreenCastStreamSrc *src)
99364f
       break;
99364f
     }
99364f
 
99364f
-  meta_screen_cast_stream_src_maybe_record_frame (src);
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
 static void
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From b8d76f2ded6a0c8b88403d97d4ea2c84993c0263 Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 3 Jul 2020 16:52:43 +0200
99364f
Subject: [PATCH 4/9] screen-cast: Let the reason for recording determine what
99364f
 to record
99364f
99364f
E.g. we'll have pointer movement that, if no painting is already
99364f
scheduled, should only send new cursor metadata without any new pixel
99364f
buffer. When this happens, tell next step to not record the pixels if
99364f
this was the case, instead of having it rediscover this itself.
99364f
99364f
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1323
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit cf88d648822eb6b7d412c08d4038c657d415bfff)
99364f
---
99364f
 .../meta-screen-cast-monitor-stream-src.c     |  5 +-
99364f
 src/backends/meta-screen-cast-stream-src.c    | 51 +++++++++++--------
99364f
 src/backends/meta-screen-cast-stream-src.h    |  1 +
99364f
 .../meta-screen-cast-window-stream-src.c      |  4 +-
99364f
 4 files changed, 33 insertions(+), 28 deletions(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
index 8d57fafc0f..2352c3b3d8 100644
99364f
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
@@ -190,7 +190,7 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
99364f
   if (clutter_stage_is_redraw_queued (stage))
99364f
     return;
99364f
 
99364f
-  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
99364f
   meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
@@ -361,9 +361,6 @@ meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *s
99364f
   MetaLogicalMonitor *logical_monitor;
99364f
 
99364f
   stage = get_stage (monitor_src);
99364f
-  if (!clutter_stage_is_redraw_queued (stage))
99364f
-    return FALSE;
99364f
-
99364f
   monitor = get_monitor (monitor_src);
99364f
   logical_monitor = meta_monitor_get_logical_monitor (monitor);
99364f
   clutter_stage_capture_into (stage, FALSE, &logical_monitor->rect, data);
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index 303c030be7..aa4b03b180 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -470,34 +470,41 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
       return;
99364f
     }
99364f
 
99364f
-  if (do_record_frame (src, spa_buffer, data))
99364f
+  if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
99364f
     {
99364f
-      struct spa_meta_region *spa_meta_video_crop;
99364f
+      if (do_record_frame (src, spa_buffer, data))
99364f
+        {
99364f
+          struct spa_meta_region *spa_meta_video_crop;
99364f
 
99364f
-      spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
99364f
-      spa_buffer->datas[0].chunk->stride = priv->video_stride;
99364f
+          spa_buffer->datas[0].chunk->size = spa_buffer->datas[0].maxsize;
99364f
+          spa_buffer->datas[0].chunk->stride = priv->video_stride;
99364f
 
99364f
-      /* Update VideoCrop if needed */
99364f
-      spa_meta_video_crop =
99364f
-        spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
99364f
-                                   sizeof (*spa_meta_video_crop));
99364f
-      if (spa_meta_video_crop)
99364f
-        {
99364f
-          if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
99364f
-            {
99364f
-              spa_meta_video_crop->region.position.x = crop_rect.x;
99364f
-              spa_meta_video_crop->region.position.y = crop_rect.y;
99364f
-              spa_meta_video_crop->region.size.width = crop_rect.width;
99364f
-              spa_meta_video_crop->region.size.height = crop_rect.height;
99364f
-            }
99364f
-          else
99364f
+          /* Update VideoCrop if needed */
99364f
+          spa_meta_video_crop =
99364f
+            spa_buffer_find_meta_data (spa_buffer, SPA_META_VideoCrop,
99364f
+                                       sizeof (*spa_meta_video_crop));
99364f
+          if (spa_meta_video_crop)
99364f
             {
99364f
-              spa_meta_video_crop->region.position.x = 0;
99364f
-              spa_meta_video_crop->region.position.y = 0;
99364f
-              spa_meta_video_crop->region.size.width = priv->stream_width;
99364f
-              spa_meta_video_crop->region.size.height = priv->stream_height;
99364f
+              if (meta_screen_cast_stream_src_get_videocrop (src, &crop_rect))
99364f
+                {
99364f
+                  spa_meta_video_crop->region.position.x = crop_rect.x;
99364f
+                  spa_meta_video_crop->region.position.y = crop_rect.y;
99364f
+                  spa_meta_video_crop->region.size.width = crop_rect.width;
99364f
+                  spa_meta_video_crop->region.size.height = crop_rect.height;
99364f
+                }
99364f
+              else
99364f
+                {
99364f
+                  spa_meta_video_crop->region.position.x = 0;
99364f
+                  spa_meta_video_crop->region.position.y = 0;
99364f
+                  spa_meta_video_crop->region.size.width = priv->stream_width;
99364f
+                  spa_meta_video_crop->region.size.height = priv->stream_height;
99364f
+                }
99364f
             }
99364f
         }
99364f
+      else
99364f
+        {
99364f
+          spa_buffer->datas[0].chunk->size = 0;
99364f
+        }
99364f
     }
99364f
   else
99364f
     {
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
99364f
index 6c73d05c1d..87054eedf5 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.h
99364f
+++ b/src/backends/meta-screen-cast-stream-src.h
99364f
@@ -40,6 +40,7 @@ typedef struct _MetaScreenCastStream MetaScreenCastStream;
99364f
 typedef enum _MetaScreenCastRecordFlag
99364f
 {
99364f
   META_SCREEN_CAST_RECORD_FLAG_NONE = 0,
99364f
+  META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY = 1 << 0,
99364f
 } MetaScreenCastRecordFlag;
99364f
 
99364f
 #define META_TYPE_SCREEN_CAST_STREAM_SRC (meta_screen_cast_stream_src_get_type ())
99364f
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
99364f
index f64d00860a..63c3429df0 100644
99364f
--- a/src/backends/meta-screen-cast-window-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-window-stream-src.c
99364f
@@ -340,7 +340,7 @@ screen_cast_window_damaged (MetaWindowActor               *actor,
99364f
   MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (window_src);
99364f
   MetaScreenCastRecordFlag flags;
99364f
 
99364f
-  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
99364f
   meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
@@ -386,7 +386,7 @@ sync_cursor_state (MetaScreenCastWindowStreamSrc *window_src)
99364f
   if (meta_screen_cast_window_has_damage (window_src->screen_cast_window))
99364f
     return;
99364f
 
99364f
-  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
99364f
   meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
 
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From 5c925cf4de91c9fdd44cb1c13748b2f4d6187dd9 Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 3 Jul 2020 16:57:01 +0200
99364f
Subject: [PATCH 5/9] screen-cast/src: Make record functions return an error
99364f
 when failing
99364f
99364f
Now that we don't use the record function to early out depending on
99364f
implicit state (don't record pixels if only cursor moved for example),
99364f
let it simply report an error when it fails, as we should no longer ever
99364f
return without pixels if nothing failed.
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit 2d899596e21d43ab241d0ba37c0a9f90c2e610be)
99364f
---
99364f
 .../meta-screen-cast-monitor-stream-src.c     | 19 +++++------
99364f
 src/backends/meta-screen-cast-stream-src.c    | 32 ++++++++++++-------
99364f
 src/backends/meta-screen-cast-stream-src.h    | 10 +++---
99364f
 .../meta-screen-cast-window-stream-src.c      | 16 +++++++---
99364f
 4 files changed, 45 insertions(+), 32 deletions(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
index 2352c3b3d8..27b3ea37d8 100644
99364f
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
@@ -351,8 +351,9 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
99364f
-                                                      uint8_t                 *data)
99364f
+meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc  *src,
99364f
+                                                      uint8_t                  *data,
99364f
+                                                      GError                  **error)
99364f
 {
99364f
   MetaScreenCastMonitorStreamSrc *monitor_src =
99364f
     META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
99364f
@@ -369,8 +370,9 @@ meta_screen_cast_monitor_stream_src_record_to_buffer (MetaScreenCastStreamSrc *s
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
-                                                           CoglFramebuffer         *framebuffer)
99364f
+meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc  *src,
99364f
+                                                           CoglFramebuffer          *framebuffer,
99364f
+                                                           GError                  **error)
99364f
 {
99364f
   MetaScreenCastMonitorStreamSrc *monitor_src =
99364f
     META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
99364f
@@ -394,7 +396,6 @@ meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamS
99364f
   for (l = _clutter_stage_peek_stage_views (stage); l; l = l->next)
99364f
     {
99364f
       ClutterStageView *view = CLUTTER_STAGE_VIEW (l->data);
99364f
-      g_autoptr (GError) error = NULL;
99364f
       CoglFramebuffer *view_framebuffer;
99364f
       MetaRectangle view_layout;
99364f
       int x, y;
99364f
@@ -415,12 +416,8 @@ meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamS
99364f
                                   x, y,
99364f
                                   cogl_framebuffer_get_width (view_framebuffer),
99364f
                                   cogl_framebuffer_get_height (view_framebuffer),
99364f
-                                  &error))
99364f
-        {
99364f
-          g_warning ("Error blitting view into DMABuf framebuffer: %s",
99364f
-                     error->message);
99364f
-          return FALSE;
99364f
-        }
99364f
+                                  error))
99364f
+        return FALSE;
99364f
     }
99364f
 
99364f
   cogl_framebuffer_finish (framebuffer);
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index aa4b03b180..b930d5e7c0 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -133,23 +133,25 @@ meta_screen_cast_stream_src_get_videocrop (MetaScreenCastStreamSrc *src,
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
99364f
-                                              uint8_t                 *data)
99364f
+meta_screen_cast_stream_src_record_to_buffer (MetaScreenCastStreamSrc  *src,
99364f
+                                              uint8_t                  *data,
99364f
+                                              GError                  **error)
99364f
 {
99364f
   MetaScreenCastStreamSrcClass *klass =
99364f
     META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
99364f
 
99364f
-  return klass->record_to_buffer (src, data);
99364f
+  return klass->record_to_buffer (src, data, error);
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
-                                                   CoglFramebuffer         *framebuffer)
99364f
+meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc  *src,
99364f
+                                                   CoglFramebuffer          *framebuffer,
99364f
+                                                   GError                  **error)
99364f
 {
99364f
   MetaScreenCastStreamSrcClass *klass =
99364f
     META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
99364f
 
99364f
-  return klass->record_to_framebuffer (src, framebuffer);
99364f
+  return klass->record_to_framebuffer (src, framebuffer, error);
99364f
 }
99364f
 
99364f
 static void
99364f
@@ -407,9 +409,10 @@ maybe_record_cursor (MetaScreenCastStreamSrc *src,
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-do_record_frame (MetaScreenCastStreamSrc *src,
99364f
-                 struct spa_buffer       *spa_buffer,
99364f
-                 uint8_t                 *data)
99364f
+do_record_frame (MetaScreenCastStreamSrc  *src,
99364f
+                 struct spa_buffer        *spa_buffer,
99364f
+                 uint8_t                  *data,
99364f
+                 GError                  **error)
99364f
 {
99364f
   MetaScreenCastStreamSrcPrivate *priv =
99364f
     meta_screen_cast_stream_src_get_instance_private (src);
99364f
@@ -417,7 +420,7 @@ do_record_frame (MetaScreenCastStreamSrc *src,
99364f
   if (spa_buffer->datas[0].data ||
99364f
       spa_buffer->datas[0].type == SPA_DATA_MemFd)
99364f
     {
99364f
-      return meta_screen_cast_stream_src_record_to_buffer (src, data);
99364f
+      return meta_screen_cast_stream_src_record_to_buffer (src, data, error);
99364f
     }
99364f
   else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf)
99364f
     {
99364f
@@ -428,9 +431,12 @@ do_record_frame (MetaScreenCastStreamSrc *src,
99364f
         cogl_dma_buf_handle_get_framebuffer (dmabuf_handle);
99364f
 
99364f
       return meta_screen_cast_stream_src_record_to_framebuffer (src,
99364f
-                                                                dmabuf_fbo);
99364f
+                                                                dmabuf_fbo,
99364f
+                                                                error);
99364f
     }
99364f
 
99364f
+  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
99364f
+               "Unknown SPA buffer type %u", spa_buffer->datas[0].type);
99364f
   return FALSE;
99364f
 }
99364f
 
99364f
@@ -445,6 +451,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
   struct spa_buffer *spa_buffer;
99364f
   uint8_t *data = NULL;
99364f
   uint64_t now_us;
99364f
+  g_autoptr (GError) error = NULL;
99364f
 
99364f
   now_us = g_get_monotonic_time ();
99364f
   if (priv->video_format.max_framerate.num > 0 &&
99364f
@@ -472,7 +479,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
 
99364f
   if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
99364f
     {
99364f
-      if (do_record_frame (src, spa_buffer, data))
99364f
+      if (do_record_frame (src, spa_buffer, data, &error))
99364f
         {
99364f
           struct spa_meta_region *spa_meta_video_crop;
99364f
 
99364f
@@ -503,6 +510,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
         }
99364f
       else
99364f
         {
99364f
+          g_warning ("Failed to record screen cast frame: %s", error->message);
99364f
           spa_buffer->datas[0].chunk->size = 0;
99364f
         }
99364f
     }
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
99364f
index 87054eedf5..152790ecfb 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.h
99364f
+++ b/src/backends/meta-screen-cast-stream-src.h
99364f
@@ -59,10 +59,12 @@ struct _MetaScreenCastStreamSrcClass
99364f
                       float                   *frame_rate);
99364f
   void (* enable) (MetaScreenCastStreamSrc *src);
99364f
   void (* disable) (MetaScreenCastStreamSrc *src);
99364f
-  gboolean (* record_to_buffer) (MetaScreenCastStreamSrc *src,
99364f
-                                 uint8_t                 *data);
99364f
-  gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc *src,
99364f
-                                      CoglFramebuffer         *framebuffer);
99364f
+  gboolean (* record_to_buffer) (MetaScreenCastStreamSrc  *src,
99364f
+                                 uint8_t                  *data,
99364f
+                                 GError                  **error);
99364f
+  gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc  *src,
99364f
+                                      CoglFramebuffer          *framebuffer,
99364f
+                                      GError                  **error);
99364f
   gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
99364f
                               MetaRectangle           *crop_rect);
99364f
   void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
99364f
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
99364f
index 63c3429df0..70e868997e 100644
99364f
--- a/src/backends/meta-screen-cast-window-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-window-stream-src.c
99364f
@@ -468,8 +468,9 @@ meta_screen_cast_window_stream_src_disable (MetaScreenCastStreamSrc *src)
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *src,
99364f
-                                                     uint8_t                 *data)
99364f
+meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc  *src,
99364f
+                                                     uint8_t                  *data,
99364f
+                                                     GError                  **error)
99364f
 {
99364f
   MetaScreenCastWindowStreamSrc *window_src =
99364f
     META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
99364f
@@ -480,8 +481,9 @@ meta_screen_cast_window_stream_src_record_to_buffer (MetaScreenCastStreamSrc *sr
99364f
 }
99364f
 
99364f
 static gboolean
99364f
-meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc *src,
99364f
-                                                          CoglFramebuffer         *framebuffer)
99364f
+meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc  *src,
99364f
+                                                          CoglFramebuffer          *framebuffer,
99364f
+                                                          GError                  **error)
99364f
 {
99364f
   MetaScreenCastWindowStreamSrc *window_src =
99364f
     META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
99364f
@@ -496,7 +498,11 @@ meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSr
99364f
   if (!meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window,
99364f
                                                     &stream_rect,
99364f
                                                     framebuffer))
99364f
-    return FALSE;
99364f
+    {
99364f
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
99364f
+                   "Failed to blit window content to framebuffer");
99364f
+      return FALSE;
99364f
+    }
99364f
 
99364f
   stream = meta_screen_cast_stream_src_get_stream (src);
99364f
   switch (meta_screen_cast_stream_get_cursor_mode (stream))
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From 47b03793413aad449f021f64e66c68ca95be9a0f Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 3 Jul 2020 23:50:28 +0200
99364f
Subject: [PATCH 6/9] screen-cast/src: Fix signedness of timestamp field
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit 449fa7bf81fe0bee63f497d896cbeffe84dca82d)
99364f
---
99364f
 src/backends/meta-screen-cast-stream-src.c | 2 +-
99364f
 1 file changed, 1 insertion(+), 1 deletion(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index b930d5e7c0..f6f66daaa3 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -89,7 +89,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
99364f
   struct spa_video_info_raw video_format;
99364f
   int video_stride;
99364f
 
99364f
-  uint64_t last_frame_timestamp_us;
99364f
+  int64_t last_frame_timestamp_us;
99364f
 
99364f
   GHashTable *dmabuf_handles;
99364f
 
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From d8c8ea23e700f85a55a5cc0b79151fbed75ab191 Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 3 Jul 2020 23:57:31 +0200
99364f
Subject: [PATCH 7/9] screen-cast/src: Record follow up frame after timeout
99364f
99364f
During animation or other things that cause multiple frames in a row
99364f
being painted, we might skip recording frames if the max framerate is
99364f
reached.
99364f
99364f
Doing so means we might end up skipping the last frame in a series,
99364f
ending with the last frame we sent was not the last one, making things
99364f
appear to get stuck sometimes.
99364f
99364f
Handle this by creating a timeout if we ever throttle, and at the time
99364f
the timeout callback is triggered, make sure we eventually send an up to
99364f
date frame.
99364f
99364f
This is handle differently depending on the source type. A monitor
99364f
source type reports 1x1 pixel damage on each view its monitor overlaps,
99364f
while a window source type simply records a frame from the surface
99364f
directly, except without recording a timestamp, so that timestamps
99364f
always refer to when damage actually happened.
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit e8052f169b957a502bf86ca65071582692039b9c)
99364f
---
99364f
 .../meta-screen-cast-monitor-stream-src.c     | 43 +++++++++++
99364f
 src/backends/meta-screen-cast-stream-src.c    | 77 +++++++++++++++++--
99364f
 src/backends/meta-screen-cast-stream-src.h    |  4 +
99364f
 .../meta-screen-cast-window-stream-src.c      | 11 +++
99364f
 4 files changed, 130 insertions(+), 5 deletions(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
index 27b3ea37d8..3079578d8d 100644
99364f
--- a/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-monitor-stream-src.c
99364f
@@ -190,6 +190,9 @@ sync_cursor_state (MetaScreenCastMonitorStreamSrc *monitor_src)
99364f
   if (clutter_stage_is_redraw_queued (stage))
99364f
     return;
99364f
 
99364f
+  if (meta_screen_cast_stream_src_pending_follow_up_frame (src))
99364f
+    return;
99364f
+
99364f
   flags = META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY;
99364f
   meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
 }
99364f
@@ -425,6 +428,44 @@ meta_screen_cast_monitor_stream_src_record_to_framebuffer (MetaScreenCastStreamS
99364f
   return TRUE;
99364f
 }
99364f
 
99364f
+static void
99364f
+meta_screen_cast_monitor_stream_record_follow_up (MetaScreenCastStreamSrc *src)
99364f
+{
99364f
+  MetaScreenCastMonitorStreamSrc *monitor_src =
99364f
+    META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
99364f
+  MetaBackend *backend = get_backend (monitor_src);
99364f
+  MetaRenderer *renderer = meta_backend_get_renderer (backend);
99364f
+  ClutterStage *stage = get_stage (monitor_src);
99364f
+  MetaMonitor *monitor;
99364f
+  MetaLogicalMonitor *logical_monitor;
99364f
+  MetaRectangle logical_monitor_layout;
99364f
+  GList *l;
99364f
+
99364f
+  monitor = get_monitor (monitor_src);
99364f
+  logical_monitor = meta_monitor_get_logical_monitor (monitor);
99364f
+  logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor);
99364f
+
99364f
+  for (l = meta_renderer_get_views (renderer); l; l = l->next)
99364f
+    {
99364f
+      MetaRendererView *view = l->data;
99364f
+      MetaRectangle view_layout;
99364f
+      MetaRectangle damage;
99364f
+
99364f
+      clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
99364f
+
99364f
+      if (!meta_rectangle_overlap (&logical_monitor_layout, &view_layout))
99364f
+        continue;
99364f
+
99364f
+      damage = (cairo_rectangle_int_t) {
99364f
+        .x = view_layout.x,
99364f
+        .y = view_layout.y,
99364f
+        .width = 1,
99364f
+        .height = 1,
99364f
+      };
99364f
+      clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &damage);
99364f
+    }
99364f
+}
99364f
+
99364f
 static void
99364f
 meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
99364f
                                                          struct spa_meta_cursor  *spa_meta_cursor)
99364f
@@ -553,6 +594,8 @@ meta_screen_cast_monitor_stream_src_class_init (MetaScreenCastMonitorStreamSrcCl
99364f
     meta_screen_cast_monitor_stream_src_record_to_buffer;
99364f
   src_class->record_to_framebuffer =
99364f
     meta_screen_cast_monitor_stream_src_record_to_framebuffer;
99364f
+  src_class->record_follow_up =
99364f
+    meta_screen_cast_monitor_stream_record_follow_up;
99364f
   src_class->set_cursor_metadata =
99364f
     meta_screen_cast_monitor_stream_src_set_cursor_metadata;
99364f
 }
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index f6f66daaa3..55af56f8b9 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -90,6 +90,7 @@ typedef struct _MetaScreenCastStreamSrcPrivate
99364f
   int video_stride;
99364f
 
99364f
   int64_t last_frame_timestamp_us;
99364f
+  guint follow_up_frame_source_id;
99364f
 
99364f
   GHashTable *dmabuf_handles;
99364f
 
99364f
@@ -107,6 +108,12 @@ G_DEFINE_TYPE_WITH_CODE (MetaScreenCastStreamSrc,
99364f
                                                 meta_screen_cast_stream_src_init_initable_iface)
99364f
                          G_ADD_PRIVATE (MetaScreenCastStreamSrc))
99364f
 
99364f
+static inline uint32_t
99364f
+us2ms (uint64_t us)
99364f
+{
99364f
+  return (uint32_t) (us / 1000);
99364f
+}
99364f
+
99364f
 static void
99364f
 meta_screen_cast_stream_src_get_specs (MetaScreenCastStreamSrc *src,
99364f
                                        int                     *width,
99364f
@@ -154,6 +161,15 @@ meta_screen_cast_stream_src_record_to_framebuffer (MetaScreenCastStreamSrc  *src
99364f
   return klass->record_to_framebuffer (src, framebuffer, error);
99364f
 }
99364f
 
99364f
+static void
99364f
+meta_screen_cast_stream_src_record_follow_up (MetaScreenCastStreamSrc *src)
99364f
+{
99364f
+  MetaScreenCastStreamSrcClass *klass =
99364f
+    META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
99364f
+
99364f
+  klass->record_follow_up (src);
99364f
+}
99364f
+
99364f
 static void
99364f
 meta_screen_cast_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
99364f
                                                  struct spa_meta_cursor  *spa_meta_cursor)
99364f
@@ -440,6 +456,43 @@ do_record_frame (MetaScreenCastStreamSrc  *src,
99364f
   return FALSE;
99364f
 }
99364f
 
99364f
+gboolean
99364f
+meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src)
99364f
+{
99364f
+  MetaScreenCastStreamSrcPrivate *priv =
99364f
+    meta_screen_cast_stream_src_get_instance_private (src);
99364f
+
99364f
+  return priv->follow_up_frame_source_id != 0;
99364f
+}
99364f
+
99364f
+static gboolean
99364f
+follow_up_frame_cb (gpointer user_data)
99364f
+{
99364f
+  MetaScreenCastStreamSrc *src = user_data;
99364f
+  MetaScreenCastStreamSrcPrivate *priv =
99364f
+    meta_screen_cast_stream_src_get_instance_private (src);
99364f
+
99364f
+  priv->follow_up_frame_source_id = 0;
99364f
+  meta_screen_cast_stream_src_record_follow_up (src);
99364f
+
99364f
+  return G_SOURCE_REMOVE;
99364f
+}
99364f
+
99364f
+static void
99364f
+maybe_schedule_follow_up_frame (MetaScreenCastStreamSrc *src,
99364f
+                                int64_t                  timeout_us)
99364f
+{
99364f
+  MetaScreenCastStreamSrcPrivate *priv =
99364f
+    meta_screen_cast_stream_src_get_instance_private (src);
99364f
+
99364f
+  if (priv->follow_up_frame_source_id)
99364f
+    return;
99364f
+
99364f
+  priv->follow_up_frame_source_id = g_timeout_add (us2ms (timeout_us),
99364f
+                                                   follow_up_frame_cb,
99364f
+                                                   src);
99364f
+}
99364f
+
99364f
 void
99364f
 meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
                                                 MetaScreenCastRecordFlag  flags)
99364f
@@ -455,11 +508,24 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
 
99364f
   now_us = g_get_monotonic_time ();
99364f
   if (priv->video_format.max_framerate.num > 0 &&
99364f
-      priv->last_frame_timestamp_us != 0 &&
99364f
-      (now_us - priv->last_frame_timestamp_us <
99364f
-       ((1000000 * priv->video_format.max_framerate.denom) /
99364f
-        priv->video_format.max_framerate.num)))
99364f
-    return;
99364f
+      priv->last_frame_timestamp_us != 0)
99364f
+    {
99364f
+      int64_t min_interval_us;
99364f
+      int64_t time_since_last_frame_us;
99364f
+
99364f
+      min_interval_us = ((1000000 * priv->video_format.max_framerate.denom) /
99364f
+                         priv->video_format.max_framerate.num);
99364f
+
99364f
+      time_since_last_frame_us = now_us - priv->last_frame_timestamp_us;
99364f
+      if (time_since_last_frame_us < min_interval_us)
99364f
+        {
99364f
+          int64_t timeout_us;
99364f
+
99364f
+          timeout_us = min_interval_us - time_since_last_frame_us;
99364f
+          maybe_schedule_follow_up_frame (src, timeout_us);
99364f
+          return;
99364f
+        }
99364f
+    }
99364f
 
99364f
   if (!priv->pipewire_stream)
99364f
     return;
99364f
@@ -479,6 +545,7 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
 
99364f
   if (!(flags & META_SCREEN_CAST_RECORD_FLAG_CURSOR_ONLY))
99364f
     {
99364f
+      g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
99364f
       if (do_record_frame (src, spa_buffer, data, &error))
99364f
         {
99364f
           struct spa_meta_region *spa_meta_video_crop;
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.h b/src/backends/meta-screen-cast-stream-src.h
99364f
index 152790ecfb..81ea20b173 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.h
99364f
+++ b/src/backends/meta-screen-cast-stream-src.h
99364f
@@ -65,6 +65,8 @@ struct _MetaScreenCastStreamSrcClass
99364f
   gboolean (* record_to_framebuffer) (MetaScreenCastStreamSrc  *src,
99364f
                                       CoglFramebuffer          *framebuffer,
99364f
                                       GError                  **error);
99364f
+  void (* record_follow_up) (MetaScreenCastStreamSrc *src);
99364f
+
99364f
   gboolean (* get_videocrop) (MetaScreenCastStreamSrc *src,
99364f
                               MetaRectangle           *crop_rect);
99364f
   void (* set_cursor_metadata) (MetaScreenCastStreamSrc *src,
99364f
@@ -74,6 +76,8 @@ struct _MetaScreenCastStreamSrcClass
99364f
 void meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
                                                      MetaScreenCastRecordFlag  flags);
99364f
 
99364f
+gboolean meta_screen_cast_stream_src_pending_follow_up_frame (MetaScreenCastStreamSrc *src);
99364f
+
99364f
 MetaScreenCastStream * meta_screen_cast_stream_src_get_stream (MetaScreenCastStreamSrc *src);
99364f
 
99364f
 gboolean meta_screen_cast_stream_src_draw_cursor_into (MetaScreenCastStreamSrc  *src,
99364f
diff --git a/src/backends/meta-screen-cast-window-stream-src.c b/src/backends/meta-screen-cast-window-stream-src.c
99364f
index 70e868997e..7026ec3b4f 100644
99364f
--- a/src/backends/meta-screen-cast-window-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-window-stream-src.c
99364f
@@ -520,6 +520,15 @@ meta_screen_cast_window_stream_src_record_to_framebuffer (MetaScreenCastStreamSr
99364f
   return TRUE;
99364f
 }
99364f
 
99364f
+static void
99364f
+meta_screen_cast_window_stream_record_follow_up (MetaScreenCastStreamSrc *src)
99364f
+{
99364f
+  MetaScreenCastRecordFlag flags;
99364f
+
99364f
+  flags = META_SCREEN_CAST_RECORD_FLAG_NONE;
99364f
+  meta_screen_cast_stream_src_maybe_record_frame (src, flags);
99364f
+}
99364f
+
99364f
 static void
99364f
 meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
99364f
                                                         struct spa_meta_cursor  *spa_meta_cursor)
99364f
@@ -607,6 +616,8 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
99364f
     meta_screen_cast_window_stream_src_record_to_buffer;
99364f
   src_class->record_to_framebuffer =
99364f
     meta_screen_cast_window_stream_src_record_to_framebuffer;
99364f
+  src_class->record_follow_up =
99364f
+    meta_screen_cast_window_stream_record_follow_up;
99364f
   src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
99364f
   src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
99364f
 }
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From f2babf5129df9e948f471e3d464162888a99201d Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Wed, 8 Jul 2020 15:08:23 +0200
99364f
Subject: [PATCH 8/9] screen-cast/src: Use G_USEC_PER_SEC instead of 1000000
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1351
99364f
(cherry picked from commit 0c6ac287e6da91ba76bf3958befef4bec6ed28f6)
99364f
---
99364f
 src/backends/meta-screen-cast-stream-src.c | 5 +++--
99364f
 1 file changed, 3 insertions(+), 2 deletions(-)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index 55af56f8b9..1d6c2b9d08 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -513,8 +513,9 @@ meta_screen_cast_stream_src_maybe_record_frame (MetaScreenCastStreamSrc  *src,
99364f
       int64_t min_interval_us;
99364f
       int64_t time_since_last_frame_us;
99364f
 
99364f
-      min_interval_us = ((1000000 * priv->video_format.max_framerate.denom) /
99364f
-                         priv->video_format.max_framerate.num);
99364f
+      min_interval_us =
99364f
+        ((G_USEC_PER_SEC * priv->video_format.max_framerate.denom) /
99364f
+         priv->video_format.max_framerate.num);
99364f
 
99364f
       time_since_last_frame_us = now_us - priv->last_frame_timestamp_us;
99364f
       if (time_since_last_frame_us < min_interval_us)
99364f
-- 
99364f
2.26.2
99364f
99364f
99364f
From 950b3ea51391ffcb434f8f5380459174ba4c4853 Mon Sep 17 00:00:00 2001
99364f
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
99364f
Date: Fri, 10 Jul 2020 07:06:33 +0000
99364f
Subject: [PATCH 9/9] screen-cast/src: Remove follow up timeout source on
99364f
 disable
99364f
99364f
We failed to remove the timeout source when disabling, meaning that if a
99364f
follow up was scheduled, and shortly after we disabled the source, the
99364f
timeout would be invoked after the source was freed causing
99364f
use-after-free bugs.
99364f
99364f
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1337
99364f
99364f
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1365
99364f
99364f
(cherry picked from commit d67ba3ea65717ceab3e0c91267191c6ed2aac2c2)
99364f
(cherry picked from commit 1fd53c480f9bb58bd4ac0efc2bbce17dfda8645b)
99364f
---
99364f
 src/backends/meta-screen-cast-stream-src.c | 2 ++
99364f
 1 file changed, 2 insertions(+)
99364f
99364f
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
99364f
index 1d6c2b9d08..f39d348baa 100644
99364f
--- a/src/backends/meta-screen-cast-stream-src.c
99364f
+++ b/src/backends/meta-screen-cast-stream-src.c
99364f
@@ -622,6 +622,8 @@ meta_screen_cast_stream_src_disable (MetaScreenCastStreamSrc *src)
99364f
 
99364f
   META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src)->disable (src);
99364f
 
99364f
+  g_clear_handle_id (&priv->follow_up_frame_source_id, g_source_remove);
99364f
+
99364f
   priv->is_enabled = FALSE;
99364f
 }
99364f
 
99364f
-- 
99364f
2.26.2
99364f