Donner SVG Editor & Engine
SVG-native editor and embeddable SVG2 + CSS3 engine in C++20, with GPU (WebGPU) and compact CPU renderers, built for correctness, security, and performance.
Loading...
Searching...
No Matches
donner::geode::GeodeResidentSlot Struct Reference

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 vertex quad, the six analytic dual-ray SSBO regions, and the per-draw uniform block, plus the cached fill bind group. 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 4-byte zero-filled slot so the shader's band-count gate keeps them un-dereferenced (matching the wave-1 arena allocStorageOrDummy dummy). More...

Public Member Functions

 GeodeResidentSlot (const GeodeResidentSlot &)=delete
GeodeResidentSlot & operator= (const GeodeResidentSlot &)=delete
 GeodeResidentSlot (GeodeResidentSlot &&) noexcept=default
GeodeResidentSlot & operator= (GeodeResidentSlot &&other) noexcept
void reset ()
 Release the GPU buffer + bind group handles and settle the live-bytes gauge. Safe to call on an empty slot. A geometry mutation can remove this component after a draw has referenced the buffer but before the frame's command encoder is submitted. Do not call Buffer::destroy() here: WebGPU makes that buffer unusable immediately, invalidating the already-recorded draw. Releasing our handles is sufficient because the command encoder keeps the referenced resources alive until it is done.

Public Attributes

ScopedWgpuHandle< wgpu::Buffer > buffer
 Combined Vertex|Storage|Uniform|CopyDst buffer. Layout (each region offset satisfies the binding's alignment requirement): [ vertex quad | bands | curves | vBands | vCurves | hGrid | vGrid | uniform ].
ScopedWgpuHandle< wgpu::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 vertex
 Vertex quad range (4-byte aligned offset).
Region bands
 Horizontal band SSBO (binding 1).
Region curves
 Horizontal curve SSBO (binding 2).
Region vBands
 Vertical band SSBO (binding 8).
Region vCurves
 Vertical curve SSBO (binding 9).
Region hGrid
 Horizontal band grid (binding 10).
Region vGrid
 Vertical band grid (binding 11).
Region uniform
 Per-draw uniform block (binding 0, 256-aligned).
uint32_t vertexCount = 0
 Number of quad vertices (draw count).
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 wave-1 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".
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 > 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 288-byte region and keeps the cached bind group.
std::shared_ptr< std::atomic< int64_t > > liveBytesGauge
 Live-resident-bytes gauge, co-owned with GeodeDevice so the accounting is lifetime-safe even if the owning document outlives the device. Incremented on residence, decremented on reset/destroy.
int64_t accountedBytes = 0

Detailed Description

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 vertex quad, the six analytic dual-ray SSBO regions, and the per-draw uniform block, plus the cached fill bind group. 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.


Class Documentation

◆ donner::geode::GeodeResidentSlot::Region

struct donner::geode::GeodeResidentSlot::Region

A byte sub-range of buffer. size == 0 is never bound directly - empty SSBO regions reserve a 4-byte zero-filled slot so the shader's band-count gate keeps them un-dereferenced (matching the wave-1 arena allocStorageOrDummy dummy).

Class Members
uint64_t offset = 0
uint64_t size = 0

The documentation for this struct was generated from the following file: