gsk-render review



So, I had a quick look at the gsk-render branch. I don't really have
much time for an in depth review, but here are some issues i saw:

The first one is a detail in the gl renderer. As opposed to a regular
3d engine we will mostly be drawing things with z=0, with a lot of
overdraw. So, we have to be very careful with z-overlap. In practice
we're probably using something like the CSS z-index where in addition
to the z value we have an order for rendernodes that share z. This
order is implicit when we draw the tree in a simple fashion, but
becomes more important when we start to do more advanced reordering
during rendering (and we may also want to support explicit z-indexes
in css).

Right now the default rendering of opaque nodes is front to back. With
the default depth test (LESS) this ends up doing the right
thing. However, for the alpha nodes we render back-to-front, and I
think the LESS depth test is wrong, is it not? I mean if you draw the
back-most thing at Z=0, and then render another item at Z=0 it will
not be drawn at all. Should it not be LEQUAL in this case?

And when we start doing more interesting things such as reordering to
minimize state changes then we need to explictily keep track of the
node z-index and apply it as a depth offset. I think glPolygonOffset
can be used for the z-index here, as its units is multiplied with "the
smallest value that is guaranteed to produce a resolvable offset for a
given implementation". How does servo handle this?

The second issue I found was in the Gtk+ integration. In particular,
the handling of queue_draw/resize. Traditionally, whenever you called
queue_draw the affected area would be invalidated on the toplevel
window and *everything* in that area would be redrawn from
scratch. Currently this happens in the gsk-render case too, i.e. we
re-render to a surface for each node. However, in an ideal world we
would often not want to do this. For instance, if a button becomes
focused we don't want to re-draw anything but that surface of the
button, and then just re-compose all the other previously drawn
surfaces. And in the case of a simple move of a widget we don't want
to redraw anything at all, just recompose.

Furthermore, there are many cases where we have/want to keep a
pre-rendered version of a subtree of the widget tree. For instance,
any place we have a opacity for a container and are currently
pushing/poping an opacity group during the cairo-based rendering we
really need to draw everything to a framebuffer and re-compose from
that. In such a case, if nothing inside that framebuffer changed we
want to avoid ever re-rendering it, and if something *does* change in
it, we only have to re-render the framebuffer and then recompose
anything outside it.

I think we need to extend the api with which a widget can tell gtk how
to redraw it. The sub-tree issues above is very similar to the ones we
had when the pixel-cache was introduced. To handle that i added
gdk_window_set_invalidate_handler() which can handle the catching and
propagation of invalidation of child invalidations. We need something
similar but on the render tree level. We also I think need to separate
the calls to queue a compose of your level in the tree, and the
marking of your cairo surface to be re-rendered.


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