[mutter] clutter-offscreen-effect: Invalidate cache on gl-video-memory-purged



commit 2de69cd3cc1f1c86c81008b0a3116063149d4ac8
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Fri Jul 17 15:35:13 2020 +0800

    clutter-offscreen-effect: Invalidate cache on gl-video-memory-purged
    
    This fixes graphics corruption that could occur on resume from suspend
    with the Nvidia driver.
    
    https://www.khronos.org/registry/OpenGL/extensions/NV/NV_robustness_video_memory_purge.txt
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1374

 clutter/clutter/clutter-offscreen-effect.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)
---
diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c
index 75174ef104..40bb5f8cc6 100644
--- a/clutter/clutter/clutter-offscreen-effect.c
+++ b/clutter/clutter/clutter-offscreen-effect.c
@@ -100,6 +100,8 @@ struct _ClutterOffscreenEffectPrivate
   int target_height;
 
   gint old_opacity_override;
+
+  gulong purge_handler_id;
 };
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterOffscreenEffect,
@@ -158,6 +160,12 @@ ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self,
                                    filter, filter);
 }
 
+static void
+video_memory_purged (ClutterOffscreenEffect *self)
+{
+  g_clear_pointer (&self->priv->offscreen, cogl_object_unref);
+}
+
 static gboolean
 update_fbo (ClutterEffect *effect,
             int            target_width,
@@ -166,8 +174,26 @@ update_fbo (ClutterEffect *effect,
 {
   ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (effect);
   ClutterOffscreenEffectPrivate *priv = self->priv;
+  ClutterActor *stage_actor;
+
+  stage_actor = clutter_actor_get_stage (priv->actor);
+  if (stage_actor != priv->stage)
+    {
+      g_clear_signal_handler (&priv->purge_handler_id, priv->stage);
+
+      priv->stage = stage_actor;
+
+      if (priv->stage)
+        {
+          priv->purge_handler_id =
+            g_signal_connect_object (priv->stage,
+                                     "gl-video-memory-purged",
+                                     G_CALLBACK (video_memory_purged),
+                                     self,
+                                     G_CONNECT_SWAPPED);
+        }
+    }
 
-  priv->stage = clutter_actor_get_stage (priv->actor);
   if (priv->stage == NULL)
     {
       CLUTTER_NOTE (MISC, "The actor '%s' is not part of a stage",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]