Re: Cullng drawing depending on visibility events



Federico Mena Quintero <federico ximian com> writes:

> 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.

Usually the expensive part of gtk+ drawing is walking the widget tree
emitting expose signals, not executing the drawing primitives, so just
making the drawing primitives no-ops is probably not going to make a
big difference.

So my guess is that gnome-terminal is still spending a lot of time
drawing stuff, even though all the "drawing" is done with no-op
primitives.

> 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.

This is a good idea, I think. If you can make sure that a window is
never invalidated when it is fully obscured, then the expose signal
will never be emitted and no drawing (real or no-op) will take place.

I modified your patch to do this instead, and a quick test with
pixbuf-demo showed that it works. It should also work for
vte, but I don't use gnome-terminal anymore, so I haven't tested it.

Søren

? visibility2.diff
Index: gdkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.c,v
retrieving revision 1.146
diff -u -p -u -r1.146 gdkwindow.c
--- gdkwindow.c	28 Nov 2002 00:33:03 -0000	1.146
+++ gdkwindow.c	4 Apr 2003 11:39:35 -0000
@@ -2331,6 +2331,9 @@ gdk_window_invalidate_maybe_recurse (Gdk
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
+
+  if (private->fully_obscured)
+    return;
   
   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
     return;
Index: gdkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.h,v
retrieving revision 1.45
diff -u -p -u -r1.45 gdkwindow.h
--- gdkwindow.h	17 Nov 2002 22:03:47 -0000	1.45
+++ gdkwindow.h	4 Apr 2003 11:39:36 -0000
@@ -260,6 +260,8 @@ struct _GdkWindowObject
   guint modal_hint : 1;
   
   guint destroyed : 2;
+
+  guint fully_obscured : 1;
   
   GdkEventMask event_mask;
 };
Index: x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.108
diff -u -p -u -r1.108 gdkevents-x11.c
--- x11/gdkevents-x11.c	8 Mar 2003 21:11:38 -0000	1.108
+++ x11/gdkevents-x11.c	4 Apr 2003 11:39:39 -0000
@@ -1449,14 +1449,29 @@ gdk_event_translate (GdkDisplay *display
 	{
 	case VisibilityFullyObscured:
 	  event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED;
+	  window_private->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_private->fully_obscured)
+	    gdk_window_invalidate_rect (window, NULL, FALSE);
+
+	  window_private->fully_obscured = FALSE;
 	  break;
 	  
 	case VisibilityUnobscured:
 	  event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
+
+	  /* FIXME: same as above */
+	  if (window_private->fully_obscured)
+	    gdk_window_invalidate_rect (window, NULL, FALSE);
+
+	  window_private->fully_obscured = FALSE;
 	  break;
 	}
       
Index: x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.183
diff -u -p -u -r1.183 gdkwindow-x11.c
--- x11/gdkwindow-x11.c	6 Mar 2003 20:19:10 -0000	1.183
+++ x11/gdkwindow-x11.c	4 Apr 2003 11:39:45 -0000
@@ -270,7 +270,7 @@ gdk_window_impl_x11_get_visible_region (
   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);
 
   return gdk_region_rectangle (&result_rect);
@@ -489,7 +489,7 @@ gdk_window_new (GdkWindow     *parent,
     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: x11/gdkwindow-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.h,v
retrieving revision 1.7
diff -u -p -u -r1.7 gdkwindow-x11.h
--- x11/gdkwindow-x11.h	10 Dec 2002 20:06:02 -0000	1.7
+++ x11/gdkwindow-x11.h	4 Apr 2003 11:39:45 -0000
@@ -90,7 +90,7 @@ struct _GdkWindowImplX11
   /* Set if we are requesting these hints */
   guint skip_taskbar_hint : 1;
   guint skip_pager_hint : 1;
-  
+
   /* We use an extra X window for toplevel windows that we XSetInputFocus()
    * to in order to avoid getting keyboard events redirected to subwindows
    * that might not even be part of this app


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