floss.social is one of the many independent Mastodon servers you can use to participate in the fediverse.
For people who care about, support, and build Free, Libre, and Open Source Software (FLOSS).

Administered by:

Server stats:

685
active users

alcinnz

To finish my description of GTK4's "GSK" renderer, I'll new describe the (GLSL) code running on the GPU to do the actual rendering.

And this starts with a handful of common input variables & utilities to output a (clipped) colour, hittest a rounded rectangle, or lookup a point in a texture. That hittest first involves hittesting the unrounded rectangle, then each corner, then combines those latter tests. Different variants are implemented for ES2, GL3, & GL2.

The formula for hittesting an ellipsis is:

(dotproduct(p / r, p / r) - 1.0) / length(2 * (p / r) / r)

Where dotproduct(a, b) = a.x*b.x + a.y*b.y & length(a) = sqrt dotproduct(a, a).

Feel free to explain this formula to me, I haven't studied much geometry.

To color blend between two surfaces, lookup the appropriate colours in both textures & mixes them according to the specified (of numerous) formulas.

To copy ("blit") an image onto the output you simply look up that pixel & apply the opacity. That texture position from which to read is interpolated between this "fragment shader" and the "vertex shader".

(cont.)

To apply a blur to a texture, it computes an incrementalGaussian x/y/z, pixels-per-side, & pixel step based on the blur radius. From there it computes a sum & coefficientSum & updates the incrementalGuassian.

Then iterates between 1 & the computed pixels-per-side, and uses each of the intermediate (inclusive) numbers to update the sum, coefficientsum, & incrementalGuassian based on the pixel-step, provided blurDir, & incrementalGaussian.

The output colour is sum/coefficientSum.

To render a single-coloured border, it checks if the point is in an outer rounded rect but not an inner rounded rect, and outputs the specified colour if so.

To render a solid fill it simply outputs the provided colour for each fragment pixel. Both for this & the previous shaders, premultiplied-alpha (a technique for making colours behave like vectors via the statement `color.rgb *= color.a`) is computed on the GPU.

Another shader allows you to multiply a texture pixel by a matrix.

To recoulor an image multiply the desired at each output pixel by the alpha looked up from the texture.

To cross-fade two textures, use the provided progress to compute the opacity to apply to the pixels looked up from the two textures, applies those opacities & add the two colours.

To render an unblurred inset shadow, compute the desired outline & inside rounded rects and fill the difference, much like for borders.

To apply a linear gradient it iterates over the colour steps to find the relevant ones & uses the builtin mix() function to interpolate between them.

An unblurred outset shadow computes a single rounded rect to fill.

Repeating texture fills simply uses the mod() operator to bring the coordinate for lookup into range.

And I don't see the difference between the "outset_shadow" & "unblurred_outset_shadow" fragment shaders. Barely any vertex shaders are used.

Fin.

These toots have been persisted to: adrian.geek.nz/graphics_docs/G

P.S. GSK uses an external library "graphene" to implement geometric maths. I skimmed it, and don't have anything else to say.

Tomorrow I'll start describing Wayland/Weston and some of it's underlying libraries.

adrian.geek.nz"GSK (GTK4 Scenegraph Kit)" by Adrian Cochrane