[gtk+] Optimize clip-to-window with clipmask case when fully visible or obscured
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+] Optimize clip-to-window with clipmask case when fully visible or obscured
- Date: Tue, 7 Jul 2009 15:12:12 +0000 (UTC)
commit 52e3d2cf0e848d8956a6091c68b6d382cbbf4eb6
Author: Alexander Larsson <alexl redhat com>
Date: Tue Jul 7 15:14:16 2009 +0200
Optimize clip-to-window with clipmask case when fully visible or obscured
This avoids creating alot of bitmaps in common trivial cases.
gdk/gdkgc.c | 59 ++++++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 42 insertions(+), 17 deletions(-)
---
diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c
index 43e2a5f..699cebf 100644
--- a/gdk/gdkgc.c
+++ b/gdk/gdkgc.c
@@ -646,24 +646,49 @@ _gdk_gc_add_drawable_clip (GdkGC *gc,
GdkPixmap *new_mask;
GdkGC *tmp_gc;
GdkColor black = {0, 0, 0, 0};
+ GdkRectangle r;
+ GdkOverlapType overlap;
- priv->old_clip_mask = g_object_ref (priv->clip_mask);
- gdk_drawable_get_size (priv->old_clip_mask, &w, &h);
-
- new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1);
- tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE);
-
- gdk_gc_set_foreground (tmp_gc, &black);
- gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1);
- _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */
- gdk_draw_drawable (new_mask,
- tmp_gc,
- priv->old_clip_mask,
- 0, 0,
- 0, 0,
- -1, -1);
- gdk_gc_set_clip_region (tmp_gc, NULL);
- gdk_gc_set_clip_mask (gc, new_mask);
+ gdk_drawable_get_size (priv->clip_mask, &w, &h);
+
+ r.x = 0;
+ r.y = 0;
+ r.width = w;
+ r.height = h;
+
+ /* Its quite common to expose areas that are completely in or outside
+ * the region, so we try to avoid allocating bitmaps that are just fully
+ * set or completely unset.
+ */
+ overlap = gdk_region_rect_in (region, &r);
+ if (overlap == GDK_OVERLAP_RECTANGLE_PART)
+ {
+ /* The region and the mask intersect, create a new clip mask that
+ includes both areas */
+ priv->old_clip_mask = g_object_ref (priv->clip_mask);
+ new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1);
+ tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE);
+
+ gdk_gc_set_foreground (tmp_gc, &black);
+ gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1);
+ _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */
+ gdk_draw_drawable (new_mask,
+ tmp_gc,
+ priv->old_clip_mask,
+ 0, 0,
+ 0, 0,
+ -1, -1);
+ gdk_gc_set_clip_region (tmp_gc, NULL);
+ gdk_gc_set_clip_mask (gc, new_mask);
+ }
+ else if (overlap == GDK_OVERLAP_RECTANGLE_OUT)
+ {
+ GdkRegion *empty = gdk_region_new ();
+
+ priv->old_clip_mask = g_object_ref (priv->clip_mask);
+ _gdk_windowing_gc_set_clip_region (gc, empty, FALSE);
+ gdk_region_destroy (empty);
+ }
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]