We're caching two things, either a node itself being rendered, or a
parent storing a cached version of a child as rendered to an offscreen
the size and location of the parent.
If both the parent and child uses the cache this will cause a conflict in
the cache as it is currently use keying of a node pointer which will have
the same value for the node-as-itself and the child-node-of-the-parent.
We fix this by adding another part to the key "pointer_is_child" which means
we can have the same node pointer twice in the cache.
Additionally, in the child-is-rendered-offscreen case the offscreen
result actually depends on the position and size of the parent viewport,
so we need to store the parent bounds in that case.
The GtkGears widget is a bit too chatty, especially when used inside
demos like the fishbowl. Let's use g_debug() instead of g_print() for
the GL debugging message.
This adds a bunch of snazz to the gltransitions demo. It is perhaps
a bit overloaded now, but it demos everything that we can do.
Changes:
* The fire shader is now not a bin, it just renders an animating
background with no textures involved.
* The stacks don't all start on the same page.
* The shaderbin passes the mouse coordinate to the shader.
* The shaderbin allows specifying a "border" so that you can
cause effects outside the bin child (something that is new to gtk4).
* All the buttons and the stacks are now in shader-bins that runs
a wobbly-widget effect based on the mouse position that
wobbles outside the child allocation.
Now that the functions that wrap them have gone away from the public
API, we need proper annotations for the virtual functions, otherwise
languages will not have enough information on nullable arguments and
ownership transfer.
Most of the time the snapshot is less than 16 levels deep (did some testing
in gtk-demo), so lets pre-allocate 16 levels of state stack to avoid the
extra allocation most of the time.
If all your callers already initialize the array element as needed,
then we don't need to memset it to zero first.
This is pretty useful for the snapshot state stack, because due
to the per-node-type data area the elements on the stack are
quite large, but often a lot of it is not used.
This inlines the splice and reserver GdkArray calls. These are
typically only called from the gdk_array_(append/set_size) functions
anyway, and inlining the caller means we can constant propagate the
constant arguments in those calls. Its hard to get exact numbers, but
in fishbowl i noticed a significant decrease in the time spent in
the array code when pushing and poping states.
This allows us to avoid updating uniforms if that is not necessary. This
in turn allows us to sometimes reuse the same draw op by just extending the
vertex array size we draw rather than doing a separate glDraw call.
For example, in the fishbowl demo, all the icons added at the same
time will have the same time and size, so we emit single draw calls
with 100s of triangles instead of 100s of draw calls with 2 triangles.
Add adds a demo showing off GskGLShaderNode in various ways.
It has a transistion widget, using some examples from
gl-transitions.com, with child widgets being both images, a GL area
and real widgets (that let you edit the transition shaders
themselves.
It also has a fancy fire effect on hove on the buttons.
For vulkan/broadway this just means to ignore it, but for the gl
backend we support (with up to 4 texture inputs, which is similar to
what shadertoy does, so should be widely supported).
A GskGLShader is an abstraction of a GLSL fragment shader that
can produce pixel values given inputs:
* N (currently max 4) textures
* Current arguments for the shader uniform
Uniform types are: float,(u)int,bool,vec234)
There is also a builder for the uniform arguments which are
passed around as immutable GBytes in the built form.
A GskGLShaderNode is a render node that renders a GskGLShader inside a
specified rectangular bounds. It renders its child nodes as textures
and passes those as texture arguments to the shader. You also pass it
a uniform arguments object.
Print out the full assembled shader sources when
GSK_DEBUG=shaders is given. This is very verbose,
but may be useful to see what we actually pass
to the compiler.
This way the child widgets can rely on the renderer (for example what
type it is) to decide details about how they render (such as if they
should use OpenGL shaders).
This adds a gsk prefix to the stuff in the preamble, as we want to
avoid it conflicting with things in the main shader. Especially once
we start allow some customization of shaders.
Almost always the source is created by combining various sources, which
means the line numbers in the error messages are hard to use. Adding
the line numbers to the source in the error message helps with this.