|
|
Donner 0.5.1
Embeddable browser-grade SVG2 engine
|
AsyncRenderer owns a svg::Renderer and runs its draw() + takeSnapshot() on a dedicated worker thread so heavy renders don't block the UI thread. More...
#include <atomic>#include <condition_variable>#include <cstdint>#include <functional>#include <mutex>#include <optional>#include <thread>#include <unordered_map>#include "donner/base/EcsRegistry.h"#include "donner/base/Vector2.h"#include "donner/svg/SVGDocument.h"#include "donner/svg/SVGElement.h"#include "donner/svg/compositor/CompositorController.h"#include "donner/svg/compositor/ScopedCompositorHint.h"#include "donner/svg/renderer/Renderer.h"#include "donner/svg/renderer/RendererInterface.h"Classes | |
| struct | donner::editor::RenderRequest |
| Per-request handoff data captured at render-request time so the worker has everything it needs without touching live UI state. More... | |
| struct | donner::editor::RenderRequest::DragPreview |
| struct | donner::editor::RenderResult |
| Bitmap plus the document version it was rendered from. More... | |
| struct | donner::editor::RenderResult::CompositedPreview |
| class | donner::editor::AsyncRenderer |
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. | |
AsyncRenderer owns a svg::Renderer and runs its draw() + takeSnapshot() on a dedicated worker thread so heavy renders don't block the UI thread.
The worker thread owns the Renderer for its entire lifetime — the Renderer is constructed on the worker thread at startup and destroyed on the worker thread at shutdown. This is load-bearing for the Geode (WebGPU) backend under Emscripten pthreads: WebGPU JS objects are per-worker, so the device, pipelines, textures, and readback buffers must all be created and used on a single thread. See the "first render aborts with `getJsObject` assertion" incident that motivated moving renderer ownership here.
The worker additionally takes exclusive ownership of the SVGDocument during an active render. The UI thread must not mutate the document while a render is in flight.
UI thread flow per frame:
The safety invariant: between requestRender() and a non-nullopt return from pollResult(), the UI thread must not mutate the SVGDocument, and must not touch state the overlay renderer reads (selection, etc. — those are snapshotted at request time, see RenderRequest). The UI thread must not call any method on the Renderer at any time — it lives on the worker.
| struct donner::editor::RenderRequest::DragPreview |
| Class Members | ||
|---|---|---|
| Entity | entity = entt::null | |
| InteractionHint | interactionKind = svg::compositor::InteractionHint::ActiveDrag | Which interaction phase drove this preview. Selection means the editor is pre-warming a layer for the selected entity before any drag begins. ActiveDrag means the user is actively dragging — the DOM's transform attribute already reflects the cursor delta, so no extra translation is passed here. The compositor stamps the correct InteractionHint on the entity based on this field so downstream introspection stays accurate. |