From 59639909b1b7189835c25e5017e2b5700188185e Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Sat, 13 Nov 2010 15:44:59 -0500 Subject: [PATCH] MetaWindowGroup: further optimize paints by using current scissor When in a partial stage paint, we can combine that with the visibility information in MetaWindowGroup to further eliminate unneeded drawing. Since there is no current Clutter API to access the current clip, drop to using GL directly. https://bugzilla.gnome.org/show_bug.cgi?id=634779 --- src/compositor/meta-window-group.c | 32 +++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index ecb2f35a6..d501d837a 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -5,6 +5,8 @@ #define _ISOC99_SOURCE /* for roundf */ #include +#include /* for gdk_rectangle_intersect() */ + #include "meta-window-actor-private.h" #include "meta-window-group.h" @@ -102,7 +104,9 @@ meta_window_group_paint (ClutterActor *actor) { MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); cairo_region_t *visible_region; + GLboolean scissor_test; cairo_rectangle_int_t screen_rect = { 0 }; + cairo_rectangle_int_t scissor_rect; GList *children, *l; /* We walk the list from top to bottom (opposite of painting order), @@ -118,7 +122,33 @@ meta_window_group_paint (ClutterActor *actor) * optimization, however.) */ meta_screen_get_size (window_group->screen, &screen_rect.width, &screen_rect.height); - visible_region = cairo_region_create_rectangle (&screen_rect); + + /* When doing a partial stage paint, Clutter will set the GL scissor + * box to the clip rectangle for the partial repaint. We combine the screen + * rectangle with the scissor box to get the region we need to + * paint. (Strangely, the scissor box sometimes seems to be bigger + * than the stage ... Clutter should probably be clampimg) + */ + glGetBooleanv (GL_SCISSOR_TEST, &scissor_test); + + if (scissor_test) + { + GLint scissor_box[4]; + glGetIntegerv (GL_SCISSOR_BOX, scissor_box); + + scissor_rect.x = scissor_box[0]; + scissor_rect.y = screen_rect.height - (scissor_box[1] + scissor_box[3]); + scissor_rect.width = scissor_box[2]; + scissor_rect.height = scissor_box[3]; + + gdk_rectangle_intersect (&scissor_rect, &screen_rect, &scissor_rect); + } + else + { + scissor_rect = screen_rect; + } + + visible_region = cairo_region_create_rectangle (&scissor_rect); for (l = children; l; l = l->next) {