Re: [gtk-list] Re: GraphicsExpose (was Re: About the About Box)





On Sun, 14 Dec 1997, Owen Taylor wrote:

> I think what happens is:
> 
> After the XCopyArea call, X thinks that the entire window now contains
> valid information (for the purpose of calculating GraphicsExpose
> events). But actually, that isn't true until the GraphicsExpose events
> filter through the queue. Before then, X has blanked out the improper
> areas to the background color (*) If another motion event occurs
> before then, X will copy the blanked out areas, but not produce
> graphics expose events for them, thus leading to the observed gray
> bars. 

Umm. This sounds like a serious problem.

> I'm thinking of adding a specialized function to gdk to handle this:
> 
>   gdk_get_next_graphics_expose_event (GdkWindow *window, GdkEvent
>                                       *event, gint status);
> 
> or something. So you could do:
> 
>  gdk_draw_pixmap (widget->window, gc, widget->window, ...);
> 
>  do
>    {
>      if (gdk_get_next_graphics_expose_event (widget->window, &event, &status))
>        gtk_widget_event (widget, &event)
>    }
>   while (status);
> 
> to make sure that all the GraphicsExpose events are properly handled.
> status would become FALSE when a NoExpose event or GraphicsExpose
> event with a count of zero was received, or no suitable events were in
> the queue. The GIMP tries to to do this using gdk_next_event () with a
> predicate, but as I mentioned, that seems completely broken, and I
> don't know how to fix it without tons of overhead. (And changing a lot
> of assumptions in the event handling code)

I still see the race condition - specifically, two XCopyArea's in a row 
before the GraphicsExpose from the first one makes it to the app. This 
seems to be a general consequence of the asynchronous coupling between 
the X client and server.

> > > So, for starters, I would like to make no graphics expose events
> > > the default for GDK created GC's. 
>     ^^^^^^^^^^^
> 
> > I'm not quite sure I understand the proposal. How are you going to detect 
> > the case when XCopyArea is used to scroll inside a partially obscured 
> > window? Unless I totally misunderstand, enabling graphics expose is the 
> > only way to do this.
> 
> People who knew what they were doing could still specify that they
> wanted GraphicsExpose events. But it would remove a trap for
> beginners, and cut down on the number of NoExpose events GTK handles.

Ok, so the rule is: if you do XCopyArea within a window, you'll want to 
turn on GraphicsExpose, right?

> > Currently, Gzw (and thus Gzilla) handles scrolling by moving the 
> > underlying X window, pretty much the same as gtk_scrolled_window, except 
> > with some stuff to handle >32kpixel scrollable regions. Thus, the stuff 
> > scrolled in is handled by a vanilla expose event. This works ok, but you 
> > do get the round-trip latency of waiting for the expose event, which is 
> > visually noticeable. It's especially noticeable when scrolling very 
> > quickly and/or on a highly loaded machine. I'd like to add an alternate 
> > mode that works the same as gtk_text. On the other hand, the gtk_text 
> > method works very poorly when there are embedded non-NO_WINDOW widgets. 
> > In any case, I'm certainly interested to find out how this is resolved.
> 
> The same latency should be present in any case, right? X should
> optimize scrolling the window like using XCopyArea, and the
> GraphicsExpose events also have to go round-trip. 

No, what I'm saying is that the scroll-in areas are drawn directly by the 
app right after the XCopyArea, without any GraphicsExpose events. The 
only time the latter become relevant is when the window is partially 
exposed, a rare enough case that I don't care about the slight 
performance problem.

> I was thinking some more about how to avoid the lagging-widget effect,
> and came only came up with a rather wild and impractical idea -
> make the embedded widget's have InputOnly windows, and redirect
> the drawing calls onto the scrolled window's pixmap. It would require
> some changes to GdkWindow handling, and you'd have to handle exposures
> pretty much by hand...

It sounds like it would be much less painful just to move Gtk over to an 
entirely NO_WINDOW mode, except for nonembeddable widgets like toplevel 
windows, popup menus, and viewports. At least you'd get a siable 
performance improvement as part of the bargain.

> Another way to get the display right - with horrible performance and
> complexity. Set the background pixmap of the parent window to None. Do
> an XCopyArea with SubwindowMode set to IncludeInferiors, unmap the
> child windows, ignore the resulting expose events on the parent
> window. Set the background pixmap of all the child windows and their
> descendants to None, remap them in the new position, ignore the
> resulting expose events on the child windows, then restore the
> backgrounds.

This sounds just a little bit like what XmHTML does. But I for one am not 
willing to volunteer to write the code :)

> But pretty much, I don't think it is possible to do better than what
> you do in Gzilla now.

Yeah, the performance in Gzilla is actually quite good. I'm willing to 
live with it until we replace X, anyway.

Raph



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