mjakeman / text-engine

A lightweight rich text framework for GTK
Other
21 stars 1 forks source link

Invalidation and Caching #11

Open mjakeman opened 2 years ago

mjakeman commented 2 years ago

text-engine uses multiple mutable trees in order to store semantic, style, layout, and render states.

The current pipeline (without a style module) looks as follows:

Model --> Layout --> Render

At present, we recreate the entire layout tree each time a draw is queued. Instead, we should cache the layout tree between redraws. Whenever a change is made to the model, the changed element should be marked as dirty (full recalculation) and all parent elements should be marked as having dirty descendants (partial recalculation).

The layout object watches for changes to the root element and triggers a partial recalculation whenever the root element is either marked dirty or has dirty descendants. Layout recalculations can be done in parallel, as we assume a normal flow for the document (this may change if floating images are supported). If there are more than N recalculations in a frame, we should mark the entire tree as dirty.

Something to avoid is recalculating layout every time the cursor and/or selection changes. This ties in with needing to support Home/End keyboard shortcuts on a per-line basis, as the length of a line is determined by the layout process rather than the document model itself. We'll need some way of moving from Model -> Layout efficiently in order to retrieve line layout data.

mjakeman commented 2 years ago

Regarding how the model, style, and layout modules should be connected, it might be worth looking at how webkit handles things:

https://webkit.org/blog/114/webcore-rendering-i-the-basics/