[mutter] clutter/stage-cogl: Extract damage history logic



commit ae4d29949928f09d34a40b59db56974ff49754c9
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed May 6 09:11:34 2020 +0200

    clutter/stage-cogl: Extract damage history logic
    
    Move the damage history tracking to a new ClutterDamageHistory helper
    type. The aim is to be able to track damage history elsewhere without
    reimplementing the data structure and tracking logic.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1237

 clutter/clutter/clutter-damage-history.c  | 92 +++++++++++++++++++++++++++++++
 clutter/clutter/clutter-damage-history.h  | 42 ++++++++++++++
 clutter/clutter/cogl/clutter-stage-cogl.c | 67 +++++++++++-----------
 clutter/clutter/meson.build               |  2 +
 4 files changed, 169 insertions(+), 34 deletions(-)
---
diff --git a/clutter/clutter/clutter-damage-history.c b/clutter/clutter/clutter-damage-history.c
new file mode 100644
index 0000000000..d5e86f1b76
--- /dev/null
+++ b/clutter/clutter/clutter-damage-history.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007,2008,2009,2010,2011  Intel Corporation.
+ * Copyright (C) 2020 Red Hat Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "clutter-build-config.h"
+
+#include "clutter-damage-history.h"
+
+#define DAMAGE_HISTORY_LENGTH 0x10
+
+struct _ClutterDamageHistory
+{
+  cairo_region_t *damages[DAMAGE_HISTORY_LENGTH];
+  int index;
+};
+
+ClutterDamageHistory *
+clutter_damage_history_new (void)
+{
+  ClutterDamageHistory *history;
+
+  history = g_new0 (ClutterDamageHistory, 1);
+
+  return history;
+}
+
+void
+clutter_damage_history_free (ClutterDamageHistory *history)
+{
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (history->damages); i++)
+    g_clear_pointer (&history->damages[i], cairo_region_destroy);
+
+  g_free (history);
+}
+
+gboolean
+clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
+                                     int                   age)
+{
+  if (age >= DAMAGE_HISTORY_LENGTH ||
+      age < 1)
+    return FALSE;
+
+  if (!clutter_damage_history_lookup (history, age))
+    return FALSE;
+
+  return TRUE;
+}
+
+void
+clutter_damage_history_record (ClutterDamageHistory *history,
+                               const cairo_region_t *damage)
+{
+  g_clear_pointer (&history->damages[history->index], cairo_region_destroy);
+  history->damages[history->index] = cairo_region_copy (damage);
+}
+
+static inline int
+step_damage_index (int current,
+                   int diff)
+{
+  return (current + diff) & (DAMAGE_HISTORY_LENGTH - 1);
+}
+
+void
+clutter_damage_history_step (ClutterDamageHistory *history)
+{
+  history->index = step_damage_index (history->index, 1);
+}
+
+const cairo_region_t *
+clutter_damage_history_lookup (ClutterDamageHistory *history,
+                               int                   age)
+{
+  return history->damages[step_damage_index (history->index, -age)];
+}
diff --git a/clutter/clutter/clutter-damage-history.h b/clutter/clutter/clutter-damage-history.h
new file mode 100644
index 0000000000..e29c3f1cb9
--- /dev/null
+++ b/clutter/clutter/clutter-damage-history.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007,2008,2009,2010,2011  Intel Corporation.
+ * Copyright (C) 2020 Red Hat Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CLUTTER_DAMAGE_HISTORY_H
+#define CLUTTER_DAMAGE_HISTORY_H
+
+#include <cairo.h>
+#include <glib.h>
+
+typedef struct _ClutterDamageHistory ClutterDamageHistory;
+
+ClutterDamageHistory * clutter_damage_history_new (void);
+
+void clutter_damage_history_free (ClutterDamageHistory *history);
+
+gboolean clutter_damage_history_is_age_valid (ClutterDamageHistory *history,
+                                              int                   age);
+
+void clutter_damage_history_record (ClutterDamageHistory *history,
+                                    const cairo_region_t *damage);
+
+void clutter_damage_history_step (ClutterDamageHistory *history);
+
+const cairo_region_t * clutter_damage_history_lookup (ClutterDamageHistory *history,
+                                                      int                   age);
+
+#endif /* CLUTTER_DAMAGE_HISTORY_H */
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 2e2086c813..0552c04d02 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -38,6 +38,7 @@
 
 #include "clutter-actor-private.h"
 #include "clutter-backend-private.h"
+#include "clutter-damage-history.h"
 #include "clutter-debug.h"
 #include "clutter-event.h"
 #include "clutter-enum-types.h"
