[gtk+/wip/simple-draw2: 9/15] gdkwindow: Simplify invalidation



commit 08c33ef953487b9a9156fd2c56e1aeffc8c34be2
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Apr 19 17:40:58 2013 +0200

    gdkwindow: Simplify invalidation
    
    Now that all windows are non-opaque we can simplify the invalidation
    a lot. There is no need to clip the invalidate area to child regions,
    because we will always redraw everything under all the children.
    We only have to handle native childen specially.

 gdk/gdkwindow.c |  163 +++++++++++++++++++++++++------------------------------
 1 files changed, 75 insertions(+), 88 deletions(-)
---
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 3363669..3086bb3 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -151,12 +151,6 @@ enum {
   PROP_CURSOR
 };
 
-typedef enum {
-  CLEAR_BG_NONE,
-  CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
-  CLEAR_BG_ALL
-} ClearBg;
-
 struct _GdkWindowPaint
 {
   cairo_region_t *region;
@@ -193,12 +187,10 @@ static void impl_window_add_update_area (GdkWindow *impl_window,
                                         cairo_region_t *region);
 static void gdk_window_invalidate_region_full (GdkWindow       *window,
                                               const cairo_region_t *region,
-                                              gboolean         invalidate_children,
-                                              ClearBg          clear_bg);
+                                              gboolean         invalidate_children);
 static void gdk_window_invalidate_rect_full (GdkWindow          *window,
                                             const GdkRectangle *rect,
-                                            gboolean            invalidate_children,
-                                            ClearBg             clear_bg);
+                                            gboolean            invalidate_children);
 static cairo_surface_t *gdk_window_ref_impl_surface (GdkWindow *window);
 
 static void gdk_window_set_frame_clock (GdkWindow      *window,
@@ -3624,8 +3616,7 @@ gdk_window_process_updates (GdkWindow *window,
 static void
 gdk_window_invalidate_rect_full (GdkWindow          *window,
                                  const GdkRectangle *rect,
-                                 gboolean            invalidate_children,
-                                 ClearBg             clear_bg)
+                                 gboolean            invalidate_children)
 {
   GdkRectangle window_rect;
   cairo_region_t *region;
@@ -3648,7 +3639,7 @@ gdk_window_invalidate_rect_full (GdkWindow          *window,
     }
 
   region = cairo_region_create_rectangle (rect);
-  gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
+  gdk_window_invalidate_region_full (window, region, invalidate_children);
   cairo_region_destroy (region);
 }
 
@@ -3668,7 +3659,7 @@ gdk_window_invalidate_rect (GdkWindow          *window,
                            const GdkRectangle *rect,
                            gboolean            invalidate_children)
 {
-  gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
+  gdk_window_invalidate_rect_full (window, rect, invalidate_children);
 }
 
 static void
@@ -3700,26 +3691,66 @@ impl_window_add_update_area (GdkWindow *impl_window,
     }
 }
 
