Cullng drawing depending on visibility events
- From: Federico Mena Quintero <federico ximian com>
- To: gtk-devel-list gnome org
- Subject: Cullng drawing depending on visibility events
- Date: 03 Apr 2003 21:56:16 -0600
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]