|
|
Donner SVG 0.8.0-pre
SVG editor and embeddable C++20 engine.
|
GPU-resident geometry for one cached EncodedPath (a fill slot or a stroke slot). Owns a single combined-usage GPU buffer that holds the path's eight analytic dual-ray SSBO regions and per-draw uniform block, plus the cached fill bind group. Bounding vertices live in that uniform and are expanded from vertex_index, so the resident geometry needs no vertex buffer. The buffer and bind group are built once by GeoEncoder on first residence and reused every subsequent unchanged frame. More...
#include "donner/svg/renderer/geode/GeodeResidentPathComponent.h"
Classes | |
| struct | Region |
| A byte sub-range of buffer. size == 0 is never bound directly - empty SSBO regions reserve a zero-filled dummy slot wide enough for one element of the WGSL array they feed, so the shader's band-count gate keeps them un-dereferenced and the binding still passes WebGPU's minimum-size validation (matching the per-frame arena allocStorageOrDummy dummy). More... | |
Public Attributes | |
| gpu::BufferRef | buffer |
| Combined Storage|Uniform|CopyDst buffer, borrowed from the owning GeodeResidentSlab chunk. Region offsets are ABSOLUTE buffer offsets. Layout (each region offset satisfies the binding's alignment requirement): [ bands | curves | vBands | vCurves | hGrid | vGrid | hRefs | vRefs | uniform ] The four grid classes are placed adjacently on purpose: they share one storage binding, whose range spans them. The slot is padded out to the slab's allocation alignment so consecutive slots leave no unwritten bytes between them. | |
| uint64_t | bufferId = 0 |
| Stable identity of buffer (see GeodeDevice::AllocateBufferId). A cross-entity batch binds the whole chunk and caches the resulting bind group past the lifetime of the document that owns it, so the cache key has to name the chunk by this id rather than by the handle address, which the allocator recycles once the slab is destroyed. | |
| std::shared_ptr< GeodeResidentSlab > | slab |
| Slab that owns buffer; null until residence is established. Held by shared_ptr so a device change (which swaps the registry's slab) cannot leave a slot referencing a destroyed slab: old slots keep the old slab alive until their own reset drops the reference. | |
| uint64_t | allocationOffset = 0 |
| Whole-slot allocation inside the slab, returned via free on reset. | |
| uint64_t | allocationSize = 0 |
| gpu::BindGroup | bindGroup |
| Cached fill bind group. All twelve bindings reference stable objects (this slot's buffer sub-ranges + device-owned dummy texture/sampler/identity-instance handles), so it survives frames and encoders. Rebuilt only when the geometry buffer is re-allocated. | |
| Region | bands |
| Horizontal band SSBO (binding 1). | |
| Region | curves |
| Horizontal curve SSBO (binding 2). | |
| Region | hRefs |
| Horizontal curve-reference SSBO (binding 10). | |
| Region | vBands |
| Vertical band SSBO (binding 8). | |
| Region | vCurves |
| Vertical curve SSBO (binding 9). | |
| Region | vRefs |
| Vertical curve-reference SSBO (binding 10). | |
| Region | hGrid |
| Horizontal band grid (binding 10). | |
| Region | vGrid |
| Vertical band grid (binding 10). Gradient paint block: transform rows, gradient geometry, and the stop ramp, as vec4 rows addressed by the record's paintBase (binding 11). Always reserved, so a fill that changes from solid to gradient paint rewrites this region rather than re-laying-out the slot; a solid fill leaves it zero-filled and its record never reads it. | |
| Region | paint |
| Region | uniform |
| Batch-level uniform block (binding 0, 256-aligned). | |
| GeodeRecordSlab::Slot | recordSlot |
| Document-scoped record slab slot for this entity's instance record (binding 7). Solo draws bind the slot's own range; cross-entity batches bind a span of consecutive slots and index by slot index. | |
| std::shared_ptr< GeodeRecordSlab > | recordSlab |
| Record slab that owns recordSlot; mirrors the geometry slab's device-change lifetime handling. | |
| uint32_t | vertexCount = 0 |
| Triangle-fan draw count generated from vertex_index. | |
| uint64_t | lastResidentFrame = ~uint64_t{0} |
| Frame index in which this slot was last drawn via the resident path. A slot's single uniform buffer + cached bind group can only serve ONE draw per frame (all draws recorded against a frame's command buffer read the buffer's final contents at submit time). When the same slot is drawn again in the same frame at a different transform/color (markers, non-adjacent repeated <use>), the second and later draws fall back to the per-frame arena path so each gets its own uniform. The steady-state win is unaffected for the common case of a path drawn once per frame (Tiger / Lion). Sentinel ~0 means "never drawn". | |
| uint64_t | owningDeviceId = 0 |
| Process-unique id (see GeodeDevice::deviceId()) of the device that created buffer / bindGroup. A document's ECS residence components can outlive the device that filled them and later be rendered by a second RendererGeode / GeodeDevice; WebGPU rejects a bind group or buffer from device A inside device B's render pass. When this id does not match the current device at draw time the slot is treated as non-resident and re-uploaded onto the current device (the stale handles are released without touching the old device). 0 means "no device
owns this slot yet". | |
| uint64_t | lastSceneFrame = ~uint64_t{0} |
| Frame index in which this slot's record was last referenced by a recorded scene-batch draw. A record slot holds ONE record; an entity drawn again in the same frame (markers, repeated <use>) needs a fresh record slot so earlier recorded batches keep reading their own content at submit time. The scene batcher consults this to decide between the slot's primary record and a per-frame temporary one. | |
| bool | resident = false |
| True once buffer + bindGroup hold the current encode. Cleared when the slot is reset or when a re-upload is required. | |
| const void * | encodedKey = nullptr |
| Identity guard defending against any missed invalidation: the address of the EncodedPath last uploaded plus a cheap size fingerprint. If either differs at draw time the geometry is re-uploaded. Component removal is the primary invalidation; this is belt-and-suspenders for the in-place stroke-slot rebuild path. | |
| uint64_t | encodedFingerprint = 0 |
| std::vector< uint8_t > | lastRecord |
| Bytes last written to the instance-record region. A draw whose recomputed record matches this skips the writeBuffer entirely (steady-state frames write zero record bytes). | |
| std::vector< uint8_t > | lastPaint |
| Bytes last written to the gradient paint region, with the same skip-when-unchanged contract as the record and the uniform. | |
| uint32_t | paintMode = 0 |
| Paint published by the last paint write: the record's paintMode and the two gradient scalars that go with it. They live on the slot rather than travelling with each draw because a batch re-derives an instance's record at flush time, after the caller's resolved gradient is gone, and must reproduce byte-identical bytes. | |
| uint32_t | gradientSpread = 0 |
| uint32_t | gradientStopCount = 0 |
| std::vector< uint8_t > | lastUniform |
| Bytes last written to the uniform region. A draw whose recomputed uniform matches this skips the writeBuffer entirely (steady-state static frame => zero buffer writes); a camera/color change rewrites only this 416-byte region and keeps the cached bind group. | |
| GeodeGeometryCacheReservation | cpuMirrorReservation |
| uint64_t | cpuUniformBytes = 0 |
| uint64_t | cpuRecordBytes = 0 |
| uint64_t | cpuPaintBytes = 0 |
GPU-resident geometry for one cached EncodedPath (a fill slot or a stroke slot). Owns a single combined-usage GPU buffer that holds the path's eight analytic dual-ray SSBO regions and per-draw uniform block, plus the cached fill bind group. Bounding vertices live in that uniform and are expanded from vertex_index, so the resident geometry needs no vertex buffer. The buffer and bind group are built once by GeoEncoder on first residence and reused every subsequent unchanged frame.
Move-only (owns wgpu handles). Default-constructed slots are empty; GeoEncoder::fillPathResident populates them lazily.
| struct donner::geode::GeodeResidentSlot::Region |
A byte sub-range of buffer. size == 0 is never bound directly - empty SSBO regions reserve a zero-filled dummy slot wide enough for one element of the WGSL array they feed, so the shader's band-count gate keeps them un-dereferenced and the binding still passes WebGPU's minimum-size validation (matching the per-frame arena allocStorageOrDummy dummy).
| Class Members | ||
|---|---|---|
| uint64_t | offset = 0 | |
| uint64_t | size = 0 | |