@@ -51,13 +52,9 @@
 
 typedef struct _ClutterStageViewCoglPrivate
 {
-  /*
-   * List of previous damaged areas in stage view framebuffer coordinate space.
+  /* Damage history, in stage view render target framebuffer coordinate space.
    */
-#define DAMAGE_HISTORY_MAX 16
-#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
-  cairo_region_t * damage_history[DAMAGE_HISTORY_MAX];
-  unsigned int damage_index;
+  ClutterDamageHistory *damage_history;
 } ClutterStageViewCoglPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (ClutterStageViewCogl, clutter_stage_view_cogl,
@@ -295,10 +292,7 @@ valid_buffer_age (ClutterStageViewCogl *view_cogl,
   ClutterStageViewCoglPrivate *view_priv =
     clutter_stage_view_cogl_get_instance_private (view_cogl);
 
-  if (age <= 0)
-    return FALSE;
-
-  return age < MIN (view_priv->damage_index, DAMAGE_HISTORY_MAX);
+  return clutter_damage_history_is_age_valid (view_priv->damage_history, age);
 }
 
 static void
@@ -517,23 +511,6 @@ paint_stage (ClutterStageCogl *stage_cogl,
   clutter_stage_view_after_paint (view, redraw_clip);
 }
 
-static void
-fill_current_damage_history (ClutterStageView *view,
-                             cairo_region_t   *damage)
-{
-  ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
-  ClutterStageViewCoglPrivate *view_priv =
-    clutter_stage_view_cogl_get_instance_private (view_cogl);
-  cairo_region_t **current_fb_damage;
-
-  current_fb_damage =
-    &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
-
-  g_clear_pointer (current_fb_damage, cairo_region_destroy);
-  *current_fb_damage = cairo_region_copy (damage);
-  view_priv->damage_index++;
-}
-
 static cairo_region_t *
 transform_swap_region_to_onscreen (ClutterStageView *view,
                                    cairo_region_t   *swap_region)
@@ -666,23 +643,24 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
   swap_with_damage = FALSE;
   if (has_buffer_age)
     {
-      fill_current_damage_history (view, fb_clip_region);
+      clutter_damage_history_record (view_priv->damage_history,
+                                     fb_clip_region);
 
       if (use_clipped_redraw)
         {
           cairo_region_t *fb_damage;
           cairo_region_t *view_damage;
-          int i;
+          int age;
 
           fb_damage = cairo_region_create ();
 
-          for (i = 1; i <= buffer_age; i++)
+          for (age = 1; age <= buffer_age; age++)
             {
-              int damage_index;
+              const cairo_region_t *old_damage;
 
-              damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
-              cairo_region_union (fb_damage,
-                                  view_priv->damage_history[damage_index]);
+              old_damage =
+                clutter_damage_history_lookup (view_priv->damage_history, age);
+              cairo_region_union (fb_damage, old_damage);
             }
 
           /* Update the fb clip region with the extra damage. */
@@ -705,6 +683,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 
           swap_with_damage = TRUE;
         }
+
+      clutter_damage_history_step (view_priv->damage_history);
     }
 
   if (use_clipped_redraw)
@@ -891,12 +871,31 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage)
   stage->update_time = -1;
 }
 
+static void
+clutter_stage_view_cogl_finalize (GObject *object)
+{
+  ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (object);
+  ClutterStageViewCoglPrivate *view_priv =
+    clutter_stage_view_cogl_get_instance_private (view_cogl);
+
+  clutter_damage_history_free (view_priv->damage_history);
+
+  G_OBJECT_CLASS (clutter_stage_view_cogl_parent_class)->finalize (object);
+}
+
 static void
 clutter_stage_view_cogl_init (ClutterStageViewCogl *view_cogl)
 {
+  ClutterStageViewCoglPrivate *view_priv =
+    clutter_stage_view_cogl_get_instance_private (view_cogl);
+
+  view_priv->damage_history = clutter_damage_history_new ();
 }
 
 static void
 clutter_stage_view_cogl_class_init (ClutterStageViewCoglClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = clutter_stage_view_cogl_finalize;
 }
diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build
index f21d0e77c3..1796427401 100644
--- a/clutter/clutter/meson.build
+++ b/clutter/clutter/meson.build
@@ -114,6 +114,7 @@ clutter_sources = [
   'clutter-constraint.c',
   'clutter-container.c',
   'clutter-content.c',
+  'clutter-damage-history.c',
   'clutter-deform-effect.c',
   'clutter-desaturate-effect.c',
   'clutter-effect.c',
@@ -185,6 +186,7 @@ clutter_private_headers = [
   'clutter-bezier.h',
   'clutter-constraint-private.h',
   'clutter-content-private.h',
+  'clutter-damage-history.h',
   'clutter-debug.h',
   'clutter-easing.h',
   'clutter-effect-private.h',


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