[gtk+/wip/gdk-gl2: 3/13] Change the way the update area is tracked during paint



commit 91f99ed80785517169d46a2ff9e1b0e74c2c6d35
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Oct 9 10:09:51 2014 +0200

    Change the way the update area is tracked during paint
    
    First of all we track the current update area during an
    update in window->active_update_area. This will be used later
    in end_paint to know the damaged area.
    
    Secondly we keep track of old update areas for the last 2
    frames. This will later allow us to reuse old framebuffer
    contents in double or tripple buffer setups, only painting
    what has changed since then.

 gdk/gdkinternals.h |    6 ++++++
 gdk/gdkwindow.c    |   47 ++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 46 insertions(+), 7 deletions(-)
---
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 07df2f1..d70b6c4 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -213,6 +213,12 @@ struct _GdkWindow
 
   cairo_region_t *update_area;
   guint update_freeze_count;
+  /* This is the update_area that was in effect when the current expose
+     started. It may be smaller than the expose area if we'e painting
+     more than we have to, but it represents the "true" damage. */
+  cairo_region_t *active_update_area;
+  /* We store the old expose areas to support buffer-age optimizations */
+  cairo_region_t *old_updated_area[2];
 
   GdkWindowState state;
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index f5eb162..2e349ca 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -1024,9 +1024,35 @@ recompute_visible_regions (GdkWindow *private,
                                      recalculate_children);
 }
 
+static void
+gdk_window_clear_old_updated_area (GdkWindow *window)
+{
+  int i;
+
+  for (i = 0; i < 2; i++)
+    {
+      if (window->old_updated_area[i])
+        {
+          cairo_region_destroy (window->old_updated_area[i]);
+          window->old_updated_area[i] = NULL;
+        }
+    }
+}
+
+static void
+gdk_window_append_old_updated_area (GdkWindow *window,
+                                    cairo_region_t *region)
+{
+  if (window->old_updated_area[1])
+    cairo_region_destroy (window->old_updated_area[1]);
+  window->old_updated_area[1] = window->old_updated_area[0];
+  window->old_updated_area[0] = cairo_region_reference (region);
+}
+
 void
 _gdk_window_update_size (GdkWindow *window)
 {
+  gdk_window_clear_old_updated_area (window);
   recompute_visible_regions (window, FALSE);
 }
 
@@ -3375,15 +3401,19 @@ gdk_window_process_updates_internal (GdkWindow *window)
    */
   if (window->update_area)
     {
-      cairo_region_t *update_area = window->update_area;
+      g_assert (window->active_update_area == NULL); /* No reentrancy */
+
+      window->active_update_area = window->update_area;
       window->update_area = NULL;
 
       if (gdk_window_is_viewable (window))
        {
          cairo_region_t *expose_region;
 
+         expose_region = cairo_region_copy (window->active_update_area);
+
          /* Clip to part visible in impl window */
-         cairo_region_intersect (update_area, window->clip_region);
+         cairo_region_intersect (expose_region, window->clip_region);
 
          if (debug_updates)
            {
@@ -3395,14 +3425,15 @@ gdk_window_process_updates_internal (GdkWindow *window)
          impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
 
           if (impl_class->queue_antiexpose)
-            impl_class->queue_antiexpose (window, update_area);
+            impl_class->queue_antiexpose (window, expose_region);
 
-         expose_region = cairo_region_copy (update_area);
           impl_class->process_updates_recurse (window, expose_region);
-         cairo_region_destroy (expose_region);
-       }
 
-      cairo_region_destroy (update_area);
+          gdk_window_append_old_updated_area (window, window->active_update_area);
+        }
+
+      cairo_region_destroy (window->active_update_area);
+      window->active_update_area = NULL;
     }
 
   window->in_update = FALSE;
@@ -5046,6 +5077,7 @@ gdk_window_hide (GdkWindow *window)
       impl_class->hide (window);
     }
 
+  gdk_window_clear_old_updated_area (window);
   recompute_visible_regions (window, FALSE);
 
   /* all decendants became non-visible, we need to send visibility notify */
@@ -5105,6 +5137,7 @@ gdk_window_withdraw (GdkWindow *window)
        }
 
       recompute_visible_regions (window, FALSE);
+      gdk_window_clear_old_updated_area (window);
     }
 }
 


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