[PATCH] hippo_repaint_using_regions.diff



Hi,

this patch changes the paint-related methods to use GdkRegion instead
of HippoRectangle as the expose area. This is specially important for
performance on limited platforms like the XO because allows canvas
items to better decide when they need to be redrawn.

Thanks,

tomeu
Index: python/hippo.defs
===================================================================
--- python/hippo.defs	(revision 7296)
+++ python/hippo.defs	(working copy)
@@ -752,7 +752,7 @@
   (return-type "none")
   (parameters
     '("cairo_t*" "cr")
-    '("HippoRectangle*" "damaged_box")
+    '("GdkRegion*" "damaged_region")
   )
 )
 
@@ -762,7 +762,7 @@
   (return-type "none")
   (parameters
     '("cairo_t*" "cr")
-    '("HippoRectangle*" "damaged_box")
+    '("GdkRegion*" "damaged_region")
   )
 )
 
@@ -772,7 +772,7 @@
   (return-type "none")
   (parameters
     '("cairo_t*" "cr")
-    '("HippoRectangle*" "damaged_box")
+    '("GdkRegion*" "damaged_region")
   )
 )
 
@@ -782,7 +782,7 @@
   (return-type "none")
   (parameters
     '("cairo_t*" "cr")
-    '("HippoRectangle*" "damaged_box")
+    '("GdkRegion*" "damaged_region")
   )
 )
 
@@ -1177,7 +1177,7 @@
   (return-type "none")
   (parameters
     '("cairo_t*" "cr")
-    '("HippoRectangle*" "damaged_area")
+    '("GdkRegion*" "damaged_region")
   )
 )
 
@@ -1337,7 +1337,7 @@
   (return-type "none")
   (parameters
     '("cairo_t*" "cr")
-    '("HippoRectangle*" "damaged_box")
+    '("GdkRegion*" "damaged_region")
     '("int" "allocation_x")
     '("int" "allocation_y")
   )
Index: python/hippo.override
===================================================================
--- python/hippo.override	(revision 7296)
+++ python/hippo.override	(working copy)
@@ -28,6 +28,30 @@
 
 extern Pycairo_CAPI_t *Pycairo_CAPI;
 
+/* A boxed type for GdkRegion until one gets into gtk+ itself. */
+#ifdef GDK_TYPE_REGION
+#define PYGDK_TYPE_REGION  GDK_TYPE_REGION 
+#else
+GType pygdk_region_get_type (void) G_GNUC_CONST;
+
+#define PYGDK_TYPE_REGION (pygdk_region_get_type ())
+#endif /* GDK_TYPE_REGION */
+
+#ifndef GDK_TYPE_REGION
+GType
+pygdk_region_get_type (void)
+{
+  static GType our_type = 0;
+  
+  if (our_type == 0)
+    /* GdkRegion is already taken by pygtk in its boxing of GdkRegion. */
+    our_type = g_boxed_type_register_static ("HippoGdkRegion",
+					     (GBoxedCopyFunc)gdk_region_copy,
+					     (GBoxedFreeFunc)gdk_region_destroy);
+  return our_type;
+}
+#endif
+
 static int
 marshal_compare_child_func(HippoCanvasItem *a, HippoCanvasItem *b, void *data)
 {
Index: docs/tmpl/hippo-canvas-item.sgml
===================================================================
--- docs/tmpl/hippo-canvas-item.sgml	(revision 7296)
+++ docs/tmpl/hippo-canvas-item.sgml	(working copy)
@@ -453,7 +453,7 @@
 
 @canvas_item: 
 @cr: 
- damaged_box: 
+ damaged_region: 
 @allocation_x: 
 @allocation_y: 
 
Index: common/hippo/hippo-canvas-image.c
===================================================================
--- common/hippo/hippo-canvas-image.c	(revision 7296)
+++ common/hippo/hippo-canvas-image.c	(working copy)
@@ -27,7 +27,7 @@
 /* Canvas box methods */
 static void hippo_canvas_image_paint_below_children       (HippoCanvasBox *box,
                                                            cairo_t        *cr,
-                                                           HippoRectangle  *damaged_box);
+                                                           GdkRegion      *damaged_region);
 static void hippo_canvas_image_get_content_width_request  (HippoCanvasBox *box,
                                                            int            *min_width_p,
                                                            int            *natural_width_p);
