Development

This document describes some handy things to know when developing the GEGL internals. The GEGL glossary might help make sense of the terms used.

Getting sources, and building

Links and information about various ways of getting a build environment for GEGL.

GEGL inheritance tree

Class inheritance graph generated from static introspection.

Operation API

An overview to the operation API.

Abyss policy

A description of the abyss policy settings in gegl_buffer_get()

Source overview

An overview of the source tree.

Some examples of programs built against the GEGL library can be found in the examples subdirectory of the GEGL source tree including hello-world.

Setting up

Ubuntu 20.04

Setup instructions for Ubuntu 20.04 Focal Fossa

To install the mandatory dependencies:

$ sudo apt-get install build-essential pkg-config python3 python3-pip \
  ninja-build git libglib2.0-dev libjson-glib-dev libpng-dev
$ sudo pip3 install meson

Some of the other dependencies:

  • Documentation:

    $ sudo apt-get install asciidoc source-highlight graphviz-dev
  • Localisation:

    $ sudo apt-get install gettext
  • Plugins:

    $ sudo apt-get install libjpeg libopenraw libtiff

When running gegl the environment variable GEGL_PATH is used to set the location of the dynamically loaded operation libraries. Setting the path to <gegl_build_dir>/operations allows gegl to be run using uninstalled operations, e.g.

$ export GEGL_PATH=<gegl_build_dir>/operations/

BABL

Meson uses pkg-config to find its dependencies. When building against an uninstalled development version of babl, gegl needs to be able to locate the library and headers. This done by adding the location of the uninstalled pkg-config file to the PKG_CONFIG_PATH environment variable when configuring meson:

$ PKG_CONFIG_PATH=<babl_build_dir>/meson-uninstalled:$PKG_CONFIG_PATH meson

The babl library searches for extensions in the directory stored in the BABL_PATH environment variable or in the directory containing the library itself. For example, if building against an uninstalled babl installation set the BABL_PATH as follows

$ export BABL_PATH=<babl_build_dir>/babl/extensions

to allow gegl tests to be run correctly and the documentation to be built.

Debugging

By default gegl and babl build with the meson buildtype=debugoptimized setting which uses the compiler flags -g for debug instrumentation and -Ofast for code optimisation. These optimisations cause unexpected code jumps when stepping through code in a debugger. To turn of optimisation (-O0) build with buildtype=debug, e.g.

$ meson _build buildtype=debug
$ ninja

Debug output

GEGL has built in mechanisms for logging debug information.

GEGL_NOTE(CACHE, "foo %s", bar);
GEGL_TIMESTAMP(PROCESSOR);
GEGL_MARK();

Where CACHE and PROCESSOR are used the following logging domains are available:

PROCESS, CACHE, BUFFER_LOAD, BUFFER_SAVE, TILE_BACKEND and PROCESSOR

Actual printing of these can be enabled by setting the GEGL_DEBUG environment variable:

$ GEGL_DEBUG=processor,cache

or even

$ GEGL_DEBUG=all

Other debug specific environment variables are also available.

There are also a few functions that are useful as you debug from within a debugger such as GDB. In GDB for example, you call a function interactively in the prompt, while a breakpoint is hit for example, by typing print function_name(args).

Some useful functions are:

  • gegl_dot_node_to_png_default() Writes a PNG to /tmp/node.png with the dependency graph for the passed node.

  • gegl_node_dump_depends_on() Dumps to stdout the nodes that the passed node depends on. With this you can work yourself backwards in a dependency graph.

  • gegl_node_get_debug_name() Prints a debug string representation of a node.

Graphviz export

The gegl library has a utility that permits to export of the DAG in Graphviz format. Graphviz is a library that creates visualisations of text graph descriptions. See the graphviz website.

It is done using:

#include "../gegl/gegl-dot.h"
/* for printing the dot output, note that gegl_node is a GeglNode pointer */
gchar *dot_output = gegl_to_dot( gegl_node );
printf( "%s\n", dot_output );
g_free( dot_output );

