Bounding box calculation before gtk_widget_expose()



Hi,

I'm using the GtkViewport to wrap some scrolling around a container
instance that has a potentially large number of children. Only a very
few of these children are on-screen (that is, intersecting the logical
viewport of the GtkViewport) at any one time.

It turns out that the largest single expense of exposing the viewport
is the determination of the clipping region before the expose handler
is called on each child. From gtk_container_propagate_expose():

 ...
 if (GTK_WIDGET_DRAWABLE (child) &&
     GTK_WIDGET_NO_WINDOW (child) &&
     (child->window == event->window))
   {
     child_event = gdk_event_new (GDK_EXPOSE);
     child_event->expose = *event;
     g_object_ref (child_event->expose.window);

     // [1]
     child_event->expose.region = gtk_widget_region_intersect (child,
event->region);

     if (!gdk_region_empty (child_event->expose.region))
       {
         gdk_region_get_clipbox (child_event->expose.region,
                                 &child_event->expose.area);
         gtk_widget_send_expose (child, child_event);
       }
     gdk_event_free (child_event);
   }

[1] Now, the calculation of that intersection calls
gtk_widget_get_draw_rectangle(), whose implementation looks like this:

 if (GTK_WIDGET_NO_WINDOW (widget))
   {
     // [2]
     *rect = widget->allocation;
     ...
     if (GTK_IS_CONTAINER (widget))
       {
         // [3]
         gtk_container_forall (GTK_CONTAINER (widget),
                               (GtkCallback)widget_add_child_draw_rectangle,
                               rect);
       }
   }
 else
   {
     rect->x = 0;
     rect->y = 0;
     rect->width = widget->allocation.width;
     rect->height = widget->allocation.height;
   }

I'm not understanding why step [3] above is necessary. Doesn't the
strict containment policy enforce that child will ever need a larger
area exposed than its container already needs (as calculated at [2])?

Removing line [3] seems to boost performance enormously, when the
child widgets are themselves fairly deeply nested.

--Matt



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