@@ -351,7 +351,7 @@
 static void
 hippo_canvas_image_paint_below_children(HippoCanvasBox  *box,
                                         cairo_t         *cr,
-                                        HippoRectangle  *damaged_box)
+                                        GdkRegion       *damaged_region)
 {
     HippoCanvasImage *image = HIPPO_CANVAS_IMAGE(box);
     int x, y, w, h;
Index: common/hippo/hippo-canvas-text.c
===================================================================
--- common/hippo/hippo-canvas-text.c	(revision 7296)
+++ common/hippo/hippo-canvas-text.c	(working copy)
@@ -4,6 +4,7 @@
 #include "hippo-canvas-style.h"
 #include "hippo-canvas-text.h"
 #include "hippo-canvas-box.h"
+#include <gdk/gdk.h>
 #include <pango/pangocairo.h>
 #include <stdlib.h>
 #include <string.h>
@@ -36,7 +37,7 @@
 /* Box methods */
 static void hippo_canvas_text_paint_below_children       (HippoCanvasBox *box,
                                                           cairo_t        *cr,
-                                                          HippoRectangle *damaged_box);
+                                                          GdkRegion      *damaged_region);
 static void hippo_canvas_text_get_content_width_request  (HippoCanvasBox *box,
                                                           int            *min_width_p,
                                                           int            *natural_width_p);
@@ -552,7 +553,7 @@
 static void
 hippo_canvas_text_paint_below_children(HippoCanvasBox  *box,
                                        cairo_t         *cr,
-                                       HippoRectangle  *damaged_box)
+                                       GdkRegion       *damaged_region)
 {
     HippoCanvasText *text = HIPPO_CANVAS_TEXT(box);
     guint32 color_rgba;
Index: common/hippo/hippo-canvas-box.c
===================================================================
--- common/hippo/hippo-canvas-box.c	(revision 7296)
+++ common/hippo/hippo-canvas-box.c	(working copy)
@@ -93,7 +93,7 @@
 static HippoCanvasContainer* hippo_canvas_box_get_parent       (HippoCanvasItem    *item);
 static void               hippo_canvas_box_paint               (HippoCanvasItem    *item,
                                                                 cairo_t            *cr,
-                                                                HippoRectangle     *damaged_box);
+                                                                GdkRegion          *damaged_region);
 static void               hippo_canvas_box_get_width_request   (HippoCanvasItem   *item,
                                                                 int               *min_width_p,
                                                                 int               *natural_width_p);
@@ -129,10 +129,10 @@
 /* Canvas box methods */
 static void hippo_canvas_box_paint_background           (HippoCanvasBox *box,
                                                          cairo_t        *cr,
-                                                         HippoRectangle *damaged_box);
+                                                         GdkRegion      *damaged_region);
 static void hippo_canvas_box_paint_children             (HippoCanvasBox *box,
                                                          cairo_t        *cr,
-                                                         HippoRectangle *damaged_box);
+                                                         GdkRegion      *damaged_region);
 
 static void hippo_canvas_box_get_content_width_request  (HippoCanvasBox *box,
                                                          int            *min_width_p,
@@ -1619,7 +1619,7 @@
 static void
 hippo_canvas_box_paint_background(HippoCanvasBox *box,
                                   cairo_t        *cr,
-                                  HippoRectangle *damaged_box)
+                                  GdkRegion      *damaged_region)
 {
     HippoCanvasStyle *style = hippo_canvas_context_get_style(HIPPO_CANVAS_CONTEXT(box));
     HippoCanvasThemeImage *background_theme_image;
@@ -1681,7 +1681,7 @@
 static void
 hippo_canvas_box_paint_children(HippoCanvasBox *box,
                                 cairo_t        *cr,
-                                HippoRectangle *damaged_box)
+                                GdkRegion      *damaged_region)
 {
     GSList *link;
 
@@ -1707,7 +1707,7 @@
             cairo_clip(cr);
         }
         