For creating the graph image:

$ gegl --file gaussian-blur.xml --output out.png | dot -Tpng > gb.png
gaussian-blur.xml
<?xml version='1.0' encoding='UTF-8'?>
<gegl>
  <node operation='gegl:gaussian-blur'>
    <params>
      <param name='std-dev-x'>0.999</param>
      <param name='std-dev-y'>0.999</param>
    </params>
  </node>
  <node operation='gegl:load'>
    <params>
      <param name='path'>in.png</param>
    </params>
  </node>
</gegl>

You can also just call the function gegl_dot_node_to_png() directly from within gdb to show the Graphviz graph of a node and its dependencies.

Tests

There are regression tests in the subfolder tests. These are run with the command meson test. On slow platforms the test timeouts can be multiplied n-fold using the -t n parameter. The tests are divided into a number test-suites and these may be run individually by using the parameter --suite suite-1 [[--suite suite-2] ...]. Individual tests can be run by appending the test name(s) to the command. For example:

$ meson test -t 5
$ meson test --suite composition
$ meson test alien_map bump_map

Operation reference renders

For the operation documentation available at The GEGL website the GEGL build runs ‘tools/gegl-tester` which generates a 200x200 pixel PNG image for each operation, based on a set of standard input images and default parameters, or optionally, with a custom, representative, GEGL graph stored in the operations’ meta-data.

GEGL tries to tune its settings to be as deterministic as possible when rendering these images, taking the md5sums of the raster content (not the PNG files) and comparing it against a reference md5sum also stored in the operation meta-data. Reference compositions with mismatched hashes are reported as errors by the program. It is possible to use this program for regression testing. To force a re-run of the image file generation remove the docs/operations/images sub-folder and run ninja again.

XML Composition tests

The tests under ‘tests/compositions` are high-level system tests for GEGL and its’ operations. Together with the GNOME gitlab CI/CD pipelines that run all our tests whenever the codebase is changed, the composition tests make a powerful framework for detecting regressions.

Adding an XML composition test

To add a composition test for a operation called gegl:new-operation, do the following:

  1. Create a GEGL XML file tests/compositions/new-operation.xml (will typically look approximately like tests/compositions/pixelise.xml).

  2. Produce a reference image: cd tests/compositions; gegl -o /tmp/new-operation.png new-operation.xml (make sure your operation is installed so gegl finds it).

  3. Manually inspect the reference image /tmp/new-operation.png and move it to tests/compositions/reference if it looks as you expect.

  4. Add the test name new-operation to composition_tests in the tests/compositions/meson.build file.

  5. Run meson test new-operation to verify that your test works.

When the composition test suite is called it will run gegl with tests/compositions/new-operation.xml and compare the result with tests/compositions/reference/new-operation.png. If the results differ, the test will fail. Whenever a new commit is made to the GEGL source code repository the CI/CD pipelines will be triggered and, if they fail, emails will be sent to the GEGL maintainers. Thus, if someone breaks your contributed GEGL operation, it will be discovered quickly, making it easy to fix, either by reverting or fixing the erroneous commit.

An example of a commit that adds a composition test for a GEGL operation is tests: add exposure and saturation composition.

Documentation

This document describes how to document GEGL using it’s build system.

There are three utilities used:

  1. asciidoc - used for generating html from text files.

  2. source-highlight - used to add syntax coloring to source code (called by asciidoc).

  3. gtk-doc - used for generating api documentation.

All documentation resources are placed in the doc sub-directory of the source tree and the generation is controlled by the meson.build files.

asciidoc

TODO

source-highlight

TODO

This example will show how a new c/h file is converted into html using asciidoc and source-highlight.

gtk-doc

The API documentation is generated automatically using gtk-doc. Normally this is created at install time but may be generated in the build tree by building the gegl-doc target manually:

$ ninja gegl-doc

Inheritance tree

There is an automatically generated inheritance tree of the gobjects used by gegl.

Note

Operations are also gobjects, but they are not included in the inheritance tree.