summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2013-04-17 13:13:46 +0200
committerAlexander Larsson <alexl@redhat.com>2013-05-02 16:09:08 +0200
commit479b69a8bfe3654d9188660e5e7ea7a10c63b490 (patch)
tree91e2f43326fa8a0f2b60362069975d93c46fd423
parent7cecc8e524f9ac3825622e10f8a98f5e01ac4727 (diff)
downloadgtk+-479b69a8bfe3654d9188660e5e7ea7a10c63b490.tar.gz
gdk: Don't ever do copies from the window
This basically neuters gdk_window_move_region, gdk_window_scroll and gdk_window_move_resize, in that they now never copy any bits but just invalidate the source and destination regions. This is a performance loss, but the hope is that the simplifications it later allows will let us recover this performance loss (which mainly affects scrolling).
-rw-r--r--gdk/gdkwindow.c285
1 files changed, 9 insertions, 276 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 3f0a58f4f7..1d4687be16 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -6120,64 +6120,6 @@ move_native_children (GdkWindow *private)
}
}
-static gboolean
-collect_native_child_region_helper (GdkWindow *window,
- GdkWindowImpl *impl,
- cairo_region_t **region,
- int x_offset,
- int y_offset)
-{
- GdkWindow *child;
- cairo_region_t *tmp;
- GList *l;
-
- for (l = window->children; l != NULL; l = l->next)
- {
- child = l->data;
-
- if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
- continue;
-
- if (child->impl != impl)
- {
- tmp = cairo_region_copy (child->clip_region);
- cairo_region_translate (tmp,
- x_offset + child->x,
- y_offset + child->y);
- if (*region == NULL)
- *region = tmp;
- else
- {
- cairo_region_union (*region, tmp);
- cairo_region_destroy (tmp);
- }
- }
- else
- collect_native_child_region_helper (child, impl, region,
- x_offset + child->x,
- y_offset + child->y);
- }
-
- return FALSE;
-}
-
-static cairo_region_t *
-collect_native_child_region (GdkWindow *window,
- gboolean include_this)
-{
- cairo_region_t *region;
-
- if (include_this && gdk_window_has_impl (window) && window->viewable)
- return cairo_region_copy (window->clip_region);
-
- region = NULL;
-
- collect_native_child_region_helper (window, window->impl, &region, 0, 0);
-
- return region;
-}
-
-
static void
gdk_window_move_resize_internal (GdkWindow *window,
gboolean with_move,
@@ -6186,13 +6128,10 @@ gdk_window_move_resize_internal (GdkWindow *window,
gint width,
gint height)
{
- cairo_region_t *old_region, *old_layered, *new_region, *copy_area;
- cairo_region_t *old_native_child_region, *new_native_child_region;
- GdkWindow *impl_window;
+ cairo_region_t *old_region, *new_region;
GdkWindowImplClass *impl_class;
gboolean expose;
- int old_x, old_y, old_abs_x, old_abs_y;
- int dx, dy;
+ int old_abs_x, old_abs_y;
g_return_if_fail (GDK_IS_WINDOW (window));
@@ -6217,39 +6156,15 @@ gdk_window_move_resize_internal (GdkWindow *window,
expose = FALSE;
old_region = NULL;
- old_layered = NULL;
-
- impl_window = gdk_window_get_impl_window (window);
-
- old_x = window->x;
- old_y = window->y;
- old_native_child_region = NULL;
if (gdk_window_is_viewable (window) &&
!window->input_only)
{
expose = TRUE;
old_region = cairo_region_copy (window->clip_region);
- old_layered = cairo_region_copy (window->layered_region);
/* Adjust regions to parent window coords */
cairo_region_translate (old_region, window->x, window->y);
- cairo_region_translate (old_layered, window->x, window->y);
-
- old_native_child_region = collect_native_child_region (window, TRUE);
- if (old_native_child_region)
- {
- /* Adjust region to parent window coords */
- cairo_region_translate (old_native_child_region, window->x, window->y);
-
- /* Any native window move will immediately copy stuff to the destination, which may overwrite a
- * source or destination for a delayed GdkWindowRegionMove. So, we need
- * to flush those here for the parent window and all overlapped subwindows
- * of it. And we need to do this before setting the new clips as those will be
- * affecting this.
- */
- gdk_window_flush_recursive (window->parent);
- }
}
/* Set the new position and size */
@@ -6268,22 +6183,11 @@ gdk_window_move_resize_internal (GdkWindow *window,
window->height = height;
}
- dx = window->x - old_x;
- dy = window->y - old_y;
-
old_abs_x = window->abs_x;
old_abs_y = window->abs_y;
recompute_visible_regions (window, TRUE, FALSE);
- new_native_child_region = NULL;
- if (old_native_child_region)
- {
- new_native_child_region = collect_native_child_region (window, TRUE);
- /* Adjust region to parent window coords */
- cairo_region_translate (new_native_child_region, window->x, window->y);
- }
-
if (gdk_window_has_impl (window))
{
impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
@@ -6304,87 +6208,14 @@ gdk_window_move_resize_internal (GdkWindow *window,
/* Adjust region to parent window coords */
cairo_region_translate (new_region, window->x, window->y);
- /* copy_area:
- * Part of the data at the new location can be copied from the
- * old location, this area is the intersection of the old region
- * moved as the copy will move it and then intersected with
- * the new region.
- *
- * new_region:
- * Everything in the old and new regions that is not copied must be
- * invalidated (including children) as this is newly exposed
- */
- if (gdk_window_has_alpha (window))
- copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
- else
- copy_area = cairo_region_copy (new_region);
-
- /* Don't copy from a previously layered region */
- cairo_region_translate (old_layered, dx, dy);
- cairo_region_subtract (copy_area, old_layered);
-
- /* Don't copy into a layered region */
- cairo_region_translate (copy_area, -window->x, -window->y);
- cairo_region_subtract (copy_area, window->layered_region);
- cairo_region_translate (copy_area, window->x, window->y);
-
cairo_region_union (new_region, old_region);
- if (old_native_child_region)
- {
- /* Don't copy from inside native children, as this is copied by
- * the native window move.
- */
- cairo_region_subtract (old_region, old_native_child_region);
- }
- cairo_region_translate (old_region, dx, dy);
-
- cairo_region_intersect (copy_area, old_region);
-
- if (new_native_child_region)
- {
- /* Don't copy any bits that would cause a read from the moved
- native windows, as we can't read that data */
- cairo_region_translate (new_native_child_region, dx, dy);
- cairo_region_subtract (copy_area, new_native_child_region);
- cairo_region_translate (new_native_child_region, -dx, -dy);
- }
-
- cairo_region_subtract (new_region, copy_area);
-
- /* Convert old region to impl coords */
- cairo_region_translate (old_region, -dx + window->abs_x - window->x, -dy + window->abs_y - window->y);
-
- /* convert from parent coords to impl */
- cairo_region_translate (copy_area, window->abs_x - window->x, window->abs_y - window->y);
-
- move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
-
- /* Invalidate affected part in the parent window
- * (no higher window should be affected)
- * We also invalidate any children in that area, which could include
- * this window if it still overlaps that area.
- */
- if (old_native_child_region)
- {
- /* No need to expose the region that the native window move copies */
- cairo_region_translate (old_native_child_region, dx, dy);
- cairo_region_intersect (old_native_child_region, new_native_child_region);
- cairo_region_subtract (new_region, old_native_child_region);
- }
gdk_window_invalidate_region_full (window->parent, new_region, TRUE, CLEAR_BG_ALL);
cairo_region_destroy (old_region);
- cairo_region_destroy (old_layered);
cairo_region_destroy (new_region);
}
- if (old_native_child_region)
- {
- cairo_region_destroy (old_native_child_region);
- cairo_region_destroy (new_native_child_region);
- }
-
_gdk_synthesize_crossing_events_for_geometry_change (window);
}
@@ -6484,9 +6315,6 @@ gdk_window_scroll (GdkWindow *window,
gint dx,
gint dy)
{
- GdkWindow *impl_window;
- cairo_region_t *copy_area, *noncopy_area, *old_layered_area;
- cairo_region_t *old_native_child_region, *new_native_child_region;
GList *tmp_list;
g_return_if_fail (GDK_IS_WINDOW (window));
@@ -6497,20 +6325,6 @@ gdk_window_scroll (GdkWindow *window,
if (window->destroyed)
return;
- old_layered_area = cairo_region_copy (window->layered_region);
- old_native_child_region = collect_native_child_region (window, FALSE);
- if (old_native_child_region)
- {
- /* Any native window move will immediately copy stuff to the destination, which may overwrite a
- * source or destination for a delayed GdkWindowRegionMove. So, we need
- * to flush those here for the window and all overlapped subwindows
- * of it. And we need to do this before setting the new clips as those will be
- * affecting this.
- */
- gdk_window_flush_recursive (window);
- }
-
-
/* First move all child windows, without causing invalidation */
tmp_list = window->children;
@@ -6527,64 +6341,9 @@ gdk_window_scroll (GdkWindow *window,
recompute_visible_regions (window, FALSE, TRUE);
- new_native_child_region = NULL;
- if (old_native_child_region)
- new_native_child_region = collect_native_child_region (window, FALSE);
-
move_native_children (window);
- /* Then copy the actual bits of the window w/ child windows */
-
- impl_window = gdk_window_get_impl_window (window);
-
- /* Calculate the area that can be gotten by copying the old area */
- if (gdk_window_has_alpha (window))
- copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
- else
- copy_area = cairo_region_copy (window->clip_region);
- cairo_region_subtract (copy_area, old_layered_area);
- if (old_native_child_region)
- {
- /* Don't copy from inside native children, as this is copied by
- * the native window move.
- */
- cairo_region_subtract (copy_area, old_native_child_region);
-
- /* Don't copy any bits that would cause a read from the moved
- native windows, as we can't read that data */
- cairo_region_subtract (copy_area, new_native_child_region);
- }
- cairo_region_translate (copy_area, dx, dy);
- cairo_region_intersect (copy_area, window->clip_region);
- cairo_region_subtract (copy_area, window->layered_region);
-
- /* And the rest need to be invalidated */
- noncopy_area = cairo_region_copy (window->clip_region);
- cairo_region_subtract (noncopy_area, copy_area);
-
- /* convert from window coords to impl */
- cairo_region_translate (copy_area, window->abs_x, window->abs_y);
-
- move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
-
- /* Invalidate not copied regions */
- if (old_native_child_region)
- {
- /* No need to expose the region that the native window move copies */
- cairo_region_translate (old_native_child_region, dx, dy);
- cairo_region_intersect (old_native_child_region, new_native_child_region);
- cairo_region_subtract (noncopy_area, old_native_child_region);
- }
- gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
-
- cairo_region_destroy (noncopy_area);
- cairo_region_destroy (old_layered_area);
-
- if (old_native_child_region)
- {
- cairo_region_destroy (old_native_child_region);
- cairo_region_destroy (new_native_child_region);
- }
+ gdk_window_invalidate_region_full (window, window->clip_region, TRUE, CLEAR_BG_ALL);
_gdk_synthesize_crossing_events_for_geometry_change (window);
}
@@ -6610,9 +6369,7 @@ gdk_window_move_region (GdkWindow *window,
gint dx,
gint dy)
{
- GdkWindow *impl_window;
- cairo_region_t *nocopy_area;
- cairo_region_t *copy_area;
+ cairo_region_t *expose_area;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (region != NULL);
@@ -6623,36 +6380,12 @@ gdk_window_move_region (GdkWindow *window,
if (window->destroyed)
return;
- impl_window = gdk_window_get_impl_window (window);
+ expose_area = cairo_region_copy (region);
+ cairo_region_translate (expose_area, dx, dy);
+ cairo_region_union (expose_area, region);
- /* compute source regions */
- if (gdk_window_has_alpha (window))
- copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
- else
- copy_area = cairo_region_copy (region);
- cairo_region_intersect (copy_area, window->clip_region_with_children);
- cairo_region_subtract (copy_area, window->layered_region);
- remove_layered_child_area (window, copy_area);
-
- /* compute destination regions */
- cairo_region_translate (copy_area, dx, dy);
- cairo_region_intersect (copy_area, window->clip_region_with_children);
- cairo_region_subtract (copy_area, window->layered_region);
- remove_layered_child_area (window, copy_area);
-
- /* Invalidate parts of the region (source and dest) not covered
- by the copy */
- nocopy_area = cairo_region_copy (region);
- cairo_region_translate (nocopy_area, dx, dy);
- cairo_region_union (nocopy_area, region);
- cairo_region_subtract (nocopy_area, copy_area);
-
- /* convert from window coords to impl */
- cairo_region_translate (copy_area, window->abs_x, window->abs_y);
- move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
-
- gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
- cairo_region_destroy (nocopy_area);
+ gdk_window_invalidate_region_full (window, expose_area, FALSE, CLEAR_BG_ALL);
+ cairo_region_destroy (expose_area);
}
/**