-        hippo_canvas_item_process_paint(HIPPO_CANVAS_ITEM(child->public.item), cr, damaged_box,
+        hippo_canvas_item_process_paint(HIPPO_CANVAS_ITEM(child->public.item), cr, damaged_region,
                                         child->x, child->y);
 
         if (child->public.fixed) {
@@ -1719,7 +1719,7 @@
 static void
 hippo_canvas_box_paint(HippoCanvasItem *item,
                        cairo_t         *cr,
-                       HippoRectangle  *damaged_box)
+                       GdkRegion       *damaged_region)
 {
     HippoCanvasBox *box = HIPPO_CANVAS_BOX(item);
     HippoCanvasBoxClass *klass = HIPPO_CANVAS_BOX_GET_CLASS(box);
@@ -1727,22 +1727,22 @@
     g_return_if_fail(box->allocated_width > 0 && box->allocated_height > 0);
     
     cairo_save(cr);
-    (* klass->paint_background) (box, cr, damaged_box);
+    (* klass->paint_background) (box, cr, damaged_region);
     cairo_restore(cr);
     
     if (klass->paint_below_children != NULL) {
         cairo_save(cr);
-        (* klass->paint_below_children) (box, cr, damaged_box);
+        (* klass->paint_below_children) (box, cr, damaged_region);
         cairo_restore(cr);
     }
 
     cairo_save(cr);
-    (* klass->paint_children) (box, cr, damaged_box);
+    (* klass->paint_children) (box, cr, damaged_region);
     cairo_restore(cr);
     
     if (klass->paint_above_children != NULL) {
         cairo_save(cr);
-        (* klass->paint_above_children) (box, cr, damaged_box);
+        (* klass->paint_above_children) (box, cr, damaged_region);
         cairo_restore(cr);
     }
 }
Index: common/hippo/hippo-canvas-box.h
===================================================================
--- common/hippo/hippo-canvas-box.h	(revision 7296)
+++ common/hippo/hippo-canvas-box.h	(working copy)
@@ -141,16 +141,16 @@
 
     void     (* paint_background)             (HippoCanvasBox   *box,
                                                cairo_t          *cr,
-                                               HippoRectangle   *damaged_box);
+                                               GdkRegion        *damaged_region);
     void     (* paint_children)               (HippoCanvasBox   *box,
                                                cairo_t          *cr,
-                                               HippoRectangle   *damaged_box);
+                                               GdkRegion        *damaged_region);
     void     (* paint_below_children)         (HippoCanvasBox   *box,
                                                cairo_t          *cr,
-                                               HippoRectangle   *damaged_box);
+                                               GdkRegion        *damaged_region);
     void     (* paint_above_children)         (HippoCanvasBox   *box,
                                                cairo_t          *cr,
-                                               HippoRectangle   *damaged_box);
+                                               GdkRegion        *damaged_region);
     
     void     (* get_content_width_request)    (HippoCanvasBox   *box,
                                                int              *min_width_p,
Index: common/hippo/hippo-canvas-gradient.c
===================================================================
--- common/hippo/hippo-canvas-gradient.c	(revision 7296)
+++ common/hippo/hippo-canvas-gradient.c	(working copy)
@@ -23,7 +23,7 @@
 /* Canvas box methods */
 static void hippo_canvas_gradient_paint_below_children (HippoCanvasBox *box,
                                                         cairo_t        *cr,
-                                                        HippoRectangle *damaged_box);
+                                                        GdkRegion      *damaged_region);
 
 struct _HippoCanvasGradient {
     HippoCanvasBox box;
@@ -179,7 +179,7 @@
 static void
 hippo_canvas_gradient_paint_below_children(HippoCanvasBox  *box,
                                            cairo_t         *cr,
-                                           HippoRectangle  *damaged_box)
+                                           GdkRegion       *damaged_region)
 {
     HippoCanvasGradient *gradient = HIPPO_CANVAS_GRADIENT(box);
     cairo_pattern_t *pattern;
Index: common/hippo/hippo-canvas-item.c
===================================================================
--- common/hippo/hippo-canvas-item.c	(revision 7296)
+++ common/hippo/hippo-canvas-item.c	(working copy)
@@ -1,5 +1,6 @@
 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 #include <string.h>
+#include <gdk/gdk.h>
 
 #include "hippo-canvas-internal.h"
 #include "hippo-canvas-item.h"
@@ -75,7 +76,7 @@
                       G_STRUCT_OFFSET(HippoCanvasItemIface, paint),
                       NULL, NULL,
                       hippo_canvas_marshal_VOID__POINTER_BOXED,
-                      G_TYPE_NONE, 2, G_TYPE_POINTER, HIPPO_TYPE_RECTANGLE);
+                      G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
     /**
      * HippoCanvasItem::request-changed
      *
@@ -662,38 +663,34 @@
     return handled;
 }
 
-// the cairo_t and damaged_box are in the coordinate system in which canvas_item
+// the cairo_t and damaged_region are in the coordinate system in which canvas_item
 // is at (allocation_x, allocation_y), so they are both translated before
 // passing them to the child
 void
 hippo_canvas_item_process_paint(HippoCanvasItem *canvas_item,
                                 cairo_t         *cr,
-                                HippoRectangle  *damaged_box,
+                                GdkRegion       *damaged_region,
                                 int              allocation_x,
                                 int              allocation_y)
 {
-    HippoRectangle item_box;
-    HippoRectangle translated_box;
-    
+    GdkRectangle item_box;
+
     /* HippoCanvasItem::paint() is guaranteed to not be called if an item has any 0 allocation,
      * that invariant should be maintained here.
      */
