Re: gtk_widget_draw()



On Mon, 2010-08-09 at 02:07 +0200, Benjamin Otte wrote:

This is awesome stuff, Benjamin.

> I'll start with the end goal: gtk_widget_draw(GtkWidget *widget, cairo_t *cr);

One thing I'd definitely like to have is the region-to-expose.  Many
times people have started with "oh, I'll just paint everything every
time", only to find later that this is too slow.  Then they go and make
use of the expose-rectangle or the finer expose-region, and things
magically become fast.

EOG uses this to good effect, for example - scaling an image is
expensive, so it only scales the areas that absolutely need to be
repainted.

I don't know if you can get the clip path set on a cairo_t, but even if
you can, getting a path is not ideal... a region made out of rectangles,
like GdkRegion, seems more generally useful.

> 3) Resolution independence. A cairo_scale (cr, 2, 2) before calling
> gtk_widget_draw() smoothly scales widgets to twice the size. Of
> course, event translation and all that fun is needed, too, but the
> rendering part is there.

Good drawing functions do their best to align things to the pixel grid,
if it exists.  Does Cairo let you know the device's resolution, or
something that lets you know if the current transformation is
pixel-aligned?

(If I tell my resolution-independent desktop to scale itself by 1.73
times for my aging eyes, by using the friendly "zoom factor" slider that
it provides, then I'd still like crisp widgets as best as possible.)

> 4) Make the window's surface gettable
> You might want to use a window as a source in drawing operations or do
> other stuff with it (like calling cairo_surface_create_similar() for
> the pixmap replacement) so this needs to be available. Arguably,

Hmmm, is this related to GDK_NO_EXPOSE events?  Such as you would get on
the destination window if you gdk_draw_drawble() with the source being
partially obscured.

(Copying from window to window seems anachronistic these days, anyway...
and if you can simply tell another widget/window to gtk_widget_draw()
itself into our own temporary surface, you don't need cross-window
blits.)

> 7) Improve repaint semantics
> Something like disallowing multiple being_paint_region() calls and
> disallowing the use of windows as a source while a repaint is
> happening sound very desirable to me. The code that circumvents these
> issues is quite extensive and buggy and noone uses these features
> anyway. Also, the Paintable interface should probably be folded back
> into GdkWindow, too.

gdk_window_begin_paint_region() is just a convenient way of saying "give
me a temporary buffer with magic coordinates".  We could very well have
windows keep a stack of Cairo surfaces (or just a stack of clipping
regions + transformations, etc.) that get flattened when the last
gdk_window_end_paint() is called.  Or maybe just make those functions
basically be wrappers for cairo_save/restore() plus some clipping and
coordinate-changing.

Somewhat related to that is gdk_window_scroll().  Or does CSW handle
that magically?  You *definitely* want scrolling to be done as much in
hardware as possible, at least for blitting the already-exposed region.
You only want to repaint the scrolled-in area at any time.

> 11) Remove the expose_event from GtkWidget
> Now that the whole repaint handling is done in the draw signal,
> there's no more need for expose events. The semantics are somewhat
> different, as draw signals don't correspond 1:1 to expose events. But
> I think that change shouldn't matter for all practical purposes. And
> if you need it, you can just connect to the "event" signal of the
> GdkWindow.

This seems very clean - native windows send you events; widgets
translate that to "draw" signals as appropriate.

  Federico



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