Donner SVG 0.8.0-pre
SVG editor and embeddable C⁠+⁠+⁠20 engine.
Loading...
Searching...
No Matches
RendererTinySkiaCache.h File Reference

Per-entity caches for the conversions donner::svg::RendererTinySkia runs on the way into tiny-skia. More...

#include <cstdint>
#include <optional>
#include <vector>
#include "tiny_skia/Path.h"
Include dependency graph for RendererTinySkiaCache.h:

Classes

struct  donner::svg::components::TinySkiaPathCacheComponent
 Per-entity cache of a shape's donner::Path converted to tiny_skia::Path. More...
struct  donner::svg::components::TinySkiaImageCacheComponent
 Per-entity cache of a LoadedImageComponent's pixels converted from the straight-alpha ImageResource contract to the premultiplied form tiny-skia samples. More...

Namespaces

namespace  donner
 Top-level Donner namespace, which is split into different sub-namespaces such as donner::svg and donner::css.
namespace  donner::svg
 Donner SVG library, which can load, manipulate and render SVG files.
namespace  donner::svg::components
 Contains the implementation of the Donner ECS,.

Detailed Description

Per-entity caches for the conversions donner::svg::RendererTinySkia runs on the way into tiny-skia.

Both conversions below are pure functions of document state that does not change between frames, yet the backend re-ran them on every draw of every frame:

  • donner::Path -> tiny_skia::Path, which allocates a verb buffer and a point buffer per shape per frame. A document with a few hundred shapes pays that several hundred times a frame for geometry that never moved.
  • An image's straight-alpha pixels -> premultiplied pixels, a full-buffer pass plus a full-buffer allocation for every image draw.

Invalidation is owned by donner::svg::RendererTinySkia, which connects entt on_update + on_destroy listeners for the source component and removes the matching cache component whenever that source changes. A cached conversion that outlived its source would be a correctness bug, not a stale optimization, so the listeners are wired before the first cache entry is installed and cover both mutation and teardown. ShapeSystem's content-equality gate (emplaceComputedPathIfChanged) keeps the path signals from firing on an unchanged re-render, so an idle frame keeps its caches intact.


Class Documentation

◆ donner::svg::components::TinySkiaPathCacheComponent

struct donner::svg::components::TinySkiaPathCacheComponent

Per-entity cache of a shape's donner::Path converted to tiny_skia::Path.

Installed lazily at the draw call sites via get_or_emplace, keyed by PathShape::sourceEntity; removed by the ComputedPathComponent listener when the geometry changes or the entity goes away. A null source entity (overlay drawing, test harnesses) is not cached and converts inline, exactly as before the cache existed.

Lives in donner::svg::components, alongside ComputedPathComponent and every other component it derives from, rather than in a backend-private namespace. (Geode's equivalent sits in donner::geode instead, to match the other Geode types its renderer references unqualified; the tiny-skia backend has no such namespace and already spells its component dependencies components::.)

Class Members
optional< Path > closedPath Conversion that preserves ClosePath verbs. Used by fills and by every ordinary stroke.
optional< Path > openedPath Conversion that replaces each ClosePath with an explicit closing line. Used only by the dash-stroke path that has to emit caps at a closed contour's seam, so it is filled in on demand rather than alongside closedPath.

◆ donner::svg::components::TinySkiaImageCacheComponent

struct donner::svg::components::TinySkiaImageCacheComponent

Per-entity cache of a LoadedImageComponent's pixels converted from the straight-alpha ImageResource contract to the premultiplied form tiny-skia samples.

Installed lazily by drawImage via get_or_emplace, keyed by ImageParams::sourceEntity; removed by the LoadedImageComponent listener when the element loads different pixels or goes away. The dimensions are stored alongside the payload and rechecked on every hit, so a draw whose source no longer matches the cached buffer reconverts instead of sampling the wrong extent.

Residency tradeoff: the cached payload is a second full copy of the element's decoded pixels and there is no eviction, so a drawn image stays doubled in resident bytes for as long as the document holds it. That is bounded by the images the document actually draws (an undrawn or removed image holds nothing), and it buys a full-buffer conversion pass and allocation per image per frame; a document with a large enough image working set to care would need an eviction policy this cache deliberately does not have.

See also
TinySkiaPathCacheComponent for the namespace-placement rationale.
Class Members
int height = 0 Height the payload was converted at, in pixels.
vector< uint8_t > premultiplied Premultiplied RGBA8, tightly packed.
int width = 0 Width the payload was converted at, in pixels.