-    
+
     item_box.x = allocation_x;
     item_box.y = allocation_y;
     hippo_canvas_item_get_allocation(canvas_item, &item_box.width, &item_box.height);
-    
-    if (hippo_rectangle_intersect(damaged_box, &item_box, &translated_box)) {
-        translated_box.x -= allocation_x;
-        translated_box.y -= allocation_y;
 
-        g_assert(translated_box.x >= 0);
-        g_assert(translated_box.y >= 0);
-        g_assert(translated_box.width > 0);
-        g_assert(translated_box.height > 0);
+    if (gdk_region_rect_in(damaged_region, &item_box) != GDK_OVERLAP_RECTANGLE_OUT) {
+        GdkRegion *translated_region;
 
+        translated_region = gdk_region_rectangle(&item_box);
+        gdk_region_intersect(translated_region, damaged_region);
+        gdk_region_offset(translated_region, -allocation_x, -allocation_y);
+
         cairo_save(cr);
-        
         cairo_translate(cr, allocation_x, allocation_y);
 
 #if 0
@@ -701,9 +698,9 @@
         cairo_rectangle(cr, 0, 0, item_box.width, item_box.height);
         cairo_fill(cr);
 #endif
-        
-        g_signal_emit(canvas_item, signals[PAINT], 0, cr, &translated_box);
-        
+
+        g_signal_emit(canvas_item, signals[PAINT], 0, cr, translated_region);
+
         cairo_restore(cr);
     }
 }