-/* clear_bg controls if the region will be cleared to
- * the background pattern if the exposure mask is not
- * set for the window, whereas this might not otherwise be
- * done (unless necessary to emulate background settings).
- * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
- * need to clear the background, such as when exposing the area beneath a
- * hidden or moved window, but not when an app requests repaint or when the
- * windowing system exposes a newly visible area (because then the windowing
- * system has already cleared the area).
- */
 static void
 gdk_window_invalidate_maybe_recurse_full (GdkWindow            *window,
                                          const cairo_region_t *region,
-                                         ClearBg               clear_bg,
+                                          GdkWindowChildFunc    child_func,
+                                         gpointer              user_data);
+
+static void
+invalidate_impl_subwindows (GdkWindow            *window,
+                           const cairo_region_t *region,
+                           GdkWindowChildFunc    child_func,
+                           gpointer              user_data,
+                           int dx, int dy)
+{
+  GList *tmp_list;
+
+  tmp_list = window->children;
+
+  while (tmp_list)
+    {
+      GdkWindow *child = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      if (child->input_only ||
+         !window->viewable)
+       continue;
+
+      if (child_func && (*child_func) ((GdkWindow *)child, user_data))
+       {
+         if (gdk_window_has_impl (child))
+           {
+             cairo_region_t *tmp = cairo_region_copy (region);
+             cairo_region_translate (tmp, -dx, -dy);
+             gdk_window_invalidate_maybe_recurse_full (child,
+                                                       tmp, child_func, user_data);
+             cairo_region_destroy (tmp);
+           }
+         else
+           {
+             dx += child->x;
+             dy += child->y;
+             invalidate_impl_subwindows (child,
+                                         region,
+                                         child_func, user_data,
+                                         dx, dy);
+             dx -= child->x;
+             dy -= child->y;
+           }
+
+       }
+    }
+}
+
+static void
+gdk_window_invalidate_maybe_recurse_full (GdkWindow            *window,
+                                         const cairo_region_t *region,
                                           GdkWindowChildFunc    child_func,
                                          gpointer              user_data)
 {
   GdkWindow *impl_window;
   cairo_region_t *visible_region;
-  GList *tmp_list;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3735,54 +3766,14 @@ gdk_window_invalidate_maybe_recurse_full (GdkWindow            *window,
   visible_region = gdk_window_get_visible_region (window);
   cairo_region_intersect (visible_region, region);
 
-  tmp_list = window->children;
-  while (tmp_list)
-    {
-      GdkWindow *child = tmp_list->data;
-
-      if (!child->input_only)
-       {
-         cairo_region_t *child_region;
-         GdkRectangle child_rect;
-
-         child_rect.x = child->x;
-         child_rect.y = child->y;
-         child_rect.width = child->width;
-         child_rect.height = child->height;
-         child_region = cairo_region_create_rectangle (&child_rect);
-
-         /* remove child area from the invalid area of the parent */
-         if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
-             !child->composited &&
-             !gdk_window_is_offscreen (child))
-           cairo_region_subtract (visible_region, child_region);
-
-         if (child_func && (*child_func) ((GdkWindow *)child, user_data))
-           {
-             cairo_region_t *tmp = cairo_region_copy (region);
-
-             cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
-             cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
-             cairo_region_intersect (child_region, tmp);
-
-             gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
-                                                       child_region, clear_bg, child_func, user_data);
-
-             cairo_region_destroy (tmp);
-           }
-
-         cairo_region_destroy (child_region);
-       }
-
-      tmp_list = tmp_list->next;
-    }
+  invalidate_impl_subwindows (window, region, child_func, user_data, 0, 0);
 
   impl_window = gdk_window_get_impl_window (window);
 
   if (!cairo_region_is_empty (visible_region))
     {
       if (debug_updates)
-       draw_ugly_color (window, region);
+       draw_ugly_color (window, visible_region);
 
       /* Convert to impl coords */
       cairo_region_translate (visible_region, window->abs_x, window->abs_y);
@@ -3791,10 +3782,7 @@ gdk_window_invalidate_maybe_recurse_full (GdkWindow            *window,
         we need to clear the area (by request or to emulate background
         clearing for non-native windows or native windows with no support
         for window backgrounds */
-      if (window->event_mask & GDK_EXPOSURE_MASK ||
-         clear_bg == CLEAR_BG_ALL ||
-         clear_bg == CLEAR_BG_WINCLEARED)
-       impl_window_add_update_area (impl_window, visible_region);
+      impl_window_add_update_area (impl_window, visible_region);
     }
 
   cairo_region_destroy (visible_region);
@@ -3831,7 +3819,7 @@ gdk_window_invalidate_maybe_recurse (GdkWindow            *window,
                                      GdkWindowChildFunc    child_func,
                                     gpointer              user_data)
 {
-  gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
+  gdk_window_invalidate_maybe_recurse_full (window, region,
                                            child_func, user_data);
 }
 
@@ -3845,10 +3833,9 @@ true_predicate (GdkWindow *window,
 static void
 gdk_window_invalidate_region_full (GdkWindow       *window,
                                    const cairo_region_t *region,
-                                   gboolean         invalidate_children,
-                                   ClearBg          clear_bg)
+                                   gboolean         invalidate_children)
 {
-  gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
+  gdk_window_invalidate_maybe_recurse_full (window, region,
                                            invalidate_children ?
                                            true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
                                       NULL);
@@ -3915,7 +3902,7 @@ void
 _gdk_window_invalidate_for_expose (GdkWindow       *window,
                                   cairo_region_t       *region)
 {
-  gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
+  gdk_window_invalidate_maybe_recurse_full (window, region,
                                            (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
                                            NULL);
 }
@@ -4592,7 +4579,7 @@ gdk_window_show_internal (GdkWindow *window, gboolean raise)
       if (gdk_window_is_viewable (window))
        {
          _gdk_synthesize_crossing_events_for_geometry_change (window);
-         gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
+         gdk_window_invalidate_rect_full (window, NULL, TRUE);
        }
     }
 }
@@ -4640,7 +4627,7 @@ gdk_window_raise (GdkWindow *window)
 
   if (gdk_window_is_viewable (window) &&
       !window->input_only)
-    gdk_window_invalidate_region_full (window, window->clip_region, TRUE, CLEAR_BG_ALL);
+    gdk_window_invalidate_region_full (window, window->clip_region, TRUE);
 }
 
 static void
@@ -4726,7 +4713,7 @@ gdk_window_invalidate_in_parent (GdkWindow *private)
   child.height = private->height;
   gdk_rectangle_intersect (&r, &child, &r);
 
-  gdk_window_invalidate_rect_full (private->parent, &r, TRUE, CLEAR_BG_ALL);
+  gdk_window_invalidate_rect_full (private->parent, &r, TRUE);
 }
 
 
