From 56fb7e2c58ff53f7e2b3db3270017fc3fd7a4fe4 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sat, 27 Nov 2010 20:46:05 +0100 Subject: [PATCH] St: Take advantage of clipped redraws In order to take advantage of clipped redraws (only redraw the parts that actually changed), we have to inform clutter about our paint_volume by implementing the get_paint_volume virtual method. As this feature had been added in in clutter 1.5.x we now require that. https://bugzilla.gnome.org/show_bug.cgi?id=630932 --- configure.ac | 2 +- src/shell-generic-container.c | 29 +++++++++++++++++++++++++++++ src/st/st-group.c | 28 ++++++++++++++++++++++++++++ src/st/st-widget.c | 27 +++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 519d02825..c5d5a8920 100644 --- a/configure.ac +++ b/configure.ac @@ -57,7 +57,7 @@ fi AM_CONDITIONAL(BUILD_RECORDER, $build_recorder) -CLUTTER_MIN_VERSION=1.3.14 +CLUTTER_MIN_VERSION=1.5.8 GOBJECT_INTROSPECTION_MIN_VERSION=0.6.11 GJS_MIN_VERSION=0.7 MUTTER_MIN_VERSION=2.91.0 diff --git a/src/shell-generic-container.c b/src/shell-generic-container.c index e378d7211..8be3a96c5 100644 --- a/src/shell-generic-container.c +++ b/src/shell-generic-container.c @@ -245,6 +245,34 @@ shell_generic_container_finalize (GObject *object) G_OBJECT_CLASS (shell_generic_container_parent_class)->finalize (object); } +/* Based on implementation from clutter-group.c */ +static gboolean +shell_generic_container_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + GList *l, *children; + + children = st_container_get_children_list (ST_CONTAINER (actor)); + + CLUTTER_ACTOR_CLASS (shell_generic_container_parent_class)->get_paint_volume (actor, volume); + + for (l = children; l != NULL; l = l->next) + { + ClutterActor *child = l->data; + const ClutterPaintVolume *child_volume; + + /* This gets the paint volume of the child transformed into the + * group's coordinate space... */ + child_volume = clutter_actor_get_transformed_paint_volume (child, actor); + if (!child_volume) + return FALSE; + + clutter_paint_volume_union (volume, child_volume); + } + + return TRUE; +} + static void shell_generic_container_class_init (ShellGenericContainerClass *klass) { @@ -257,6 +285,7 @@ shell_generic_container_class_init (ShellGenericContainerClass *klass) actor_class->get_preferred_width = shell_generic_container_get_preferred_width; actor_class->get_preferred_height = shell_generic_container_get_preferred_height; actor_class->allocate = shell_generic_container_allocate; + actor_class->get_paint_volume = shell_generic_container_get_paint_volume; actor_class->paint = shell_generic_container_paint; actor_class->pick = shell_generic_container_pick; diff --git a/src/st/st-group.c b/src/st/st-group.c index b981de056..502957b03 100644 --- a/src/st/st-group.c +++ b/src/st/st-group.c @@ -3,6 +3,7 @@ * st-group.c: A fixed layout container based on ClutterGroup * * Copyright 2010 Florian Müllner + * Copyright 2010 Intel Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU Lesser General Public License, @@ -230,7 +231,33 @@ st_group_hide_all (ClutterActor *actor) NULL); } +/* Based on implementation from clutter-group.c */ +static gboolean +st_group_get_paint_volume (ClutterActor *actor, + ClutterPaintVolume *volume) +{ + GList *l, *children; + children = st_container_get_children_list (ST_CONTAINER (actor)); + + CLUTTER_ACTOR_CLASS (st_group_parent_class)->get_paint_volume (actor, volume); + + for (l = children; l != NULL; l = l->next) + { + ClutterActor *child = l->data; + const ClutterPaintVolume *child_volume; + + /* This gets the paint volume of the child transformed into the + * group's coordinate space... */ + child_volume = clutter_actor_get_transformed_paint_volume (child, actor); + if (!child_volume) + return FALSE; + + clutter_paint_volume_union (volume, child_volume); + } + + return TRUE; +} static void @@ -242,6 +269,7 @@ st_group_class_init (StGroupClass *klass) actor_class->get_preferred_height = st_group_get_preferred_height; actor_class->allocate = st_group_allocate; actor_class->paint = st_group_paint; + actor_class->get_paint_volume = st_group_get_paint_volume; actor_class->pick = st_group_pick; actor_class->show_all = st_group_show_all; actor_class->hide_all = st_group_hide_all; diff --git a/src/st/st-widget.c b/src/st/st-widget.c index fae5f5658..23b591d2f 100644 --- a/src/st/st-widget.c +++ b/src/st/st-widget.c @@ -7,6 +7,7 @@ * Copyright 2009, 2010 Red Hat, Inc. * Copyright 2009 Abderrahim Kitouni * Copyright 2009, 2010 Florian Müllner + * Copyright 2010 Adel Gadllah * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU Lesser General Public License, @@ -668,6 +669,31 @@ st_widget_hide (ClutterActor *actor) CLUTTER_ACTOR_CLASS (st_widget_parent_class)->hide (actor); } +static gboolean +st_widget_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume) +{ + ClutterActorBox paint_box, alloc_box; + StThemeNode *theme_node; + ClutterVertex origin; + + /* Setting the paint volume does not make sense when we don't have any allocation */ + if (!clutter_actor_has_allocation (self)) + return FALSE; + + theme_node = st_widget_get_theme_node (ST_WIDGET(self)); + clutter_actor_get_allocation_box (self, &alloc_box); + st_theme_node_get_paint_box (theme_node, &alloc_box, &paint_box); + + origin.x = paint_box.x1 - alloc_box.x1; + origin.y = paint_box.y1 - alloc_box.y1; + origin.z = 0.0f; + + clutter_paint_volume_set_origin (volume, &origin); + clutter_paint_volume_set_width (volume, paint_box.x2 - paint_box.x1); + clutter_paint_volume_set_height (volume, paint_box.y2 - paint_box.y1); + + return TRUE; +} static void @@ -688,6 +714,7 @@ st_widget_class_init (StWidgetClass *klass) actor_class->get_preferred_height = st_widget_get_preferred_height; actor_class->allocate = st_widget_allocate; actor_class->paint = st_widget_paint; + actor_class->get_paint_volume = st_widget_get_paint_volume; actor_class->parent_set = st_widget_parent_set; actor_class->map = st_widget_map; actor_class->unmap = st_widget_unmap;