Five years (and change) ago I was looking
at the data types and API that were needed to write a 3D-capable scene graph
API; I was also learning about SIMD instructions and compiler builtins on IA
and ARM, as well as a bunch of math I didn’t really study in my brush offs
with formal higher education. The result was a small library called
Graphene.

In the meantime, GStreamer started using Graphene in its GL element; GTK
3.9x is very much using Graphene internally and exposing it as public API;
Mutter developers are working on reimplementing the various math types in
their copies of Cogl and Clutter using Graphene; and
Alex wrote an entire 3D
engine using it.

Not bad for a side project.

Of course, now I’ll have to start maintaining Graphene like a proper
grownup, which also means reporting its changes, bug fixes, and features
when I’m at the end of a development cycle.

While the 1.8 development cycle consisted mostly of bug fixes with no new
API, there have been a few major internal changes during the development
cycle towards 1.10:

I rewrote the Euler angles conversion to and from quaternions and
matrices; the original implementation I cribbed from here and there was
not really adequate, and broke pretty horribly when you tried to
roundtrip from Euler angles to a transformation matrix and back. This
also affected the conversion between Euler angles and quaternions. The
new implementation is more correct, and as a side effect it now includes
not just the Tait–Bryan angles, but also the classic Euler angles. All
possible orders are available in both the intrinsic and extrinsic axes variants.

We’re dealing with floating point comparison and with infinities a bit
better, now; this is usually necessary because the various vector
implementations may have different behaviour, depending on the toolchain
in use. A shout out goes to Intel, who bothered to add an instruction to
check for infinities only in AVX 512, making it pointless for me, and
causing a lot more grief than necessary.

The ARMNEON implementation of graphene_simd4f_t has been fixed and
tested on actual ARM devices (an old Odroid I had lying around for ARMv7
and a Raspberry Pi3 for Aarch64); this means that the “this is experimental”
compiler warning has been removed. I still need to run the CI on an ARM
builder, but at least I can check if I’m doing something dumb, now.

As mentioned in the blog posts above, the whole test suite has been
rewritten using µTest, which dropped a dependency on GLib; you still need
GLib to get the integration with GObject, but if you’re not using that,
Graphene should now be easier to build and test.

On the API side:

there are a bunch of new functions for graphene_rect_t, courtesy of
Georges Basile Stavracas Neto and Marco Trevisan

thanks to Marco, the graphene_rect_round() function has been deprecated
in favour of the more reliable graphene_rect_round_extents()

graphene_quaternion_t gained new operators, like add(), multiply()
and scale()

thanks to Alex Larsson, graphene_plane_t can now be transformed using
a matrix

I added equality and near-equality operators for graphene_matrix_t,
and a getter function to retrieve the translation components of a
transformation matrix

I added interpolation functions for the 2, 3, and 4-sized vectors

I’m working on exposing the matrix decomposition code for Gthree, but
that requires some untangling of messy code so I’ll be in the next
development snapshot.

On the documentation side:

I’ve reworked the contribution guide, and added a code of conduct to the
project; doesn’t matter how many times you say “patches welcome” if you
also aren’t clear on how those patches should be written, submitted,
and reviewed, and if you aren’t clear on what constitutes acceptable
behaviour when it comes to interactions between contributors and the maintainer

this landed at the tail end of 1.8, but I’ve hopefully clearly
documented the conventions of the matrix/matrix and matrix/vector
operations, to the point that people can use the Graphene API without
necessarily having to read the code to understand how to use it

This concludes the changes that will appear with the next 1.10 stable
release, which will be available by the time GNOME 3.34 is out. For the
time being, you can check out the latest development
snapshot available
on Github.

I don’t have many plans for the future, to be quite honest; I’ll keep an
eye out for what GTK and Gthree need, and I expect that once Mutter starts
using Graphene I’ll start receiving bug reports.

One thing I did try was moving to a “static” API reference using
Markdeep, just like I did for µTest,
and drop yet another dependency; sadly, since we need to use gtk-doc
annotations for the GObject introspection data generation, we’re going to
depend on gtk-doc for a little while longer.

Of course, if you are using Graphene and you find some missing
functionality, feel free to open an issue,
or a merge request.