Cullng drawing depending on visibility events



Hi,

So I wrote a quick patch to make the drawing functions not do anything
if windows are fully obscured.

Is this overkill?  I haven't really noticed any speed-ups with it even
with gnome-terminal/VTE spewing stuff in the background.

It may also be desirable to modify gdk_window_invalidate_region() to do
nothing if the window is fully obscured --- I'm thinking of applications
that force repaints that way.

  Federico
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.4000.2.90
diff -u -r1.4000.2.90 ChangeLog
--- ChangeLog	2 Apr 2003 23:02:25 -0000	1.4000.2.90
+++ ChangeLog	4 Apr 2003 03:04:09 -0000
@@ -1,3 +1,32 @@
+2003-04-03  Federico Mena Quintero  <federico ximian com>
+
+	* gdk/x11/gdkwindow-x11.h (struct _GdkWindowImplX11): Added a
+	fully_obscured boolean field.
+
+	* gdk/x11/gdkwindow-x11.c (gdk_window_new): Add
+	VisibilityChangeMask to the default event mask.
+	(gdk_window_impl_x11_init): Initialize the fully_obscured field.
+	(gdk_window_impl_x11_get_visible_region): Return an empty region
+	if we are fully obscured.
+
+	* gdk/x11/gdkevents-x11.c (gdk_event_translate): Set
+	window_impl->fully_obscured as appropriate.  Also, invalidate the
+	whole window once we switch out of being fully obscured.
+
+	* gdk/x11/gdkdrawable-x11.c (gdk_x11_draw_rectangle): Do not draw
+	if the drawable is a window and it is fully obscured.
+	(gdk_x11_draw_arc): Likewise.
+	(gdk_x11_draw_polygon): Likewise.
+	(gdk_x11_draw_text): Likewise.
+	(gdk_x11_draw_text_wc): Likewise.
+	(gdk_x11_draw_drawable): Likewise.
+	(gdk_x11_draw_points): Likewise.
+	(gdk_x11_draw_segments): Likewise.
+	(gdk_x11_draw_lines): Likewise.
+	(gdk_x11_draw_glyphs): Likewise.
+	(gdk_x11_draw_image): Likewise.
+	(gdk_x11_draw_pixbuf): Likewise.
+
 2003-04-03  Matthias Clasen  <maclas gmx de>
 
 	* demos/gtk-demo/main.c (demo_find_file): Only use files from the
Index: gdk/x11/gdkdrawable-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdrawable-x11.c,v
retrieving revision 1.25
diff -u -r1.25 gdkdrawable-x11.c
--- gdk/x11/gdkdrawable-x11.c	7 Nov 2002 22:27:22 -0000	1.25
+++ gdk/x11/gdkdrawable-x11.c	4 Apr 2003 03:04:09 -0000
@@ -446,8 +446,11 @@
 {
   GdkDrawableImplX11 *impl;
 
-  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
   
+  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
+
   if (filled)
     XFillRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
 		    GDK_GC_GET_XGC (gc), x, y, width, height);
