|
|
Donner SVG 0.8.0-pre
SVG editor and embeddable C++20 engine.
|
Geode rendering backend - GPU-native via WebGPU + the Slug algorithm. More...
#include "donner/svg/renderer/RendererGeode.h"
Public Member Functions | |
| RendererGeode (bool verbose=false) | |
| Construct the renderer. | |
| RendererGeode (std::shared_ptr< geode::GeodeDevice > device, bool verbose=false) | |
| Construct the renderer with an externally-owned GeodeDevice. | |
| RendererGeode (const RendererGeode &)=delete | |
| RendererGeode & | operator= (const RendererGeode &)=delete |
| RendererGeode (RendererGeode &&) noexcept | |
| Move constructor. | |
| RendererGeode & | operator= (RendererGeode &&) noexcept |
| Move assignment operator. | |
| void | setTargetTexture (wgpu::Texture texture) |
| Set a host-owned texture as the render target for subsequent frames. | |
| void | clearTargetTexture () |
| Clear a previously set target texture, reverting to internal offscreen targets allocated per-frame by beginFrame(). | |
| void | setPreserveTargetOnBeginFrame (bool preserve) override |
| Preserve the host-owned target contents when the next frame begins. | |
| void | setAntialias (bool antialias) |
| Enable analytic edge anti-aliasing. Disabled mode emits binary pixel-center coverage for deterministic ASCII snapshot tests. | |
| void | draw (SVGDocument &document) override |
| Renders the given SVG document. | |
| int | width () const override |
| Returns the rendered width in device pixels. | |
| int | height () const override |
| Returns the rendered height in device pixels. | |
| void | beginFrameResourceScope () override |
| Begins one aggregate resource-budget scope around a controller-managed frame. | |
| void | endFrameResourceScope () override |
| Completes a scope opened by beginFrameResourceScope. | |
| void | beginFrame (const RenderViewport &viewport) override |
| Begins a render pass with the given viewport. | |
| void | endFrame () override |
| Completes the current render pass, flushing any pending work. | |
| void | setTransform (const Transform2d &transform) override |
| Sets the absolute transform on the renderer, replacing the current matrix. | |
| void | pushTransform (const Transform2d &transform) override |
| Pushes a transform onto the renderer stack, composing with the current transform. | |
| void | popTransform () override |
| Pops the most recent transform from the renderer stack. | |
| void | pushClip (const ResolvedClip &clip) override |
| Pushes a clip path/mask onto the renderer stack. | |
| void | popClip () override |
| Pops the most recent clip from the renderer stack. | |
| void | pushIsolatedLayer (double opacity, MixBlendMode blendMode) override |
| Pushes an isolated compositing layer with the given opacity and blend mode. | |
| void | popIsolatedLayer () override |
| Pops the most recent isolated layer, compositing it with the given opacity. | |
| void | pushFilterLayer (const components::FilterGraph &filterGraph, const std::optional< Box2d > &filterRegion) override |
| Pushes a filter layer that applies the given filter graph to all content drawn within it. | |
| void | popFilterLayer () override |
| Pops the most recent filter layer. | |
| void | pushMask (const std::optional< Box2d > &maskBounds) override |
| Begins mask rendering. | |
| void | pushMask (const std::optional< Box2d > &maskBounds, MaskType maskType) override |
| Begins mask rendering with an explicit coverage mode. | |
| void | transitionMaskToContent () override |
| Transitions from rendering mask content to rendering masked content. | |
| void | popMask () override |
| Pops the mask layer stack, compositing the masked content. | |
| bool | beginPatternTile (const Box2d &tileRect, const Transform2d &targetFromPattern) override |
| Begins recording content into a pattern tile. | |
| void | endPatternTile (bool forStroke) override |
| Ends pattern tile recording and sets the resulting tiled shader as the current fill or stroke paint. | |
| void | setPaint (const PaintParams &paint) override |
| Sets the active paint parameters used by subsequent draw calls. | |
| void | drawPath (const PathShape &path, const StrokeParams &stroke) override |
| Draws an arbitrary path using the current paint state. | |
| void | drawRect (const Box2d &rect, const StrokeParams &stroke) override |
| Convenience helper for drawing axis-aligned rectangles. | |
| void | drawEllipse (const Box2d &bounds, const StrokeParams &stroke) override |
| Convenience helper for drawing ellipses bounded by the provided box. | |
| void | drawImage (const ImageResource &image, const ImageParams ¶ms) override |
| Draws an image resource into the given target rectangle. | |
| bool | drawTextureSnapshot (const RendererTextureSnapshot &texture, const Box2d &targetRect, double opacity=1.0, bool pixelated=false) override |
| Draws a backend-owned texture snapshot into the given target rectangle. | |
| void | drawText (Registry ®istry, const components::ComputedTextComponent &text, const TextParams ¶ms) override |
| Draws pre-shaped text with the provided paint parameters. | |
| RendererFilterPreparationBudget * | filterPreparationBudget () override |
| Shared driver-side filter preparation budget for this renderer family, when supported. | |
| std::unique_ptr< RendererInterface > | createOffscreenInstance () const override |
| Creates an independent offscreen renderer instance of the same type as this one. | |
| void | setOffscreenCreationHookForTesting (std::function< void()> hook) override |
| Install a zero-default hook entered after the new renderer owns its device. | |
| std::uint64_t | filterBudgetChunksForTesting () const override |
| Number of filter-budget command-buffer chunks submitted by this renderer family. | |
| RendererBitmap | takeSnapshot () const override |
| Captures a CPU-readable snapshot of the current frame buffer for testing or downstream consumers. | |
| RendererBitmap | takeSnapshotInterruptibly (const std::function< bool()> &shouldCancel) const override |
| Captures a CPU-readable snapshot while allowing a low-priority caller to abort the readback. | |
| RendererReadbackStats | consumeReadbackStats () override |
| Consume readback diagnostics accumulated by this renderer backend. | |
| bool | deviceLost () const |
| True once the GPU device backing this renderer has been declared lost, either by a driver-reported WebGPU device-lost callback or by a bounded GPU wait exceeding its deadline (for example a snapshot readback map that never completed). | |
| void | enableTimestamps (bool enabled) |
| Enable or disable GPU timestamp capture. | |
| void | setDebugGeometryOverlay (bool enabled) override |
| Enable or disable the Geode geometry debug overlay. | |
| bool | debugGeometryOverlay () const override |
| Whether the geometry debug overlay is enabled. | |
| FrameTimings | lastFrameTimings () const |
| Returns per-frame instrumentation for the most recently completed beginFrame→endFrame window. | |
| RendererGeodeTexturePoolStats | texturePoolStats () const |
| Returns retained-memory instrumentation for the transient texture pool. | |
| void | setGlyphResidencyBudgetForTesting (size_t maxEntries, uint64_t maxRetainedBytes) |
| Shrink the glyph-residency budget so eviction can be exercised without building a font-sized working set. | |
| void | setGeometryBudgetForTesting (std::size_t maximumDraws, std::size_t maximumItems, std::uint64_t maximumFrameBytes, std::uint64_t maximumCacheBytes, std::uint64_t maximumResidentBytes) |
| Shrink the aggregate geometry budget for boundary tests. | |
| void | setSurfaceBudgetForTesting (std::size_t maximumSurfaces, std::uint64_t maximumBytes) |
| Shrink the aggregate frame-surface budget for boundary tests. | |
| void | setTextMaterializationBudgetForTesting (RendererTextMaterializationBudget::Cost limits, std::size_t maximumGlyphOccurrences) |
| Shrink the aggregate text-materialization budget for boundary tests. | |
| void | injectScenePreparationFailureAfterForTesting (std::size_t successfulPreparations) |
| Fail one scene preparation after the requested number of successful preparations. | |
| RendererResourceStats | resourceStats () const override |
| Return aggregate resource-admission diagnostics for the current frame. | |
| size_t | residentGlyphCountForTesting (SVGDocument &document) |
| Number of glyph outlines currently resident for document. | |
| std::shared_ptr< const RendererTextureSnapshot > | takeTextureSnapshot () override |
| Captures the current resolved render target as a directly sampleable WebGPU texture. | |
| const RendererTextureSnapshot * | borrowTextureSnapshot () UTILS_LIFETIME_BOUND override |
| Borrows the current render target until the next frame mutation. | |
| bool | requiresTextureSnapshotPresentation () const override |
| Geode presentation is GPU-native when callers can sample WebGPU textures directly. | |
| Public Member Functions inherited from donner::svg::RendererInterface | |
| virtual void | drawBitmap (const RendererBitmap &bitmap, const ImageParams ¶ms) |
| Draws a CPU bitmap (typically a compositor layer/segment raster) into the given target rectangle. | |
| virtual void | injectFilterLocalRasterAllocationFailureForTesting () |
| Cause the next local filter raster allocation to fail in a boundary test. | |
Static Public Member Functions | |
| static bool | sceneBatchingEnabledForTesting () |
| Whether cross-entity ordered batching is compiled into this build. | |
Geode rendering backend - GPU-native via WebGPU + the Slug algorithm.
RendererGeode implements RendererInterface by translating draw calls into the lower-level donner::geode::GeoEncoder API.
| Mode | Constructor | Device ownership |
|---|---|---|
| Headless | RendererGeode(verbose) | Geode leases an exclusive pooled device |
| Shared | RendererGeode(shared_ptr<GeodeDevice>) | Caller shares ownership |
In all modes, Geode creates its own offscreen render target each frame unless a host-owned target is set via setTargetTexture().
Host applications that already own a WebGPU device can:
If GeodeDevice::CreateHeadless() fails (no GPU available), all draw operations become no-ops and takeSnapshot() returns an empty bitmap.
|
explicit |
Construct the renderer.
Acquires an exclusive lease on a pooled headless GeodeDevice; if device creation fails, the renderer enters a "no-op" state and all subsequent draw calls do nothing. Pooling avoids repeated physical-device creation and keeps WebGPU pipeline caches warm for sequential renderer instances, while concurrently live renderers receive independent devices. Callers that intentionally share a device should use the explicit-device constructor.
| verbose | If true, emit warnings to stderr for unsupported features the first time they are encountered. |
|
explicit |
Construct the renderer with an externally-owned GeodeDevice.
The caller retains shared ownership of the device; it must outlive every frame rendered through this renderer. This overload avoids creating a new WebGPU instance/adapter/device per renderer, which is important in test fixtures that construct thousands of short-lived renderers - Mesa llvmpipe (and some Intel ANV configurations) accumulate driver state across device creations and eventually deadlock.
| device | Shared device. Must not be null. |
| verbose | If true, emit warnings for unsupported features. |
|
overridevirtual |
Begins a render pass with the given viewport.
Implementations may allocate or reset backend-specific frame resources here.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Begins one aggregate resource-budget scope around a controller-managed frame.
A controller may render several offscreen passes before the root render pass. Backends that share frame budgets with their offscreen instances override this pair so every pass consumes one budget epoch instead of resetting independently. Ordinary single-pass callers may omit the scope and continue to rely on beginFrame.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Begins recording content into a pattern tile.
Content drawn between beginPatternTile and endPatternTile is captured as a repeating pattern.
| tileRect | The tile rectangle in pattern coordinate space. |
| targetFromPattern | Transform from pattern tile space to target element space. |
Implements donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Borrows the current render target until the next frame mutation.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Consume readback diagnostics accumulated by this renderer backend.
Backends without asynchronous GPU readback return zeroed stats.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Creates an independent offscreen renderer instance of the same type as this one.
Used for rendering sub-documents into intermediate pixmaps when a backend needs an isolated offscreen pass (e.g., for feImage with SVG content). Returns nullptr if offscreen rendering is not supported.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Whether the geometry debug overlay is enabled.
Reimplemented from donner::svg::RendererInterface.
|
nodiscard |
True once the GPU device backing this renderer has been declared lost, either by a driver-reported WebGPU device-lost callback or by a bounded GPU wait exceeding its deadline (for example a snapshot readback map that never completed).
The condition is sticky.
Once lost: draw calls may produce no usable output, snapshots return empty bitmaps promptly instead of waiting out the readback deadline, and destroying this renderer and its GeodeDevice performs no further GPU waits (GPU resources are deliberately leaked rather than risking a blocking call into a hung driver). Callers should treat a lost device as fatal for this renderer instance: destroy it and recreate the renderer, or fall back to a CPU backend.
|
overridevirtual |
Renders the given SVG document.
Implementations prepare the document, traverse the render tree, and emit drawing commands.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Convenience helper for drawing ellipses bounded by the provided box.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Draws an image resource into the given target rectangle.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Draws an arbitrary path using the current paint state.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Convenience helper for drawing axis-aligned rectangles.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Draws pre-shaped text with the provided paint parameters.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Draws a backend-owned texture snapshot into the given target rectangle.
Backends that cannot consume texture directly return false. Callers should retain a CPU bitmap fallback when cross-backend composition is required.
Reimplemented from donner::svg::RendererInterface.
| void donner::svg::RendererGeode::enableTimestamps | ( | bool | enabled | ) |
Enable or disable GPU timestamp capture.
No-op today; reserved for future work. When wired up, this will drive the renderPassNs / totalGpuNs fields of lastFrameTimings(). Counters (the primary regression signal) are always on regardless of this flag.
|
overridevirtual |
Completes the current render pass, flushing any pending work.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Completes a scope opened by beginFrameResourceScope.
Reimplemented from donner::svg::RendererInterface.
|
overridevirtual |
Ends pattern tile recording and sets the resulting tiled shader as the current fill or stroke paint.
| forStroke | If true, set the pattern as the stroke paint; otherwise as the fill paint. |
Implements donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Number of filter-budget command-buffer chunks submitted by this renderer family.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Shared driver-side filter preparation budget for this renderer family, when supported.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Returns the rendered height in device pixels.
Implements donner::svg::RendererInterface.
|
nodiscard |
Returns per-frame instrumentation for the most recently completed beginFrame→endFrame window.
Valid after the first endFrame(); before then all fields are zero.
|
overridevirtual |
Pops the most recent clip from the renderer stack.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Pops the most recent filter layer.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Pops the most recent isolated layer, compositing it with the given opacity.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Pops the mask layer stack, compositing the masked content.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Pops the most recent transform from the renderer stack.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Pushes a clip path/mask onto the renderer stack.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Pushes a filter layer that applies the given filter graph to all content drawn within it.
| filterGraph | The filter graph describing primitives and their connections. |
| filterRegion | The filter region bounds in local coordinates, used to clip the filter output. If nullopt, the filter operates on the full surface. |
Implements donner::svg::RendererInterface.
|
overridevirtual |
Pushes an isolated compositing layer with the given opacity and blend mode.
Content drawn between pushIsolatedLayer and popIsolatedLayer is composited as a group at the specified opacity using the specified blend mode.
Implements donner::svg::RendererInterface.
|
inlineoverridevirtual |
Begins mask rendering.
The driver renders the mask content between pushMask and transitionMaskToContent, then renders the actual content between transitionMaskToContent and popMask.
This compatibility entry point begins a luminance mask. Existing embedders that implement this pure virtual remain source-compatible. Override the typed overload to support alpha masks.
| maskBounds | Optional clip rect for the mask region. |
Implements donner::svg::RendererInterface.
|
overridevirtual |
Begins mask rendering with an explicit coverage mode.
Appended after the legacy virtual surface to preserve existing vtable slot order. The default compatibility implementation delegates to the one-argument luminance entry point. Backends that support MaskType::Alpha override this overload.
| maskBounds | Optional clip rect for the mask region. |
| maskType | Whether mask coverage comes from luminance or alpha. |
Reimplemented from donner::svg::RendererInterface.
|
overridevirtual |
Pushes a transform onto the renderer stack, composing with the current transform.
Implements donner::svg::RendererInterface.
|
inlinenodiscardoverridevirtual |
Geode presentation is GPU-native when callers can sample WebGPU textures directly.
Not on the browser build. WebGPU has no cross-thread device, surface, or texture sharing in any shipping engine, so a texture produced on the raster thread cannot be sampled by the app thread's device. Browser tiles therefore cross the thread boundary as CPU bitmaps and are uploaded once per tile generation into the compositing device (single-canvas presenter architecture). The worker-owned surface that used to consume a texture snapshot directly is gone.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Return aggregate resource-admission diagnostics for the current frame.
Reimplemented from donner::svg::RendererInterface.
|
staticnodiscard |
Whether cross-entity ordered batching is compiled into this build.
Batching collapses many draws into one, so any assertion about draw-call counts or about the buffer traffic a batch's records replace has a different right answer in each build state. Tests read this rather than hard-coding one of them.
| void donner::svg::RendererGeode::setAntialias | ( | bool | antialias | ) |
Enable analytic edge anti-aliasing. Disabled mode emits binary pixel-center coverage for deterministic ASCII snapshot tests.
| antialias | True to retain analytic edge coverage. |
|
overridevirtual |
Enable or disable the Geode geometry debug overlay.
When enabled, an observer on every path-capable GeoEncoder records at the four actual Slug GPU submission paths (gradient, mask, resident fill, and transient/instanced fill). For each instance it reconstructs the submitted convex-fan triangles from EncodedPath::boundingVertices, including the shader's dynamic pixel dilation, transform fallbacks, and all submitted transforms. Text, strokes, clips, masks, and instanced paths are therefore included. Pattern-tile resource internals are deliberately excluded; the consuming pattern fill's path submission is captured instead.
endFrame() draws the collected one-device-pixel opaque-magenta edges in one final root-target pass. Normal document pixels between edges remain unchanged, and later SVG paint, filters, masks, or opacity cannot cover or distort the wireframe. Resource and compositor offscreen instances do not inherit the flag.
Default off. The focused regression verifies that explicitly-off output is byte-identical to the default-off renderer. No sink or capture storage is installed; the only hot-path cost is one null-sink branch at each actual Slug submission. Normal batching and <use> instancing remain enabled in debug mode; the observer expands submitted instances for the wireframe and the final overlay contributes one additional draw call.
Reimplemented from donner::svg::RendererInterface.
| void donner::svg::RendererGeode::setGlyphResidencyBudgetForTesting | ( | size_t | maxEntries, |
| uint64_t | maxRetainedBytes ) |
Shrink the glyph-residency budget so eviction can be exercised without building a font-sized working set.
| maxEntries | Distinct cached glyph outlines to keep. |
| maxRetainedBytes | Summed outline and encode bytes to keep. |
|
overridevirtual |
Install a zero-default hook entered after the new renderer owns its device.
Reimplemented from donner::svg::RendererInterface.
|
overridevirtual |
Sets the active paint parameters used by subsequent draw calls.
Implements donner::svg::RendererInterface.
|
overridevirtual |
Preserve the host-owned target contents when the next frame begins.
This is for embedded append passes: the host has already rendered into the target texture, and Geode should draw additional renderer primitives on top instead of clearing the texture.
| preserve | True to use LoadOp::Load for the first render pass. |
Reimplemented from donner::svg::RendererInterface.
| void donner::svg::RendererGeode::setTargetTexture | ( | wgpu::Texture | texture | ) |
Set a host-owned texture as the render target for subsequent frames.
When a target texture is set, beginFrame() renders into it instead of allocating an internal offscreen target. The texture must:
If the texture also has CopySrc usage, takeSnapshot() can read it back. If it lacks CopySrc, takeSnapshot() returns an empty bitmap.
The host retains ownership of the texture; it must remain valid from beginFrame() through endFrame(). Call clearTargetTexture() to revert to internal offscreen targets.
| texture | Host-owned render target texture. Must not be null. |
|
overridevirtual |
Sets the absolute transform on the renderer, replacing the current matrix.
Unlike pushTransform, this does not interact with the save/restore stack.
Implements donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Captures a CPU-readable snapshot of the current frame buffer for testing or downstream consumers.
The snapshot must remain valid after the render pass completes.
Implements donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Captures a CPU-readable snapshot while allowing a low-priority caller to abort the readback.
Backends whose snapshots are already bounded may inherit this default. GPU backends should override it and poll shouldCancel while waiting for mapped readback data.
Reimplemented from donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Captures the current resolved render target as a directly sampleable WebGPU texture.
For internally-owned render targets, this transfers ownership out of the renderer and detaches the current target so a subsequent same-size frame cannot overwrite a texture still being sampled by editor presentation.
Reimplemented from donner::svg::RendererInterface.
|
overridevirtual |
Transitions from rendering mask content to rendering masked content.
Must be called between pushMask and popMask.
Implements donner::svg::RendererInterface.
|
nodiscardoverridevirtual |
Returns the rendered width in device pixels.
Implements donner::svg::RendererInterface.