Add a should_propagate function for render nodes. Eventually,
this is meant to avoid creating render nodes for child widgets
that are outside the parents clip area. Since we don't have
that information available right now, just filter out nondrawable
children for now.
Change get_render_node to return nodes that are sized to the clip
area and expect to be placed at the clip position; change
gtk_container_propagate_render_node to place child render nodes
accordingly, and change gtk_css_gadget_get_render_node to return
nodes that are sized accordingly as well.
The details of the modelview and projection matrices are only useful for
the GL renderer; there's really no point in having those details
available in the generic API — especially as the Cairo fallback renderer
cannot really set up a complex modelview or a projection matrix.
Instead of using the background as the gadget's node, we add a
non-drawing node that can be used to apply offsets; all other nodes are
children of the "box" node.
This is the first example of indirect rendering involving
a box gadget. For now, we iterate the child gadgets manually,
and rely on gtk_container_propagate_render_node for the
child widgets. Eventually, we may want a better solution
here.
...and implement it for GtkCssGadget and GtkCssCustomGadget.
This allows us to decide on a per-object basis if a custom
gadget needs a render node for content or not.
The custom gadget draw function has the side effect of informing
the gadget machinery wether to draw focus or not. Bring the
draw function back, just for its boolean return value. We may
want to find a better solution for this.
Give all nodes the same detail about the owner widget.
This reveals that every GtkCssCustomGadget gets a
DrawGadgetContents node, even if their draw_func is NULL.
We may want to come up with a better solution for that.
When creating the GskRenderNodes for the gadgets we should not translate
the coordinates inside the Cairo context, but we should tweak the
coordinates of the anchor point.
This is still not enough to get an appropriate rendering, as the result
is still slightly offset to the left.
GtkWidget.create_render_node() sets up a GskRenderNode appropriate for
rendering the contents of a widget, including its bounds,
transformation, and anchor point.
The naming is consistent with other scene graph libraries, as it
represents an additional translation transformation applied on top of
the provided transformation matrices.
We can also simplify the implementation by applying the translation when
we compute the world matrix.
We were allocating a surface thats big enough for the clip, and
we were setting the transform for that, but then GtkContainer
was overriding the transform with the one for the allocation.
Also, we were drawing at the clip position, not the allocation
position.
Since we use an FBO to render the contents of the render node tree, the
coordinate space is going to be flipped in GL. We can undo the flip by
using an appropriate projection matrix, instead of changing the sampling
coordinates in the shaders and updating all our coordinates at render
time.
Render nodes need access to rendering information like scaling factors.
If we keep render nodes separate from renderers until we submit a nodes
tree for rendering we're going to have to duplicate all that information
in a way that makes the API more complicated and fuzzier on its
semantics.
By having GskRenderer create GskRenderNode instances we can tie nodes
and renderers together; since higher layers will also have access to
the renderer instance, this does not add any burden to callers.
Additionally, if memory measurements indicate that we are spending too
much time in the allocation of new render nodes, we can now easily
implement a free-list or a renderer-specific allocator without breaking
the API.
We cannot implement GtkWidgetClass.get_render_node() in GtkContainer
without breaking the fallback path that renders a widget to a single
render node rasterization. For GtkContainer subclasses we should provide
a simple API, similar to gtk_container_propagate_draw(), that gathers
all the render nodes for each child.
The clip rectangle may have non-zero offsets, so we need to ensure that
the GskRenderNode associated to the rendered area is translated by those
same offsets.
We need a virtual function to retrieve the GskRenderNode for each
widget, which is supposed to attach its own children's GskRenderNodes.
Additionally, we want to maintain the existing GtkWidget::draw mechanism
for widgets that do not implement get_render_node() — as well as widgets
that have handlers connected to the ::draw signal.