gaphor/gaphas

Improve the render cycle

amolenaar opened this issue · 2 comments

Is your feature request related to a problem? Please describe.

In Gaphor we want grey-out elements a line (e.g. association) can connect to. The current drawing process (using Painter instances) is probably not well suited. Also, this flow has been designed based on GTK+ 2.0. The render process has changed drastically for GTK+ 3 and 4. Gaphas should update it's render pipeline accordingly.

Currently all drawing and styling is handled in Item.draw(). For Gaphor we added (CSS) styling to the mix. It would be great if we can separate the render shapes and styling a little more.

Describe the solution you'd like

I like to separate the render and drawing phase. The render phase should provide a structure (tree/list) of paint nodes. These nodes are collected separately from the actual drawing process.

This allows us to transform items (e.g. grey out the shapes) of an item without the need for a re-render of the item.

Describe alternatives you've considered

  • Stick with the current situation: the current update/draw process is based on GTK+ 2.0, we're close to GTK 4 now.

Additional context

I checked on how GTK and Clutter/Mutter do their rendering. Basically they use 2 phases:

  1. Collect all render nodes/shapes
  2. Draw the items to the screen (buffer)

This allows us to add filters in between the drawing process. E.g. to grey-out items.
We produce a render tree and this is used by the view until a re-render is required. We should be able to implement speed optimizations within Gaphas, without bothering application code.

If we do this, we can basically merge the post_update and draw functionality of items into one.

Open questions

  • How to deal with drawing handles, guides, rubber-band selection, etc.?

  • Some data is coming from items, such as handles. Should the render API provide methods for handling handles?

  • Guides and such are rendered by tools, when items are moved. How to add this info to the render pipeline?

  • Should we re-render on state change (normal, focused, selected)? Can we add CSS or conditional nodes to the mix?

  • Should we stick with Cairo? GTK 4 switched to Vulkan/OpenGL renderers. The Cairo API is simple and served us well. Also it allows us to export diagrams to PNG, SVG, etc., without hassle. So yes. If we can, let's stick with Cairo IMHO.

References:

I think things are simpler now that there is only one update cycle initiated by the View.

It will be hard to collect drawing nodes/shapes. Mainly due to the way Pango integrates with Cairo. It's not possible to record text rendering.

Alternatively we could provide our own Cairo-like drawing interface, that also incorporates Pango layouts.