Loading...
Searching...
No Matches
score::gfx::NodeRenderer Class Referenceabstract

Renderer for a given node. More...

Inheritance diagram for score::gfx::NodeRenderer:
Gfx::Spout::SpoutInputNode::Renderer Gfx::WindowCapture::WindowCaptureNode::Renderer score::gfx::DMACaptureInputNode::Renderer score::gfx::DirectVideoNodeRenderer score::gfx::GenericNodeRenderer score::gfx::GeometryFilterNodeRenderer score::gfx::OutputNodeRenderer score::gfx::RenderedCSFNode score::gfx::RenderedFlattenedSceneFilterNode score::gfx::RenderedISFNode score::gfx::RenderedMergeGeometriesNode score::gfx::RenderedRawRasterPipelineNode score::gfx::RenderedSceneFilterNode score::gfx::RenderedScenePreprocessorNode score::gfx::SimpleRenderedISFNode score::gfx::SimpleRenderedVSANode score::gfx::VideoNodeRenderer

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()

void score::gfx::NodeRenderer::addInputEdge ( RenderList &  renderer,
Edge &  edge,
QRhiResourceUpdateBatch &  res 
)
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()

◆ depthCompare()

virtual QRhiGraphicsPipeline::CompareOp score::gfx::NodeRenderer::depthCompare ( ) const
inlinevirtualnoexcept

The depth compare this renderer's pipeline was built with.

Reimplemented in score::gfx::RenderedISFNode, score::gfx::RenderedRawRasterPipelineNode, and score::gfx::SimpleRenderedISFNode.

◆ findGeometryByPort()

const ossia::geometry_spec * score::gfx::NodeRenderer::findGeometryByPort ( int32_t  port) const
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()

template<typename F >
void score::gfx::NodeRenderer::forEachSceneOnPort ( int32_t  port,
F &&  fn 
) const
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()

◆ initState()

◆ inputAboutToFinish()

void score::gfx::NodeRenderer::inputAboutToFinish ( RenderList &  renderer,
const Port &  p,
QRhiResourceUpdateBatch *&   
)
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()

◆ removeInputEdge()

void score::gfx::NodeRenderer::removeInputEdge ( RenderList &  renderer,
Edge &  edge 
)
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()

◆ seedInitialOutputs()

void score::gfx::NodeRenderer::seedInitialOutputs ( RenderList &  renderer)
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()

void score::gfx::NodeRenderer::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()

QRhiTexture * score::gfx::NodeRenderer::textureForOutput ( const Port &  output)
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()

void score::gfx::NodeRenderer::updateInputSamplerFilter ( const Port &  input,
const RenderTargetSpecs &  spec 
)
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()

void score::gfx::NodeRenderer::updateInputTexture ( const Port &  input,
QRhiTexture *  tex,
QRhiTexture *  depthTex = nullptr 
)
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: