Resources
Purpose
Resources converts owned CPU descriptions into backend images, geometry, programs, pipelines and materials. Retained handles let assets and completed frames share immutable generations while the backend controls native retirement. A native resource domain is the live backend/context lifetime that owns those resources. A handle from that domain does not become usable in an unrelated context merely because both contexts use the same graphics API.
Interface
Types below are in CE::Rendering unless another namespace is shown.
Types and operations
API and purpose |
|---|
|
|
|
|
|
|
Sampling and shader choices
Type |
Choices and details |
|---|---|
Independent minification/magnification with |
|
Mipmap |
|
|
|
Indexed recipes support |
Usage
Most applications receive retained resources through asset, text or UI loading. Call the provider directly when creating content outside those loaders. Both routes create immutable handles in the same selected graphics domain.
---
config:
theme: base
themeVariables:
fontFamily: system-ui, sans-serif
fontSize: 14px
flowchart:
htmlLabels: true
curve: linear
nodeSpacing: 22
rankSpacing: 38
padding: 12
---
flowchart TB
accTitle: Resources · application uploads and retained draws
accDescr: Local names omit Rendering::Resources::; ambiguous nested namespaces remain qualified. Arrows point toward the API or type used, not call order or data flow. Methods beneath type names are selected application entry points; Implement hooks marks engine-invoked overrides. Dashed arrows mark optional choices.
k0(["Application<br/>loading work"]):::app
k1("Assets::Images::decode(file): Assets::Images::Decoded"):::neighbor
k2["Assets::Images::<br/>Decoded"]:::focal
k3(["Application<br/>init_platform()"]):::app
k4["<b>Runtime::<br/>Context</b><br/><br/>resources(): Provider"]:::neighbor
k5["<b>Provider</b><br/><br/>create_image(Assets::Images::Decoded): Image<br/><br/>upload_geometry(<br/>Rendering::Geometry::Vertex2D[],<br/>Rendering::Geometry::Topology):<br/>Rendering::Geometry::Buffer2D<br/><br/>graphics_domain(): Rendering::GraphicsDomain"]:::focal
k6(["Application<br/>platform-owner work"]):::app
k7["Image"]:::focal
k8["Rendering::Geometry::<br/>Buffer2D"]:::focal
k9["Material"]:::focal
k10["Pipeline"]:::focal
k11(["Application<br/>prepare_render_frame()"]):::app
k12["Rendering::<br/>DrawPacket2D"]:::neighbor
k13(["Application<br/>report"]):::app
k14["<b>Rendering::<br/>GraphicsDomain</b><br/><br/>snapshot(): Rendering::GraphicsDomainSnapshot"]:::focal
k0 --> k1
k1 --> k2
k3 --> k4
k4 --> k5
k6 --> k5
k5 --> k2
k5 --> k7
k5 --> k8
k9 --> k10
k11 --> k12
k12 --> k9
k12 --> k8
k13 --> k14
k5 --> k14
classDef focal fill:#e7f3ef,stroke:#387d6b,color:#153d33,stroke-width:1.2px
classDef neighbor fill:#f0f3f8,stroke:#8c9bb1,color:#35445b,stroke-width:1px
classDef app fill:#fff2df,stroke:#c09452,color:#674515,stroke-dasharray:5 3
classDef system fill:#eaf0fc,stroke:#617fab,color:#263f69,stroke-width:1.2px
linkStyle default stroke:#7e8fa7,stroke-width:1.2px
Local names omit Rendering::Resources:: where unambiguous. Explore this diagram and its other views →
The engine dependency map follows materials, pipelines and native handles behind these application entry points.
Creation, publication and retirement
Operation |
Ownership after the operation |
Consequence |
|---|---|---|
Decode CPU input |
|
CPU preparation can precede graphics initialization. |
Create/upload through |
A fresh image or geometry handle owns the uploaded generation. |
The call copies its transient input. Direct creation does not insert an asset-cache entry. |
Publish into a cache, material, scene or frame |
Each published owner retains its selected generation. |
Replacing a cache entry does not rebind older materials or frames. |
Release owners and collect |
The last logical release allows native retirement; backend maintenance collects on graphics. |
Clearing a cache is insufficient while another owner still retains that generation. Backend shutdown closes native use even if logical handles remain. |
If an object stays resident, check application handles, caches, material/scene owners and published frames before investigating the native collector. The residency guide gives the complete owner chain and shutdown contract.
Uses
Consumer |
Dependency |
Integration boundary |
|---|---|---|
|
CPU inputs are borrowed only through the upload call. The colored-vertex and sampler operations are optional capabilities and reject when unsupported. |
|
Shader/material loading |
A provider may supply this optional borrowed adapter; selected recipes require that capability. Shader definitions. |
|
Provider/renderer domain observation |
Domain availability describes native lifetime; native use still requires the original live graphics context and its owner. OpenGL ownership. |
|
Catalogue/domain observation |
Weak event routes and copied identities describe changes without retaining the backend. A domain token owns observation state, not native resources. |
Used by
Consumer |
Resource operation or retained value |
Responsibility |
|---|---|---|
Creates images, cell geometry and shader/material generations. |
Publish entries on the active loading owner; preserve partial-publication semantics. |
|
Create glyph/UI images, geometry and materials. |
Publish a complete replacement generation or scene while earlier ones remain retained. |
|
Rendering materials and |
Retain pipeline, geometry and image/sampler bindings. |
Use those generations only in their original live graphics domain. |
Runtime |
Own the provider adapter and coordinate renderer maintenance. |
Settle accepted work and recycle frames before backend closure. |
Contracts
Uploads copy transient pixels/vertices before returning. Uploaded contents are immutable: changed content requires another handle and explicit publication. Provider ownership and current-context checks apply even when the C++ handle is shared. A shared logical handle does not extend a closed native domain’s usability.
Managers support one active provider/loading-owner domain. Publication can be incremental and resource retirement is deferred; neither a cache lookup nor a handle destructor promises immediate allocation/deletion on the current thread.
Lifecycle
Initialize rendering before uploading. Keep provider/context dependencies alive through pending requests, simulation completion and frame recycling. Drop game handles while the backend is still live. Native shutdown collects tracked resources and closes the domain; surviving logical handles remain safe for destruction/CPU inspection but cannot draw through it. Partial-failure cleanup must close remaining native state without masking the original failure.
Execution
CPU decoding/preparation can run away from graphics. Creation/upload and native collection obey the selected backend’s graphics-owner/current-context rules. The OpenGL implementation queues retirement from final release and collects it on graphics; final shared-pointer release alone performs no GL operation.
Integration
On the platform owner after graphics initialization:
auto pixels = CE::Assets::Images::decode(image_path);
auto image = engine_.resources().create_image(pixels);
Both values own their contents. You may release/reuse pixels after the upload;
retain image through the material or frame that needs it. For costly decode,
prepare on a worker and send the owned result through platform dispatch instead.
Limits and further reading
The portable provider does not promise generic in-place mutation, atomic asset batches or residency budgets. Read the complete cache/publication/retirement contract, CPU lifetime guide, provider interface and OpenGL owner guide.