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

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