Index: common/hippo/hippo-canvas-item.h
===================================================================
--- common/hippo/hippo-canvas-item.h	(revision 7296)
+++ common/hippo/hippo-canvas-item.h	(working copy)
@@ -3,6 +3,7 @@
 #define __HIPPO_CANVAS_ITEM_H__
 
 #include <cairo.h>
+#include <gdk/gdk.h>
 #include <hippo/hippo-event.h>
 #include <hippo/hippo-graphics.h>
 #include <hippo/hippo-canvas-context.h>
@@ -40,7 +41,7 @@
     HippoCanvasContainer*  (* get_parent)           (HippoCanvasItem *canvas_item);
     void                   (* paint)                (HippoCanvasItem *canvas_item,
                                                      cairo_t         *cr,
-                                                     HippoRectangle  *damaged_box);
+                                                     GdkRegion       *damaged_region);
     void                   (* get_width_request)    (HippoCanvasItem *canvas_item,
                                                      int             *min_width_p,
                                                      int             *natural_width_p);
@@ -161,7 +162,7 @@
                                                       int              allocation_y);
 void     hippo_canvas_item_process_paint             (HippoCanvasItem *canvas_item,
                                                       cairo_t         *cr,
-                                                      HippoRectangle  *damaged_box,
+                                                      GdkRegion       *damaged_region,
                                                       int              allocation_x,
                                                       int              allocation_y);
 
Index: Makefile-python.am
===================================================================
--- Makefile-python.am	(revision 7296)
+++ Makefile-python.am	(working copy)
@@ -40,6 +40,7 @@
 	    --load-types $(PYTHONSRCDIR)/arg-types.py \
             --register $(PYGTK_DEFSDIR)/pango.defs \
             --register $(PYGTK_DEFSDIR)/gtk-types.defs \
+            --register $(PYGTK_DEFSDIR)/gdk-types.defs \
 	    --override $(PYTHONSRCDIR)/hippo.override \
 	    --prefix pyhippo $(PYTHONSRCDIR)/hippo.defs) > gen-hippo.c \
 	&& cp gen-hippo.c $*.c \
Index: linux/hippo/hippo-canvas-helper.c
===================================================================
--- linux/hippo/hippo-canvas-helper.c	(revision 7296)
+++ linux/hippo/hippo-canvas-helper.c	(working copy)
@@ -468,15 +468,10 @@
 
     if (helper->root != NULL) {
         int window_x, window_y;
-        HippoRectangle damage_box;
     
         get_root_item_window_coords(helper, &window_x, &window_y);
 
-        damage_box.x = event->area.x;
-        damage_box.y = event->area.y;
-        damage_box.width = event->area.width;
-        damage_box.height = event->area.height;
-        hippo_canvas_item_process_paint(helper->root, cr, &damage_box,
+        hippo_canvas_item_process_paint(helper->root, cr, event->region,
                                         window_x, window_y);
     }
     
Index: linux/hippo/hippo-canvas-widget.c
===================================================================
--- linux/hippo/hippo-canvas-widget.c	(revision 7296)
+++ linux/hippo/hippo-canvas-widget.c	(working copy)
@@ -33,7 +33,7 @@
 /* Canvas box methods */
 static void hippo_canvas_widget_paint_below_children        (HippoCanvasBox  *box,
                                                              cairo_t         *cr,
-                                                             HippoRectangle  *damage_box);
+                                                             GdkRegion       *damaged_region);
 static void  hippo_canvas_widget_get_content_width_request  (HippoCanvasBox  *box,
                                                              int             *min_width_p,
                                                              int             *natural_width_p);
@@ -301,7 +301,7 @@
 static void
 hippo_canvas_widget_paint_below_children(HippoCanvasBox  *box,
                                          cairo_t         *cr,
-                                         HippoRectangle  *damage_box)
+                                         GdkRegion       *damaged_region)
 {
     HippoCanvasWidget *widget = HIPPO_CANVAS_WIDGET(box);
 


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