@@ -469,9 +472,11 @@
 {
   GdkDrawableImplX11 *impl;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
-  
   if (filled)
     XFillArc (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
 	      GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
@@ -491,9 +496,11 @@
   gint tmp_npoints, i;
   GdkDrawableImplX11 *impl;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
-  
   if (!filled &&
       (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y))
     {
@@ -542,6 +549,9 @@
   GdkDrawableImplX11 *impl;
   Display *xdisplay;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
   xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
   
@@ -582,6 +592,9 @@
   GdkDrawableImplX11 *impl;
   Display *xdisplay;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
   xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
   
@@ -637,6 +650,9 @@
   GdkDrawableImplX11 *impl;
   GdkDrawableImplX11 *src_impl;
   
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
   if (GDK_IS_DRAWABLE_IMPL_X11 (src))
@@ -677,9 +693,12 @@
 {
   GdkDrawableImplX11 *impl;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
-  
+
   /* We special-case npoints == 1, because X will merge multiple
    * consecutive XDrawPoint requests into a PolyPoint request
    */
@@ -720,6 +739,9 @@
 {
   GdkDrawableImplX11 *impl;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
   
@@ -764,6 +786,9 @@
   XPoint *tmp_points = g_new (XPoint, npoints);
   GdkDrawableImplX11 *impl;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
   
@@ -792,6 +817,9 @@
 {
   GdkDrawableImplX11 *impl;
 
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
 #if HAVE_XFT
@@ -842,6 +870,9 @@
 {
   GdkDrawableImplX11 *impl;
   
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
   if (image->type == GDK_IMAGE_SHARED)
@@ -1436,6 +1467,9 @@
   gboolean use_pixmaps = TRUE;
 #endif /* USE_SHM */
     
+  if (GDK_IS_WINDOW_IMPL_X11 (drawable) && GDK_WINDOW_IMPL_X11 (drawable)->fully_obscured)
+    return;
+  
   format_type = select_format (gdk_drawable_get_display (drawable),
 			       &format, &mask_format);
 
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.106.2.2
diff -u -r1.106.2.2 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	8 Mar 2003 21:11:18 -0000	1.106.2.2
+++ gdk/x11/gdkevents-x11.c	4 Apr 2003 03:04:09 -0000
@@ -1449,14 +1449,29 @@
 	{
 	case VisibilityFullyObscured:
 	  event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED;
+	  window_impl->fully_obscured = TRUE;
 	  break;
 	  
 	case VisibilityPartiallyObscured:
 	  event->visibility.state = GDK_VISIBILITY_PARTIAL;
+
+	  /* FIXME: we should only do this if the visibility event did not come
+	   * with associated exposures.  Would XIfEvent() be what we need here?
+	   */
+	  if (window_impl->fully_obscured)
+	    gdk_window_invalidate_rect (window, NULL, FALSE);
+
+	  window_impl->fully_obscured = FALSE;
 	  break;
 	  
 	case VisibilityUnobscured:
 	  event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
+
+	  /* FIXME: same as above */
+	  if (window_impl->fully_obscured)
+	    gdk_window_invalidate_rect (window, NULL, FALSE);
+
+	  window_impl->fully_obscured = FALSE;
 	  break;
 	}
       
Index: gdk/x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.182.2.1
diff -u -r1.182.2.1 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c	6 Mar 2003 20:17:55 -0000	1.182.2.1
+++ gdk/x11/gdkwindow-x11.c	4 Apr 2003 03:04:10 -0000
@@ -139,6 +139,7 @@
 {  
   impl->width = 1;
   impl->height = 1;
+  impl->fully_obscured = TRUE;
 }
 
 static void
@@ -266,12 +267,22 @@
   GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
   GdkRectangle result_rect;
 
-  result_rect.x = 0;
-  result_rect.y = 0;
-  result_rect.width = impl->width;
-  result_rect.height = impl->height;
+  if (impl->fully_obscured)
+    {
+      result_rect.x = 0;
+      result_rect.y = 0;
+      result_rect.width = 0;
+      result_rect.height = 0;
+    }
+  else
+    {
+      result_rect.x = 0;
+      result_rect.y = 0;
+      result_rect.width = impl->width;
+      result_rect.height = impl->height;
 
-  gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
+      gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
+    }
 
   return gdk_region_rectangle (&result_rect);
 }
@@ -489,7 +500,7 @@
     visual = gdk_screen_get_system_visual (screen);
   xvisual = ((GdkVisualPrivate*) visual)->xvisual;
   
-  xattributes.event_mask = StructureNotifyMask | PropertyChangeMask;
+  xattributes.event_mask = StructureNotifyMask | PropertyChangeMask | VisibilityChangeMask;
   for (i = 0; i < _gdk_nenvent_masks; i++)
     {
       if (attributes->event_mask & (1 << (i + 1)))
Index: gdk/x11/gdkwindow-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.h,v
retrieving revision 1.7
diff -u -r1.7 gdkwindow-x11.h
--- gdk/x11/gdkwindow-x11.h	10 Dec 2002 20:06:02 -0000	1.7
+++ gdk/x11/gdkwindow-x11.h	4 Apr 2003 03:04:10 -0000
@@ -90,6 +90,9 @@
   /* Set if we are requesting these hints */
   guint skip_taskbar_hint : 1;
   guint skip_pager_hint : 1;
+
+  /* Set if we have received a FullyObscured VisibilityNotify event */
+  guint fully_obscured : 1;
   
   /* We use an extra X window for toplevel windows that we XSetInputFocus()
    * to in order to avoid getting keyboard events redirected to subwindows


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]