Re: oustanding gtkwindow.c FIXME



Tim Janik <timj gtk org> writes:

> > It would certainly be nice if it was possible, but the things I have
> > tried have always resulted in weird bugs and areas that should be
> > redrawn, but wasn't.  Of course, this is most likely because I don't
> > know what I am doing :-)
> 
> there's no extraneous resizing/redrawing being done in our configure_event
> handler, it just handles resizes that were previously deferred because
> we knew we're about to receive a configure event.
> 
> extra work redrawing (not resizing) work is just being done at the point
> where we're deferring the resize (and that's the original FIXME).
> if you suspect this to cause noticable lag on your machine, you can
> check that with calling gtk_container_set_resize_mode (window,
> GTK_RESIZE_IMMEDIATE) on your toplevel window (this will avoid
> deferring the resize, but also, if the window manager's configure
> event did change our window size, cause an extra flicker).

A configure event is handled (essentailly) by queuing a resize, which
takes effect in the idle loop.  On my machine, the queueing of a
resize takes a few milliseconds - not a big deal, and if the time
spent on size_allocate and redrawing is reduced, so is the number of
queued up configures, because the user will have less time to generate
them.

Did you see the data I posted a few days ago? According to them, size
allocation of the testgtk toplevel window takes around a third of
second and redrawing takes up to 7/10 second.  The time to queue up
resizes from configure events is not important compared to that.

> > One possible solution, maybe for 2.2, is to add flags H_REDRAW and
> > V_REDRAW, like on Windows, which, for compatibility, would be set by
> > default.  When the H_REDRAW flag is set, GTK+ guarantees that the
> > widget is completely redrawn when its horizontal allocation changes.
> > Similar for the V_REDRAW.
> 
> if a widget expanded in one direction, it needs to be completely new size
> allocated (and also its chilren) and therefore redrawn, so this

Why does "size allocate" imply "complete redraw"?  If a widget unsets
these flags, it would itself be responsible for invalidating those
areas that needed to.

> is not a viable aproach for speed-ups.
> there're lots of other areas where we can improve speed significantly though.

In fact, the way I read gtk_widget_size_allocate(), it *tries* to
avoid redrawing by doing

  [...]
  else if (widget->allocation.width != real_allocation.width ||
	   widget->allocation.height != real_allocation.height)
    {
      needs_draw = TRUE;
    }

  [...]

  if (needs_draw)
    {
      gtk_widget_queue_draw (widget);
      if (widget->parent && GTK_CONTAINER (widget->parent)->reallocate_redraws)
	gtk_widget_queue_draw (widget->parent);
    }

This is bogus, though, because

  a) queue_resize() already queued a complete redraw of everything from
     the resize_container down.

  b) queue_draw() clears a widget's window and all subwindows - which
     means that every sub-widget is cleared whether it's resized or
     not.

> > For example, the Canvas should not have to have its entire gdk-window
> > invalidated just because someone resized it.
> 
> that depends, imagine a canvas having an item that's always to be
> centered.

In this case, what would happen, assuming unset
H/V_REDRAW, is

      - canvas would be size allocated, an L-shaped region would be
        invalidated.

      - canvas rerenders L-shaped region (which is considerably smaller
        than the entire window)

      - must-center item is moved

      - canvas rerenders old and new locations for item

Without H/V_REDRAW, step two would be "redraw entire window, which of
course has lots and lots of overlapping items".

But yes, it is easy to think of canvas uses where H/V_REDRAW unsetting
wouldn't help.  But it wouldn't harm because the canvas does its own
invalidation.

Maybe the canvas is a bad example.  What about a DrawingArea with a
staic image that must be updated.  Unsetting H/V_REDRAW could save a
lot of redrawing here.




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