[gtk+/wip/simple-draw4: 12/20] gdkwindow: Change how paints work
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/simple-draw4: 12/20] gdkwindow: Change how paints work
- Date: Thu, 2 May 2013 17:16:59 +0000 (UTC)
commit 9c0bf55a1762400c74f60f28a7d8221e53099c68
Author: Alexander Larsson <alexl redhat com>
Date: Mon Apr 29 16:25:55 2013 +0200
gdkwindow: Change how paints work
First of all, we now only do paints on native windows, as there is
really no reason anymore to do it for subwindows. Secondly, we
keep track of the paints even for GtkPaintable windows, but for
that case we don't create the offscreen surface, but rather
assume the windowing system does the backing store.
gdk/gdkwindow.c | 160 ++++++++++++++++++++++++++++++-------------------------
1 files changed, 88 insertions(+), 72 deletions(-)
---
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 3086bb3..3b476e2 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -2716,12 +2716,16 @@ gdk_window_begin_paint_region (GdkWindow *window,
GdkRectangle clip_box;
GdkWindowPaint *paint;
GSList *list;
+ gboolean needs_surface;
g_return_if_fail (GDK_IS_WINDOW (window));
- if (GDK_WINDOW_DESTROYED (window))
+ if (GDK_WINDOW_DESTROYED (window) ||
+ !gdk_window_has_impl (window))
return;
+ needs_surface = TRUE;
+
if (GDK_IS_PAINTABLE (window->impl))
{
GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
@@ -2729,21 +2733,23 @@ gdk_window_begin_paint_region (GdkWindow *window,
if (iface->begin_paint_region)
iface->begin_paint_region ((GdkPaintable*)window->impl, window, region);
- return;
+ needs_surface = FALSE;
}
- paint = g_new (GdkWindowPaint, 1);
+ paint = g_new0 (GdkWindowPaint, 1);
paint->region = cairo_region_copy (region);
cairo_region_intersect (paint->region, window->clip_region);
cairo_region_get_extents (paint->region, &clip_box);
- paint->surface = gdk_window_create_similar_surface (window,
- gdk_window_get_content (window),
- MAX (clip_box.width, 1),
- MAX (clip_box.height, 1));
-
- cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
+ if (needs_surface)
+ {
+ paint->surface = gdk_window_create_similar_surface (window,
+ gdk_window_get_content (window),
+ MAX (clip_box.width, 1),
+ MAX (clip_box.height, 1));
+ cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
+ }
for (list = window->paint_stack; list != NULL; list = list->next)
{
@@ -2755,10 +2761,8 @@ gdk_window_begin_paint_region (GdkWindow *window,
window->paint_stack = g_slist_prepend (window->paint_stack, paint);
if (!cairo_region_is_empty (paint->region))
- {
- gdk_window_clear_backing_region (window,
- paint->region);
- }
+ gdk_window_clear_backing_region (window,
+ paint->region);
}
/**
@@ -2785,22 +2789,22 @@ gdk_window_end_paint (GdkWindow *window)
g_return_if_fail (GDK_IS_WINDOW (window));
- if (GDK_WINDOW_DESTROYED (window))
+ if (GDK_WINDOW_DESTROYED (window) ||
+ !gdk_window_has_impl (window))
return;
+ if (window->paint_stack == NULL)
+ {
+ g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
+ return;
+ }
+
if (GDK_IS_PAINTABLE (window->impl))
{
GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
if (iface->end_paint)
iface->end_paint ((GdkPaintable*)window->impl);
- return;
- }
-
- if (window->paint_stack == NULL)
- {
- g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
- return;
}
paint = window->paint_stack->data;
@@ -2808,30 +2812,35 @@ gdk_window_end_paint (GdkWindow *window)
window->paint_stack = g_slist_delete_link (window->paint_stack,
window->paint_stack);
- cairo_region_get_extents (paint->region, &clip_box);
- full_clip = cairo_region_copy (window->clip_region);
- cairo_region_intersect (full_clip, paint->region);
- cr = gdk_cairo_create (window);
- cairo_set_source_surface (cr, paint->surface, 0, 0);
- gdk_cairo_region (cr, full_clip);
- cairo_clip (cr);
- if (gdk_window_has_impl (window) ||
- window->alpha == 255)
- {
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
- }
- else
+ if (paint->surface != NULL)
{
- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
- cairo_paint_with_alpha (cr, window->alpha / 255.0);
- }
+ cairo_region_get_extents (paint->region, &clip_box);
+ full_clip = cairo_region_copy (window->clip_region);
+ cairo_region_intersect (full_clip, paint->region);
- cairo_destroy (cr);
- cairo_region_destroy (full_clip);
+ cr = gdk_cairo_create (window);
+ cairo_set_source_surface (cr, paint->surface, 0, 0);
+ gdk_cairo_region (cr, full_clip);
+ cairo_clip (cr);
+ if (gdk_window_has_impl (window) ||
+ window->alpha == 255)
+ {
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ }
+ else
+ {
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint_with_alpha (cr, window->alpha / 255.0);
+ }
+
+ cairo_destroy (cr);
+ cairo_region_destroy (full_clip);
+
+ cairo_surface_destroy (paint->surface);
+ }
- cairo_surface_destroy (paint->surface);
cairo_region_destroy (paint->region);
g_free (paint);
@@ -2870,7 +2879,8 @@ gdk_window_free_paint_stack (GdkWindow *window)
{
GdkWindowPaint *paint = tmp_list->data;
- if (tmp_list == window->paint_stack)
+ if (tmp_list == window->paint_stack &&
+ paint->surface != NULL)
cairo_surface_destroy (paint->surface);
cairo_region_destroy (paint->region);
@@ -2972,14 +2982,20 @@ gdk_window_get_visible_region (GdkWindow *window)
return cairo_region_copy (window->clip_region);
}
-static cairo_t *
-setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint)
+static void
+gdk_window_clear_backing_region (GdkWindow *window,
+ cairo_region_t *region)
{
+ GdkWindowPaint *paint = window->paint_stack->data;
+ cairo_region_t *clip;
GdkWindow *bg_window;
cairo_pattern_t *pattern = NULL;
int x_offset = 0, y_offset = 0;
cairo_t *cr;
+ if (GDK_WINDOW_DESTROYED (window) || paint->surface == NULL)
+ return;
+
cr = cairo_create (paint->surface);
for (bg_window = window; bg_window; bg_window = bg_window->parent)
@@ -3001,22 +3017,6 @@ setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint)
else
cairo_set_source_rgb (cr, 0, 0, 0);
- return cr;
-}
-
-static void
-gdk_window_clear_backing_region (GdkWindow *window,
- cairo_region_t *region)
-{
- GdkWindowPaint *paint = window->paint_stack->data;
- cairo_region_t *clip;
- cairo_t *cr;
-
- if (GDK_WINDOW_DESTROYED (window))
- return;
-
- cr = setup_backing_rect (window, paint);
-
clip = cairo_region_copy (paint->region);
cairo_region_intersect (clip, region);
@@ -3054,7 +3054,7 @@ gdk_window_create_cairo_surface (GdkWindow *window,
int height)
{
cairo_surface_t *surface, *subsurface;
-
+
surface = gdk_window_ref_impl_surface (window);
if (gdk_window_has_impl (window))
return surface;
@@ -3073,15 +3073,21 @@ cairo_surface_t *
_gdk_window_ref_cairo_surface (GdkWindow *window)
{
cairo_surface_t *surface;
+ GdkWindowPaint *paint;
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
- if (window->paint_stack)
- {
- GdkWindowPaint *paint = window->paint_stack->data;
+ paint = NULL;
+ if (window->impl_window->paint_stack)
+ paint = window->impl_window->paint_stack->data;
- surface = paint->surface;
- cairo_surface_reference (surface);
+ if (paint && paint->surface != NULL)
+ {
+ surface = cairo_surface_create_for_rectangle (paint->surface,
+ window->abs_x,
+ window->abs_y,
+ window->width,
+ window->height);
}
else
{
@@ -3125,20 +3131,30 @@ _gdk_window_ref_cairo_surface (GdkWindow *window)
cairo_t *
gdk_cairo_create (GdkWindow *window)
{
+ GdkWindowPaint *paint;
cairo_surface_t *surface;
+ cairo_region_t *region;
cairo_t *cr;
-
+
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
surface = _gdk_window_ref_cairo_surface (window);
cr = cairo_create (surface);
- if (!window->paint_stack)
+ if (window->impl_window->paint_stack)
{
- gdk_cairo_region (cr, window->clip_region);
- cairo_clip (cr);
- }
-
+ paint = window->impl_window->paint_stack->data;
+
+ region = cairo_region_copy (paint->region);
+ cairo_region_translate (region, -window->abs_x, -window->abs_y);
+ gdk_cairo_region (cr, region);
+ cairo_region_destroy (region);
+ }
+ else
+ gdk_cairo_region (cr, window->clip_region);
+
+ cairo_clip (cr);
+
cairo_surface_destroy (surface);
return cr;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]