diff options
author | Benjamin Otte <otte@redhat.com> | 2010-07-25 18:13:19 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-07-26 16:42:49 +0200 |
commit | b478081b7dcda24496b03aaf21b282657d842d50 (patch) | |
tree | 6e02f9e3375476acf79a333ae2570b55933b8861 | |
parent | 331d77f3d7a4722bfde04a8d51fee3f6b6a12a09 (diff) | |
download | gtk+-b478081b7dcda24496b03aaf21b282657d842d50.tar.gz |
gdk: Always clear backing store with Cairo
The code to use Cairo existed but wasn't used on Unix due to a bug in
XAA (that was fixed). Fwiw, we use EXA these days...
-rw-r--r-- | gdk/gdkwindow.c | 159 |
1 files changed, 25 insertions, 134 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 46841be741..c899cbca49 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -4503,15 +4503,11 @@ gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, END_DRAW; } -typedef struct { - cairo_t *cr; /* if non-null, it means use this cairo context */ - GdkGC *gc; /* if non-null, it means use this GC instead */ -} BackingRectMethod; - -static void -setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo) +static cairo_t * +setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo) { GdkWindowObject *private = (GdkWindowObject *)window; + cairo_t *cr; if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) { @@ -4524,28 +4520,12 @@ setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWind x_offset_cairo += private->x; y_offset_cairo += private->y; - setup_backing_rect_method (method, GDK_WINDOW (private->parent), &tmp_paint, x_offset_cairo, y_offset_cairo); + cr = setup_backing_rect (GDK_WINDOW (private->parent), &tmp_paint, x_offset_cairo, y_offset_cairo); } else if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && private->bg_pixmap != GDK_NO_BG) { -/* This is a workaround for https://bugs.freedesktop.org/show_bug.cgi?id=4320. - * In it, using a pixmap as a repeating pattern in Cairo, and painting it to a - * pixmap destination surface, can be very slow (on the order of seconds for a - * whole-screen copy). The workaround is to use pretty much the same code that - * we used in GTK+ 2.6 (pre-Cairo), which clears the double-buffer pixmap with - * a tiled GC XFillRectangle(). - */ - -/* Actually computing this flag is left as an exercise for the reader */ -#if defined (G_OS_UNIX) -# define GDK_CAIRO_REPEAT_IS_FAST 0 -#else -# define GDK_CAIRO_REPEAT_IS_FAST 1 -#endif - -#if GDK_CAIRO_REPEAT_IS_FAST cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap); cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); cairo_surface_destroy (surface); @@ -4559,31 +4539,19 @@ setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWind cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); - method->cr = cairo_create (paint->surface); - method->gc = NULL; + cr = cairo_create (paint->surface); - cairo_set_source (method->cr, pattern); + cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); -#else - guint gc_mask; - GdkGCValues gc_values; - - gc_values.fill = GDK_TILED; - gc_values.tile = private->bg_pixmap; - gc_values.ts_x_origin = -x_offset_cairo; - gc_values.ts_y_origin = -y_offset_cairo; - - gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; - - method->gc = gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask); -#endif } else { - method->cr = cairo_create (paint->surface); + cr = cairo_create (paint->surface); - gdk_cairo_set_source_color (method->cr, &private->bg_color); + gdk_cairo_set_source_color (cr, &private->bg_color); } + + return cr; } static void @@ -4592,64 +4560,25 @@ gdk_window_clear_backing_region (GdkWindow *window, { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowPaint *paint = private->paint_stack->data; - BackingRectMethod method; cairo_region_t *clip; GdkRectangle clipbox; -#if 0 - GTimer *timer; - double elapsed; -#endif + cairo_t *cr; if (GDK_WINDOW_DESTROYED (window)) return; -#if 0 - timer = g_timer_new (); -#endif - - method.cr = NULL; - method.gc = NULL; - setup_backing_rect_method (&method, window, paint, 0, 0); + cr = setup_backing_rect (window, paint, 0, 0); clip = cairo_region_copy (paint->region); cairo_region_intersect (clip, region); cairo_region_get_extents (clip, &clipbox); + gdk_cairo_region (cr, clip); + cairo_fill (cr); - if (method.cr) - { - g_assert (method.gc == NULL); - - gdk_cairo_region (method.cr, clip); - cairo_fill (method.cr); - - cairo_destroy (method.cr); -#if 0 - elapsed = g_timer_elapsed (timer, NULL); - g_print ("Draw the background with Cairo: %fs\n", elapsed); -#endif - } - else - { - g_assert (method.gc != NULL); - - gdk_gc_set_clip_region (method.gc, clip); - gdk_draw_rectangle (window, method.gc, TRUE, - clipbox.x, clipbox.y, - clipbox.width, clipbox.height); - g_object_unref (method.gc); - -#if 0 - elapsed = g_timer_elapsed (timer, NULL); - g_print ("Draw the background with GDK: %fs\n", elapsed); -#endif - } + cairo_destroy (cr); cairo_region_destroy (clip); - -#if 0 - g_timer_destroy (timer); -#endif } static void @@ -4661,8 +4590,8 @@ gdk_window_clear_backing_region_redirect (GdkWindow *window, cairo_region_t *clip_region; GdkRectangle clipbox; gint x_offset, y_offset; - BackingRectMethod method; GdkWindowPaint paint; + cairo_t *cr; if (GDK_WINDOW_DESTROYED (window)) return; @@ -4686,32 +4615,12 @@ gdk_window_clear_backing_region_redirect (GdkWindow *window, paint.pixmap = redirect->pixmap; paint.surface = _gdk_drawable_ref_cairo_surface (redirect->pixmap); - method.cr = NULL; - method.gc = NULL; - setup_backing_rect_method (&method, window, &paint, -x_offset, -y_offset); - - if (method.cr) - { - g_assert (method.gc == NULL); - - gdk_cairo_region (method.cr, clip_region); - cairo_fill (method.cr); - - cairo_destroy (method.cr); - } - else - { - g_assert (method.gc != NULL); - - cairo_region_get_extents (clip_region, &clipbox); - gdk_gc_set_clip_region (method.gc, clip_region); - gdk_draw_rectangle (redirect->pixmap, method.gc, TRUE, - clipbox.x, clipbox.y, - clipbox.width, clipbox.height); - g_object_unref (method.gc); + cr = setup_backing_rect (window, &paint, -x_offset, -y_offset); - } + gdk_cairo_region (cr, clip_region); + cairo_fill (cr); + cairo_destroy (cr); cairo_region_destroy (clip_region); cairo_surface_destroy (paint.surface); } @@ -4721,10 +4630,10 @@ gdk_window_clear_backing_region_direct (GdkWindow *window, cairo_region_t *region) { GdkWindowObject *private = (GdkWindowObject *)window; - BackingRectMethod method; GdkWindowPaint paint; cairo_region_t *clip; GdkRectangle clipbox; + cairo_t *cr; if (GDK_WINDOW_DESTROYED (window)) return; @@ -4734,34 +4643,16 @@ gdk_window_clear_backing_region_direct (GdkWindow *window, paint.pixmap = window; paint.surface = _gdk_drawable_ref_cairo_surface (window); - method.cr = NULL; - method.gc = NULL; - setup_backing_rect_method (&method, window, &paint, 0, 0); + cr = setup_backing_rect (window, &paint, 0, 0); clip = cairo_region_copy (private->clip_region_with_children); cairo_region_intersect (clip, region); cairo_region_get_extents (clip, &clipbox); - if (method.cr) - { - g_assert (method.gc == NULL); - - gdk_cairo_region (method.cr, clip); - cairo_fill (method.cr); + gdk_cairo_region (cr, clip); + cairo_fill (cr); - cairo_destroy (method.cr); - } - else - { - g_assert (method.gc != NULL); - - gdk_gc_set_clip_region (method.gc, clip); - gdk_draw_rectangle (window, method.gc, TRUE, - clipbox.x, clipbox.y, - clipbox.width, clipbox.height); - g_object_unref (method.gc); - - } + cairo_destroy (cr); cairo_region_destroy (clip); cairo_surface_destroy (paint.surface); |