From 864649157dd98ba8d86e0fd3561ea7345c00893d Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 4 Dec 2008 20:55:44 +0100 Subject: [PATCH] Move _gdk_gc_remove_drawable_clip from after each time its set to before each pixmap set and when adding a new different region This means we can avoid changing the clip if we're drawing with the same gc to the same clip region --- gdk/gdkgc.c | 13 +++++++++- gdk/gdkoffscreenwindow.c | 30 +++++++++++++-------- gdk/gdkpixmap.c | 14 ++++++++++ gdk/gdkwindow.c | 56 +++++++++++++++++++++++++--------------- 4 files changed, 80 insertions(+), 33 deletions(-) diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c index 355a346132..a85a3b77c6 100644 --- a/gdk/gdkgc.c +++ b/gdk/gdkgc.c @@ -44,6 +44,8 @@ struct _GdkGCPrivate GdkRegion *clip_region; guint32 region_tag_applied; + int region_tag_offset_x; + int region_tag_offset_y; GdkRegion *old_clip_region; @@ -597,9 +599,18 @@ _gdk_gc_add_drawable_clip (GdkGC *gc, { GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); - g_assert (priv->old_clip_region == NULL); + if (priv->region_tag_applied == region_tag && + offset_x == priv->region_tag_offset_x && + offset_y == priv->region_tag_offset_y) + return; /* Already appied this drawable region */ + if (priv->region_tag_applied) + _gdk_gc_remove_drawable_clip (gc); + priv->region_tag_applied = region_tag; + priv->region_tag_offset_x = offset_x; + priv->region_tag_offset_y = offset_y; + priv->old_clip_region = priv->clip_region; region = gdk_region_copy (region); diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c index 4055c5a6bc..72bb5b62c6 100644 --- a/gdk/gdkoffscreenwindow.c +++ b/gdk/gdkoffscreenwindow.c @@ -275,6 +275,14 @@ add_damage (GdkOffscreenWindow *offscreen, gdk_region_destroy (damage); } +static GdkDrawable * +get_real_drawable (GdkOffscreenWindow *offscreen) +{ + GdkPixmapObject *pixmap; + pixmap = (GdkPixmapObject *) offscreen->pixmap; + return GDK_DRAWABLE (pixmap->impl); +} + static void gdk_offscreen_window_draw_drawable (GdkDrawable *drawable, GdkGC *gc, @@ -287,7 +295,7 @@ gdk_offscreen_window_draw_drawable (GdkDrawable *drawable, gint height) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_drawable (real_drawable, gc, src, xsrc, ysrc, @@ -307,7 +315,7 @@ gdk_offscreen_window_draw_rectangle (GdkDrawable *drawable, gint height) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_rectangle (real_drawable, gc, filled, x, y, width, height); @@ -328,7 +336,7 @@ gdk_offscreen_window_draw_arc (GdkDrawable *drawable, gint angle2) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_arc (real_drawable, gc, @@ -350,7 +358,7 @@ gdk_offscreen_window_draw_polygon (GdkDrawable *drawable, gint npoints) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_polygon (real_drawable, gc, @@ -389,7 +397,7 @@ gdk_offscreen_window_draw_text (GdkDrawable *drawable, gint text_length) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); gdk_draw_text (real_drawable, @@ -414,7 +422,7 @@ gdk_offscreen_window_draw_text_wc (GdkDrawable *drawable, gint text_length) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); gdk_draw_text_wc (real_drawable, @@ -436,7 +444,7 @@ gdk_offscreen_window_draw_points (GdkDrawable *drawable, gint npoints) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_points (real_drawable, gc, @@ -472,7 +480,7 @@ gdk_offscreen_window_draw_segments (GdkDrawable *drawable, gint nsegs) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_segments (real_drawable, gc, @@ -512,7 +520,7 @@ gdk_offscreen_window_draw_lines (GdkDrawable *drawable, gint npoints) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); gdk_draw_lines (real_drawable, @@ -538,7 +546,7 @@ gdk_offscreen_window_draw_image (GdkDrawable *drawable, gint height) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_image (real_drawable, gc, @@ -569,7 +577,7 @@ gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable, gint y_dither) { GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); - GdkDrawable *real_drawable = GDK_DRAWABLE (offscreen->pixmap); + GdkDrawable *real_drawable = get_real_drawable (offscreen); gdk_draw_pixbuf (real_drawable, gc, diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c index 806a5ca8d5..cb99cb76ab 100644 --- a/gdk/gdkpixmap.c +++ b/gdk/gdkpixmap.c @@ -291,6 +291,7 @@ gdk_pixmap_draw_rectangle (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_rectangle (private->impl, gc, filled, x, y, width, height); } @@ -308,6 +309,7 @@ gdk_pixmap_draw_arc (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_arc (private->impl, gc, filled, x, y, width, height, angle1, angle2); @@ -322,6 +324,7 @@ gdk_pixmap_draw_polygon (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_polygon (private->impl, gc, filled, points, npoints); } @@ -336,6 +339,7 @@ gdk_pixmap_draw_text (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_text (private->impl, font, gc, x, y, text, text_length); } @@ -351,6 +355,7 @@ gdk_pixmap_draw_text_wc (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_text_wc (private->impl, font, gc, x, y, text, text_length); } @@ -368,6 +373,7 @@ gdk_pixmap_draw_drawable (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_drawable (private->impl, gc, src, xsrc, ysrc, xdest, ydest, width, height); @@ -381,6 +387,7 @@ gdk_pixmap_draw_points (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_points (private->impl, gc, points, npoints); } @@ -392,6 +399,7 @@ gdk_pixmap_draw_segments (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_segments (private->impl, gc, segs, nsegs); } @@ -403,6 +411,7 @@ gdk_pixmap_draw_lines (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_lines (private->impl, gc, points, npoints); } @@ -416,6 +425,7 @@ gdk_pixmap_draw_glyphs (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_glyphs (private->impl, gc, font, x, y, glyphs); } @@ -430,6 +440,7 @@ gdk_pixmap_draw_glyphs_transformed (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_glyphs_transformed (private->impl, gc, matrix, font, x, y, glyphs); } @@ -446,6 +457,7 @@ gdk_pixmap_draw_image (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_image (private->impl, gc, image, xsrc, ysrc, xdest, ydest, width, height); } @@ -466,6 +478,7 @@ gdk_pixmap_draw_pixbuf (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y, dest_x, dest_y, width, height, dither, x_dither, y_dither); @@ -479,6 +492,7 @@ gdk_pixmap_draw_trapezoids (GdkDrawable *drawable, { GdkPixmapObject *private = (GdkPixmapObject *)drawable; + _gdk_gc_remove_drawable_clip (gc); gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids); } diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 7043b8385d..6611f49449 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -460,7 +460,7 @@ recompute_visible_regions_internal (GdkWindowObject *private, GdkRectangle r; GList *l; GdkWindowObject *child; - GdkRegion *new_clip; + GdkRegion *new_clip, *old_clip_region_with_children; gboolean clip_region_changed; gboolean abs_pos_changed; int old_abs_x, old_abs_y; @@ -518,10 +518,17 @@ recompute_visible_regions_internal (GdkWindowObject *private, if (private->clip_region) gdk_region_destroy (private->clip_region); private->clip_region = new_clip; - private->clip_tag = new_region_tag (); + old_clip_region_with_children = private->clip_region_with_children; private->clip_region_with_children = gdk_region_copy (private->clip_region); remove_child_area (private, NULL, private->clip_region_with_children); + + if (clip_region_changed || + !gdk_region_equal (private->clip_region_with_children, old_clip_region_with_children)) + private->clip_tag = new_region_tag (); + + if (old_clip_region_with_children) + gdk_region_destroy (old_clip_region_with_children); } /* Update all children, recursively. */ @@ -2333,17 +2340,14 @@ setup_clip_for_paint (GdkDrawable *drawable, setup_clip_for_paint (drawable, paint, gc, old_clip_x, \ old_clip_y); -#define RESTORE_PAINT_GC_CLIP(gc) \ - if (paint->uses_implicit) \ - _gdk_gc_remove_drawable_clip (gc); +#define RESTORE_PAINT_GC_CLIP(gc) #define SETUP_DIRECT_GC_CLIP(gc) \ gdk_window_flush_implicit_paint ((GdkWindow *)drawable);\ setup_clip_for_draw (drawable, gc, old_clip_x, old_clip_y); -#define RESTORE_DIRECT_GC_CLIP(gc) \ - _gdk_gc_remove_drawable_clip (gc); +#define RESTORE_DIRECT_GC_CLIP(gc) static GdkGC * gdk_window_create_gc (GdkDrawable *drawable, @@ -2359,6 +2363,16 @@ gdk_window_create_gc (GdkDrawable *drawable, values, mask); } +/* After having set up the drawable clip rect on a GC we need + * to make sure that if we draw to a pixmap we draw to the impl, + * otherwise the pixmap code will reset the drawable clip. + */ +static GdkDrawable * +pixmap_impl (GdkPixmap *pixmap) +{ + return ((GdkPixmapObject *)pixmap)->impl; +} + static void gdk_window_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, @@ -2378,7 +2392,7 @@ gdk_window_draw_rectangle (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_rectangle (paint->pixmap, gc, filled, + gdk_draw_rectangle (pixmap_impl (paint->pixmap), gc, filled, x - x_offset, y - y_offset, width, height); RESTORE_PAINT_GC_CLIP (gc); } @@ -2414,7 +2428,7 @@ gdk_window_draw_arc (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_arc (paint->pixmap, gc, filled, + gdk_draw_arc (pixmap_impl (paint->pixmap), gc, filled, x - x_offset, y - y_offset, width, height, angle1, angle2); RESTORE_PAINT_GC_CLIP (gc); @@ -2463,7 +2477,7 @@ gdk_window_draw_polygon (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_polygon (paint->pixmap, gc, filled, new_points, npoints); + gdk_draw_polygon (pixmap_impl (paint->pixmap), gc, filled, new_points, npoints); RESTORE_PAINT_GC_CLIP (gc); } else @@ -2498,7 +2512,7 @@ gdk_window_draw_text (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_text (paint->pixmap, font, gc, + gdk_draw_text (pixmap_impl (paint->pixmap), font, gc, x - x_offset, y - y_offset, text, text_length); RESTORE_PAINT_GC_CLIP (gc); @@ -2533,7 +2547,7 @@ gdk_window_draw_text_wc (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_text_wc (paint->pixmap, font, gc, + gdk_draw_text_wc (pixmap_impl (paint->pixmap), font, gc, x - x_offset, y - y_offset, text, text_length); RESTORE_PAINT_GC_CLIP (gc); } @@ -2754,7 +2768,7 @@ gdk_window_draw_drawable (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_drawable (paint->pixmap, gc, + gdk_draw_drawable (pixmap_impl (paint->pixmap), gc, src, xsrc, ysrc, xdest - x_offset, ydest - y_offset, width, height); @@ -2805,7 +2819,7 @@ gdk_window_draw_points (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_points (paint->pixmap, gc, new_points, npoints); + gdk_draw_points (pixmap_impl (paint->pixmap), gc, new_points, npoints); RESTORE_PAINT_GC_CLIP (gc); } else @@ -2855,7 +2869,7 @@ gdk_window_draw_segments (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_segments (paint->pixmap, gc, new_segs, nsegs); + gdk_draw_segments (pixmap_impl (paint->pixmap), gc, new_segs, nsegs); RESTORE_PAINT_GC_CLIP (gc); } else @@ -2903,7 +2917,7 @@ gdk_window_draw_lines (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_lines (paint->pixmap, gc, new_points, npoints); + gdk_draw_lines (pixmap_impl (paint->pixmap), gc, new_points, npoints); RESTORE_PAINT_GC_CLIP (gc); } else @@ -2939,7 +2953,7 @@ gdk_window_draw_glyphs (GdkDrawable *drawable, GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_glyphs (paint->pixmap, gc, font, x - x_offset, y - y_offset, glyphs); + gdk_draw_glyphs (pixmap_impl (paint->pixmap), gc, font, x - x_offset, y - y_offset, glyphs); RESTORE_PAINT_GC_CLIP (gc); } else @@ -3000,7 +3014,7 @@ gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_glyphs_transformed (paint->pixmap, gc, matrix, font, x, y, glyphs); + gdk_draw_glyphs_transformed (pixmap_impl (paint->pixmap), gc, matrix, font, x, y, glyphs); RESTORE_PAINT_GC_CLIP (gc); } else @@ -3393,7 +3407,7 @@ gdk_window_draw_image (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_image (paint->pixmap, gc, image, xsrc, ysrc, + gdk_draw_image (pixmap_impl (paint->pixmap), gc, image, xsrc, ysrc, xdest - x_offset, ydest - y_offset, width, height); @@ -3438,7 +3452,7 @@ gdk_window_draw_pixbuf (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y, + gdk_draw_pixbuf (pixmap_impl (paint->pixmap), gc, pixbuf, src_x, src_y, dest_x - x_offset, dest_y - y_offset, width, height, dither, x_dither - x_offset, y_dither - y_offset); @@ -3517,7 +3531,7 @@ gdk_window_draw_trapezoids (GdkDrawable *drawable, { GdkWindowPaint *paint = private->paint_stack->data; SETUP_PAINT_GC_CLIP (gc); - gdk_draw_trapezoids (paint->pixmap, gc, trapezoids, n_trapezoids); + gdk_draw_trapezoids (pixmap_impl (paint->pixmap), gc, trapezoids, n_trapezoids); RESTORE_PAINT_GC_CLIP (gc); } else