Re: gtk_widget_draw()



On Thu, Aug 12, 2010 at 7:15 PM, Federico Mena Quintero
<federico ximian com> wrote:
> 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.
>
The way you'd do it in cairo is something like this:
gdk_cairo_rectangle (cr, &widget->allocation);
cairo_clip (cr);
cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
if (rect_is_empty (x1, y1, x2, y2))
  return;

So far this has proven enough for all the things I've done. There's
also cairo_copy_clip_rectangle_list() if you want finer-grained
control, but I never needed that.

> 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.
>
Cairo does that automatically. On the GPU, too. So I suppose EOG
doesn't yet upload the pixbuf to a native cairo surface and uses that
for rendering?

> 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?
>
Yes, it provides you with all the facilities you need to transform to
and from device units. See cairo_user_to_device(),
cairo_user_to_device_distance() and the device_to_user versions.

> (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.)
>
And you also want smooth scaling when you drag that slider, so please
no jumps from 1 pixel wide borders to 2 pixel wide ones, I know... ;)

> 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.
>
Yeah, I was thinking about using cairo_push/pop_group() internally,
but then there's backends like GL or Quartz that are double buffered.

> 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.
>
I've still not seen anybody provide a real-world use case for it, so
I'm skeptical about that assertion, but so far this is the only code
in GDK that still uses XCopyArea directly. For that reason alone, I'd
like to get rid of it. (Interestingly, it is the only function in all
of X that allows self-copies. Xrender explicitly forbids it.)

Benjamin


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