Renderer for a given node. More...
Detailed Description
Renderer for a given node.
Public Types | |
| using | PortSourceKey = std::pair< int32_t, const void * > |
| using | MergeCacheKey = std::pair< const ossia::scene_state *, int64_t > |
Public Member Functions | |
| NodeRenderer (const Node &node) | |
| virtual TextureRenderTarget | renderTargetForInput (const Port &input) |
| virtual BufferView | bufferForInput (const Port &input) |
| virtual BufferView | bufferForOutput (const Port &output) |
| virtual QRhiTexture * | textureForOutput (const Port &output) |
| virtual void | updateInputTexture (const Port &input, QRhiTexture *tex, QRhiTexture *depthTex=nullptr) |
| virtual void | updateInputSamplerFilter (const Port &input, const RenderTargetSpecs &spec) |
| virtual void | inputAboutToFinish (RenderList &renderer, const Port &p, QRhiResourceUpdateBatch *&) |
| virtual void | init (RenderList &renderer, QRhiResourceUpdateBatch &res)=0 |
| virtual void | update (RenderList &renderer, QRhiResourceUpdateBatch &res, Edge *edge)=0 |
| virtual void | runInitialPasses (RenderList &, QRhiCommandBuffer &commands, QRhiResourceUpdateBatch *&res, Edge &edge) |
| virtual void | runRenderPass (RenderList &, QRhiCommandBuffer &commands, Edge &edge) |
| virtual QRhiGraphicsPipeline::CompareOp | depthCompare () const noexcept |
| The depth compare this renderer's pipeline was built with. | |
| virtual void | release (RenderList &)=0 |
| void | checkForChanges () |
| void | syncRenderTargetIndex () |
| void | process (int32_t port, const ossia::geometry_spec &v) |
| void | process (int32_t port, const ossia::scene_spec &v) |
| virtual void | process (int32_t port, const ossia::transform3d &v) |
| void | process (int32_t port, const ossia::geometry_spec &v, const void *source_key) |
| void | process (int32_t port, const ossia::scene_spec &v, const void *source_key) |
| const ossia::geometry_spec * | findGeometryByPort (int32_t port) const |
| template<typename F > | |
| void | forEachSceneOnPort (int32_t port, F &&fn) const |
Incremental lifecycle API | |
These methods enable dynamic graph editing by splitting the init/release lifecycle into edge-independent state and per-edge passes. Renderers that override these are incrementally updateable: adding or removing an output edge only creates/destroys one pass, without touching the rest of the renderer's GPU resources. Default implementations are no-ops. | |
| virtual void | initState (RenderList &renderer, QRhiResourceUpdateBatch &res) |
| virtual void | releaseState (RenderList &renderer) |
| virtual void | addOutputPass (RenderList &renderer, Edge &edge, QRhiResourceUpdateBatch &res) |
| Create a pass for a new output edge (pipeline, SRB, processUBO). | |
| virtual void | removeOutputPass (RenderList &renderer, Edge &edge)=0 |
| virtual void | addInputEdge (RenderList &renderer, Edge &edge, QRhiResourceUpdateBatch &res) |
| virtual void | removeInputEdge (RenderList &renderer, Edge &edge) |
| Notify the renderer that an input edge was disconnected. | |
| virtual bool | hasOutputPassForEdge (Edge &edge) const |
| Check if this renderer already has an output pass for the given edge. | |
| virtual void | seedInitialOutputs (RenderList &renderer) |
Public Attributes | |
| const Node & | node |
| ossia::geometry_spec | geometry |
| The geometry to use. | |
| ossia::small_flat_map< PortSourceKey, ossia::geometry_spec, 4 > | m_portGeometries |
| ossia::scene_spec | scene |
| The scene to use (when receiving scene_spec data). | |
| ossia::small_flat_map< PortSourceKey, ossia::scene_spec, 4 > | m_portScenes |
| Per-(port, source) scene storage. See m_portGeometries comment. | |
| ossia::small_vector< MergeCacheKey, 4 > | m_mergeCacheInputs |
| ossia::scene_spec | m_mergeCacheOutput |
| ossia::small_flat_map< PortSourceKey, std::pair< ossia::geometry_spec, ossia::scene_spec >, 4 > | m_wrapCache |
| int32_t | nodeId {-1} |
| bool | materialChanged {false} |
| bool | geometryChanged {false} |
| bool | sceneChanged {false} |
| bool | renderTargetSpecsChanged {false} |
| bool | m_initialized {false} |
Member Typedef Documentation
◆ MergeCacheKey
| using score::gfx::NodeRenderer::MergeCacheKey = std::pair<const ossia::scene_state*, int64_t> |
Merge cache: the set of (scene_state pointer, version) pairs we last merged, and the resulting merged scene_spec. Keyed on BOTH pointer and version because halp-style producers (Camera, Environment, Light, …) keep a stable m_state shared_ptr and mutate its contents in place — keying on pointer alone would return a stale cached merge even after a slider moved. The version monotonically bumps on each producer update, so (ptr, version) changes whenever content changes.
◆ PortSourceKey
| using score::gfx::NodeRenderer::PortSourceKey = std::pair<int32_t, const void*> |
Per-(port, source) geometry storage. Multi-keyed so multiple upstream producers converging on the same sink port each get their own slot (additive merge rather than overwrite). The source_key is the upstream output Port pointer (opaque void*); nullptr is a valid single-slot key for legacy callers.
Member Function Documentation
◆ addInputEdge()
|
virtual |
Notify the renderer that a new input edge was connected. Typically updates sampler textures or geometry bindings.
Reimplemented in score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, and score::gfx::SimpleRenderedISFNode.
◆ addOutputPass()
|
virtual |
Create a pass for a new output edge (pipeline, SRB, processUBO).
Reimplemented in score::gfx::DirectVideoNodeRenderer, score::gfx::GenericNodeRenderer, score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, score::gfx::SimpleRenderedVSANode, score::gfx::SimpleRenderedISFNode, score::gfx::VideoNodeRenderer, score::gfx::DMACaptureInputNode::Renderer, and Gfx::WindowCapture::WindowCaptureNode::Renderer.
◆ depthCompare()
|
inlinevirtualnoexcept |
The depth compare this renderer's pipeline was built with.
Reimplemented in score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, and score::gfx::SimpleRenderedISFNode.
◆ findGeometryByPort()
|
inline |
Find the first geometry stored on the given sink port (across all sources). For single-producer-per-port consumers, which do not care which source produced it.
◆ forEachSceneOnPort()
|
inline |
Enumerate every scene_spec published on port (across all sources). Populated for ALL geometry/scene edges — raw geometry_spec deliveries are auto-wrapped into scene_specs and cached (see m_wrapCache), so the scene_state_ptr returned here is stable across frames when the input doesn't actually change. Callers doing scene-broadcast iterate this and check scene_state::dirty_index + state pointer for invalidation.
◆ hasOutputPassForEdge()
|
virtual |
Check if this renderer already has an output pass for the given edge.
Reimplemented in score::gfx::DirectVideoNodeRenderer, score::gfx::GenericNodeRenderer, score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, score::gfx::SimpleRenderedVSANode, score::gfx::SimpleRenderedISFNode, score::gfx::VideoNodeRenderer, score::gfx::DMACaptureInputNode::Renderer, and Gfx::WindowCapture::WindowCaptureNode::Renderer.
◆ initState()
|
virtual |
Initialize edge-independent state: material UBO, samplers, mesh, shaders. Called once when the renderer enters a RenderList.
Reimplemented in score::gfx::DirectVideoNodeRenderer, score::gfx::GeometryFilterNodeRenderer, score::gfx::GenericNodeRenderer, score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, score::gfx::SimpleRenderedVSANode, score::gfx::RenderedScenePreprocessorNode, score::gfx::SimpleRenderedISFNode, score::gfx::TexgenNode::Rendered, score::gfx::VideoNodeRenderer, and Gfx::WindowCapture::WindowCaptureNode::Renderer.
◆ inputAboutToFinish()
|
virtual |
Called when all the inbound nodes to a texture input have finished rendering. Mainly useful to slip in a readback.
◆ process()
| void score::gfx::NodeRenderer::process | ( | int32_t | port, |
| const ossia::geometry_spec & | v, | ||
| const void * | source_key | ||
| ) |
Source-aware overloads. source_key is an opaque identity of the upstream output port that produced this data (typically edge.source). Multiple producers converging on the same sink port each get their own storage slot, so their scenes accumulate additively instead of overwriting each other. Callers that don't care pass nullptr — all such callers then share a single per-port slot.
◆ releaseState()
|
virtual |
Release edge-independent state. Called once when the renderer leaves a RenderList.
Reimplemented in score::gfx::GeometryFilterNodeRenderer, score::gfx::SimpleRenderedISFNode, score::gfx::TexgenNode::Rendered, score::gfx::DirectVideoNodeRenderer, score::gfx::GenericNodeRenderer, score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, score::gfx::SimpleRenderedVSANode, score::gfx::RenderedScenePreprocessorNode, score::gfx::VideoNodeRenderer, and Gfx::WindowCapture::WindowCaptureNode::Renderer.
◆ removeInputEdge()
|
virtual |
Notify the renderer that an input edge was disconnected.
Reimplemented in score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, and score::gfx::SimpleRenderedISFNode.
◆ removeOutputPass()
|
pure virtual |
Remove the pass for a removed output edge. Pure-virtual: every concrete renderer must explicitly handle edge removal. Sinks (OutputNodeRenderer) and data-only renderers that store no per-edge GPU state can override with an empty body.
Implemented in score::gfx::RenderedFlattenedSceneFilterNode, score::gfx::GeometryFilterNodeRenderer, score::gfx::RenderedMergeGeometriesNode, score::gfx::OutputNodeRenderer, score::gfx::RenderedSceneFilterNode, score::gfx::RenderedScenePreprocessorNode, score::gfx::DirectVideoNodeRenderer, score::gfx::GenericNodeRenderer, score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, score::gfx::SimpleRenderedVSANode, score::gfx::SimpleRenderedISFNode, score::gfx::VideoNodeRenderer, score::gfx::DMACaptureInputNode::Renderer, and Gfx::WindowCapture::WindowCaptureNode::Renderer.
◆ seedInitialOutputs()
|
virtual |
Seed downstream consumers once at init-time with this renderer's current outputs. Default no-op. Halp scene/geometry producers (Camera, EnvironmentLoader, Light, …) override this to run their operator()() once during reconciliation and immediately push the result into each downstream sink's per-port scene cache. Otherwise a live-inserted producer's output only reaches m_portScenes when the next render frame's upstream scan fires its runInitialPasses, which can arrive after the sink's own frame-start cache snapshot.
◆ syncRenderTargetIndex()
|
inline |
Sync only the render target spec index without touching materialChanged. Used after initState() so the first render's checkForChanges() sees a material mismatch (triggering initial upload) but not a spurious rt_changed.
◆ textureForOutput()
|
virtual |
Returns a texture owned by this renderer for a given output port. Used for GrabsFromSource ports (e.g. cubemaps) where the upstream node produces a texture directly rather than rendering into a downstream-provided render target.
Reimplemented in score::gfx::RenderedScenePreprocessorNode, score::gfx::RenderedCSFNode, score::gfx::RenderedRawRasterPipelineNode, and score::gfx::SimpleRenderedISFNode.
◆ updateInputSamplerFilter()
|
virtual |
Updates the sampler filter/address settings for an input port. Called when the render target spec changes (e.g. linear → nearest).
Reimplemented in score::gfx::RenderedISFNode, and score::gfx::SimpleRenderedISFNode.
◆ updateInputTexture()
|
virtual |
Updates the sampler texture for an input port. Called when the upstream texture may have changed (edge add, RT recreation). If the port has SamplableDepth and depthTex is non-null, the depth sampler (immediately after the color sampler) is also updated.
Reimplemented in score::gfx::GenericNodeRenderer, score::gfx::RenderedCSFNode, score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, score::gfx::SimpleRenderedVSANode, and score::gfx::SimpleRenderedISFNode.
Member Data Documentation
◆ geometry
| ossia::geometry_spec score::gfx::NodeRenderer::geometry |
The geometry to use.
If not set, then a relevant default geometry for the node will be used, e.g. a full-screen quad or triangle.
For backward compatibility with single-port nodes (GenericNodeRenderer, RenderedRawRasterPipelineNode, etc.), this holds the last received geometry. Multi-geometry-port nodes (CSF) should use m_portGeometries instead.
◆ m_initialized
| bool score::gfx::NodeRenderer::m_initialized {false} |
Guard for idempotent release — prevents double-release of GPU resources. Set to true at end of init(), cleared at start of release().
◆ m_wrapCache
| ossia::small_flat_map< PortSourceKey, std::pair<ossia::geometry_spec, ossia::scene_spec>, 4> score::gfx::NodeRenderer::m_wrapCache |
Cache the wrap_geometry_as_scene result per geometry_spec so a geometry source re-pushing the same geometry_spec every frame produces a stable wrapped-scene shared_ptr (otherwise every frame produces a new wrapper → merge cache miss → full re-upload).
◆ scene
| ossia::scene_spec score::gfx::NodeRenderer::scene |
The scene to use (when receiving scene_spec data).
When a geometry_spec is received, it is auto-wrapped into a scene_spec so that downstream scene-aware renderers can always work with scenes. Renderers that only handle geometry read the geometry field instead.
The documentation for this class was generated from the following files:
- NodeRenderer.hpp
- NodeRenderer.cpp