|
|
| ~GeodeDevice () |
| | Destructor releases logical resources before their runtime device and selected root. Native builds wait, bounded by lack of progress, for this context's submitted work, and a declared loss skips those waits; a Vulkan runtime device still proves its own submissions complete when it is destroyed. WebAssembly builds do not wait.
|
|
| GeodeDevice (const GeodeDevice &)=delete |
|
GeodeDevice & | operator= (const GeodeDevice &)=delete |
|
| GeodeDevice (GeodeDevice &&)=delete |
|
GeodeDevice & | operator= (GeodeDevice &&)=delete |
|
uint32_t | maxTextureDimension2D () const |
| | Maximum supported width or height of a 2D texture on this device.
|
| GpuWaitResult | waitForQueueIdle (std::chrono::milliseconds stallBound=kDefaultGpuWaitTimeout) const |
| | Wait, bounded by lack of progress, for all submitted GPU work to complete.
|
|
void | setQueueWaitResultForTesting (std::optional< GpuWaitResult > result) |
| | Overrides one queue-idle result while preserving its loss side effects. Test seam.
|
|
bool | isDeviceLost () const |
| | True once this device has been declared lost, either by its backend or by a bounded GPU wait exceeding its deadline. Sticky: never resets. Once lost, rendering output is undefined, snapshots return empty bitmaps promptly, and this context's teardown skips its queue-idle waits; a Vulkan runtime device still proves its own submissions complete when it is destroyed.
|
|
bool | isBoundToCreatingThread () const |
| | Whether this device may only be used on the thread that created it: true on the browser backend, whose objects belong to the worker that made them, and false on every backend whose devices any thread may drive. A cache of idle devices hands a bound device back only to the thread that created it.
|
| void | markDeviceLost (const char *reason) const |
| | Declare this device lost with no wait to attribute it to. Idempotent; the first call logs reason. Called when a frame's or a filter's commands cannot be closed, submitted, or restored, and available to embedders whose own device-lost signal is not shared through the selected root. Bounded waits that give up use markDeviceLostAfterWaitTimeout instead. Const because observers treat the flag as shared diagnostic state and waits that discover a hang run through const accessors.
|
| void | markDeviceLostAfterWaitTimeout (GpuWaitSite site, std::chrono::milliseconds elapsed, const char *reason) const |
| | Declare this device lost because a bounded wait exceeded its deadline, recording which wait it was and how long it actually ran.
|
| void | setSnapshotReadbackBudgetForTesting (std::chrono::milliseconds budget) |
| | Override the total capture budget for deterministic cancellation/deadline tests.
|
| void | setSnapshotReadbackHookForTesting (std::function< void(SnapshotReadbackPhase)> hook) |
| | Install a capture-phase test hook; it may be called concurrently by capture waiters.
|
|
void | setSnapshotCaptureRuntimeHookForTesting (std::function< void(gpu::Device &)> hook) |
| | Test-only access to the capture runtime while its lease is held, before it submits work. Set only while captures are quiescent; the callback must not retain the reference past the capture context's lifetime.
|
| void | recordReadback (bool usedTimedWaitAny, int pollIterations) |
| | Record one readback buffer-map wait from a renderer sharing this device, whether or not the map completed.
|
|
ReadbackStats | consumeReadbackStats () |
| | Consume aggregate readback diagnostics for all renderers sharing this device.
|
|
const std::shared_ptr< GeodeDeviceLostState > & | lostState () const |
| | The sticky loss condition of the physical root this context renders through, shared with every other context over that root and with the runtime devices driving it. Retained rather than borrowed because a backend device-lost callback can outlive the context that registered it.
|
|
std::shared_ptr< GeodePhysicalDeviceOwner > | physicalDeviceOwner () const |
| | Shared owner of the selected backend root and the runtime device the first context over it renders through, retained by every logical context over that root. Pass it to CreateOverPhysicalDeviceOwner for a sibling context with a runtime device of its own.
|
|
gpu::TextureFormat | textureFormat () const |
| | Render-target texture format, chosen by the caller or defaulted to RGBA8Unorm.
|
| void | deferDestroy (gpu::BindGroup bindGroup) |
| | Enqueue a bind group for deferred destruction.
|
| bool | deferDestroyTextureBacking (gpu::Texture &&texture) |
| | Transfer owned texture backing to this context's thread-safe retirement mailbox.
|
| bool | deferDestroyTextureBackingAfterSerial (gpu::Texture &&texture, uint64_t serial) |
| | Retain a failed frame's owned texture until this context has completed serial, then destroy its backing instead of recycling it with any unsubmitted writes.
|
|
void | drainFencedTextureBackings () |
| | Retire completed failed-frame textures without blocking on GPU progress.
|
|
std::size_t | pendingFencedTextureBackings () const |
| | Number of failed-frame textures still awaiting a submission fence.
|
|
void | drainDeferredTextureBackings () |
| | Destroy queued texture backing on the owning rendering context or during exclusive teardown.
|
| const std::shared_ptr< GeodeHandleRetirement > & | handleRetirement () const |
| | Where state kept for this context on another thread's behalf - a document's resident slabs, say - hands back this context's buffers and bind groups when it is destroyed, so they are released on this context's thread (see GeodeHandleRetirement).
|
|
void | releaseRetiredHandles () |
| | Releases the handles other threads retired to this context. Call on this context's thread; the renderer does at every frame boundary.
|
|
GeodeHandleRetirement::HeldCounts | retiredHandleCountsForTesting () const |
| | Handles retired to this context and not yet released. Test accessor.
|
|
bool | retirementOutlivesOwnedRuntimeDeviceForTesting () const |
| | Whether this context's retirement is destroyed after the runtime device it created, as handleRetirement requires: true when handleRetirement_ is declared before ownedRuntimeDevice_. Test accessor.
|
| void | drainDeferredDestroys () |
| | Drop all deferred-destroy handles, releasing their GPU resources.
|
|
void | pollIdle () |
| | Nonblocking owner-thread maintenance after a frame or while the renderer is idle. Drains cross-thread mailboxes, pumps callback-driven backends once, and releases completed work. No new submission or queue wait is required.
|
|
bool | hasIdleWork () const |
| | Whether idle maintenance can still free resources when a completion arrives. Owner-thread only; event loops may use it to schedule a short maintenance wake instead of rendering.
|
|
void | setIdleWakeCallback (std::function< void()> callback) |
| | Posts a cheap wake when a cross-thread retirement arrives. Callbacks must not reenter this context and must be cleared before their event loop is destroyed.
|
|
std::size_t | deferredTextureDestroyCountForTesting () const |
| | Number of texture backings waiting for the next frame-boundary destroy pass. Exposed to pin resource-retirement behavior in renderer regression tests.
|
| GpuWaitResult | waitForSnapshotCaptureIdleForTesting (std::chrono::milliseconds timeout=kDefaultGpuWaitTimeout) |
| | Waits until the snapshot capture context's queue has no submitted work left, so a test can check what the owner's next release point frees once every capture has finished on the GPU, without polling for it.
|
|
const gpu::BindGroup * | findSceneBatchBindGroup (const SceneBatchBindGroupKey &key) |
| | Look up a cached scene-batch bind group. Returns a borrowed handle (valid while the cache entry lives), or an empty handle on miss. A hit refreshes the entry to most-recently-used, so eviction at the cap drops the coldest entry rather than the oldest-inserted one - with more than the cap of live groups, pure insertion order would evict the hottest steady-state entry every frame.
|
|
const gpu::BindGroup & | storeSceneBatchBindGroup (const SceneBatchBindGroupKey &key, gpu::BindGroup group) |
| | Store a scene-batch bind group under key, taking ownership of the +1 handle. At the cap, the OLDEST entries are evicted one at a time rather than the whole cache being dropped: the cache is device-wide and a key belongs to one document's buffers, so wholesale clearing punished the live document for documents that had already been torn down, and a steady frame then rebuilt every batch group it had just been using. Insertion order puts those dead entries first. Recorded command buffers keep their own references, so dropping the cache's handle mid-frame is safe either way.
|
| uint64_t | deviceId () const |
| | Process-unique identity for this device instance, assigned at construction from a monotonic counter (never reused, starts at 1).
|
| void | setCounters (GeodeCounters *counters) |
| | Install a GeodeCounters struct for this device.
|
|
GeodeCounters * | counters () const |
| | Non-owning pointer to the installed counters, or null.
|
|
void | countBuffer () const |
| | Record one buffer creation in lifetime and attached frame counters.
|
|
void | countBindGroup () const |
| | Record one bind-group creation in the attached frame counters.
|
|
void | countTexture () const |
| | Record one texture creation in lifetime and attached frame counters.
|
|
uint64_t | lifetimeTextureCreates () const |
| | Cumulative number of countTexture() calls since this GeodeDevice was created. Does not account for textures released back into a pool - it is an allocation-site counter, not a live-count.
|
|
void | countTextureRelease () const |
| | Record that this context's runtime device gave up its ownership of a texture allocation.
|
|
uint64_t | lifetimeTextureReleases () const |
| | Texture allocations whose ownership this context's runtime device has given up since the context was created (see gpu::DeviceObserver::onTextureReleased), on every backend. It excludes the snapshot-capture context, whose creations lifetimeTextureCreates() includes, so creates minus releases is not a live count.
|
|
uint64_t | lifetimeBufferCreates () const |
| | Cumulative number of countBuffer() calls since this GeodeDevice was created. Same caveat as lifetimeTextureCreates().
|
|
void | countSubmit () const |
| | Record one queue submission in the attached frame counters.
|
| void | countCommandBuffers (uint64_t count) const |
| | Record the command buffers one submission carried.
|
|
void | countPathEncode () const |
| | Record one path encoding in the attached frame counters.
|
| void | countDraws (uint64_t count) const |
| | Record the draws a submission counted (see gpu::DeviceObserver::onSubmitted).
|
|
void | countPipelineSwitch () const |
| | Record one pipeline switch in the attached frame counters.
|
|
void | countBufferWrite (uint64_t bytes) const |
| | Record one runtime buffer write of bytes payload bytes.
|
|
void | countTextureWrite (uint64_t bytes) const |
| | Record one runtime texture write of bytes payload bytes.
|
| uint64_t | beginFrameGeneration () |
| | Open a frame on this device and return its generation.
|
|
void | endFrameGeneration (uint64_t generation) |
| | Close a generation opened by beginFrameGeneration. Unknown values are ignored, so a renderer that never opened one (no-op mode) is safe.
|
|
uint64_t | oldestOpenFrameGeneration () const |
| | Oldest generation whose frame has not closed yet, or ~0 when no frame is open. Anything a generation at or after this touched may still be read by an unsubmitted draw.
|
| bool | frameStampClaimed (uint64_t stamp) const |
| | True when a resource stamped with stamp (a generation minted by beginFrameGeneration) may still be read by a frame that has not submitted: some open frame is at or before the stamp, so a recorded draw in that frame can reference the stamped bytes, and every queue write in a frame lands before every draw in its submit.
|
|
void | countGlyphResidencyHit () const |
| | Record one glyph occurrence served from an already-resident outline.
|
|
void | countGlyphResidencyUpload () const |
| | Record one unique glyph outline encoded and made resident.
|
|
void | countGlyphResidencyEvictions (uint64_t count) const |
| | Record count cached glyph outlines dropped to stay inside the budget.
|
|
const std::shared_ptr< std::atomic< int64_t > > & | residentBytesGauge () const |
| | Shared live-resident-bytes gauge for GPU residence. Co-owned with each GeodeResidentSlot's buffer so resident-memory accounting stays lifetime-safe even if a document (and its ECS registry) outlives this device. Lazily created on first access. GeoEncoder bumps it when a slot gains residence; the slot decrements it on reset / destruction (geometry change or document teardown), which is the eviction signal for "many distinct
documents".
|
|
int64_t | liveResidentBytesForTesting () const |
| | Current live resident-geometry bytes across every GeodeResidentSlot buffer created against this device. Zero at construction and after all resident documents are torn down; used by eviction tests.
|
|
bool | isVulkan () const |
| | True when the active native backend is Vulkan. GeodeFilterEngine uses this to force inter-pass serialization that eliminates a nondeterministic cross-submit storage-write -> sampled-read visibility race observed on Arc Vulkan. Metal returns false and keeps the fast multi-submit path.
|
|
gpu::Device & | runtimeDevice () const |
| | This context's GPU runtime device: the owner of its handle tables, submission serials, and resource retirement. Renderer services that need only the runtime contract take this instead of naming the concrete backend type.
|
|
const GeodeGpuContext & | gpuContext () const |
| | The recording context Geode's encoders record a frame against: this device's GPU runtime device, its shared bind-slot resources, and its counter sinks. Wired once with the shared pipelines and owned here, so it lives exactly as long as this device does.
|
| gpu::DeviceObserver & | runtimeCounterObserverForTesting () const |
| | The observer this context installs on its own runtime device, on every backend.
|
The shared bind-slot resources - 1x1 dummy pattern texture and view, 1x1 full-coverage clip-mask texture and view, their samplers, a one-element identity instance record, and a zero-filled gradient paint block - are reached through gpuContext.
RendererGeode once constructed these pipeline objects per renderer instance, exhausting the GPU memory budget in image-comparison runs (issue #575). Ownership here keeps one fixed set per GeodeDevice instead.
Every renderer that talks to this device shares the same pipeline objects; their state is intentionally immutable after construction (no per-draw mutation), so concurrent use from sibling renderers is safe as long as submissions are serialized by the selected runtime device.
|
|
GeodePipeline & | pipeline () const |
| | Slug solid-fill render pipeline.
|
|
GeodeGradientPipeline & | gradientPipeline () const |
| | Slug gradient-fill render pipeline.
|
|
GeodeImagePipeline & | imagePipeline () const |
| | Image-blit render pipeline (used by GeoEncoder::drawImage and the pattern / layer composition path).
|
|
GeodeMaskPipeline & | maskPipeline () const |
| | Clip-path mask render pipeline. Built lazily on first access rather than eagerly at device creation, matching the prior per-encoder lazy path - most documents don't use <clipPath> and the production WASM path avoids the cost.
|
|
GeodeFilterEngine & | filterEngine () const |
| | GPU filter-graph executor. Owns ~15 compute pipelines for SVG filter primitives.
|
|
GeodeCheckerboardPipeline & | checkerboardPipeline () const |
| | Framebuffer checkerboard underlay pipeline used by the editor's direct presentation path. Built lazily on first access - only the editor draws it, so headless/WASM consumers never pay the compile cost.
|
|
GeodeCheckerboardPipeline & | checkerboardUnderlayPipeline () const |
| | Destination-over variant of checkerboardPipeline, for targets that already hold composed premultiplied content and need the checkerboard placed underneath it. Built lazily and independently of the replace-blend pipeline, so a consumer only pays for the variant it actually draws.
|
Owns a logical Geode context over a selected GPU runtime device.
GeodeDevice is the entry point to the Geode rendering backend. In headless mode it selects the platform's GPU root (native Metal or Vulkan, or the browser GPU runtime in WebAssembly builds) and creates a device without window system integration.
A host that selects a presentation root creates its first context with CreateOverSelectedRoot, then creates sibling contexts with CreateOverPhysicalDeviceOwner.
Typical headless usage:
auto maybeDevice = GeodeDevice::CreateHeadless();
if (!maybeDevice) {
// No GPU available.
return;
}