@@ -5233,7 +5220,7 @@ gdk_window_move_resize_toplevel (GdkWindow *window,
        * X will expose it, but lets do that without the roundtrip
        */
       cairo_region_subtract (new_region, old_region);
-      gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
+      gdk_window_invalidate_region_full (window, new_region, TRUE);
 
       cairo_region_destroy (old_region);
       cairo_region_destroy (new_region);
@@ -5356,7 +5343,7 @@ gdk_window_move_resize_internal (GdkWindow *window,
 
       cairo_region_union (new_region, old_region);
 
-      gdk_window_invalidate_region_full (window->parent, new_region, TRUE, CLEAR_BG_ALL);
+      gdk_window_invalidate_region_full (window->parent, new_region, TRUE);
 
       cairo_region_destroy (old_region);
       cairo_region_destroy (new_region);
@@ -5489,7 +5476,7 @@ gdk_window_scroll (GdkWindow *window,
 
   move_native_children (window);
 
-  gdk_window_invalidate_region_full (window, window->clip_region, TRUE, CLEAR_BG_ALL);
+  gdk_window_invalidate_region_full (window, window->clip_region, TRUE);
 
   _gdk_synthesize_crossing_events_for_geometry_change (window);
 }
@@ -5530,7 +5517,7 @@ gdk_window_move_region (GdkWindow       *window,
   cairo_region_translate (expose_area, dx, dy);
   cairo_region_union (expose_area, region);
 
-  gdk_window_invalidate_region_full (window, expose_area, FALSE, CLEAR_BG_ALL);
+  gdk_window_invalidate_region_full (window, expose_area, FALSE);
   cairo_region_destroy (expose_area);
 }
 
@@ -5626,7 +5613,7 @@ gdk_window_set_background_pattern (GdkWindow *window,
       impl_class->set_background (window, pattern);
     }
   else
-    gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
+    gdk_window_invalidate_rect_full (window, NULL, TRUE);
 }
 
 /**
@@ -6209,7 +6196,7 @@ gdk_window_shape_combine_region (GdkWindow       *window,
       diff = cairo_region_copy (new_region);
       cairo_region_subtract (diff, old_region);
 
-      gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
+      gdk_window_invalidate_region_full (window, diff, TRUE);
 
       cairo_region_destroy (diff);
 
@@ -6222,7 +6209,7 @@ gdk_window_shape_combine_region (GdkWindow       *window,
          /* Adjust region to parent window coords */
          cairo_region_translate (diff, window->x, window->y);
 
-         gdk_window_invalidate_region_full (window->parent, diff, TRUE, CLEAR_BG_ALL);
+         gdk_window_invalidate_region_full (window->parent, diff, TRUE);
 
          cairo_region_destroy (diff);
        }
@@ -10078,7 +10065,7 @@ gdk_window_set_opacity (GdkWindow *window,
   else
     {
       recompute_visible_regions (window, FALSE);
-      gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
+      gdk_window_invalidate_rect_full (window, NULL, TRUE);
     }
 }
 


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