Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
PhosphorRendering::ShaderNodeRhi Class Reference

QSGRenderNode for fullscreen-quad shader rendering via Qt RHI (Vulkan / OpenGL) More...

#include <phosphor-rendering/include/PhosphorRendering/ShaderNodeRhi.h>

Inheritance diagram for PhosphorRendering::ShaderNodeRhi:
[legend]

Public Member Functions

 ShaderNodeRhi (QQuickItem *item)
 
 ~ShaderNodeRhi () override
 
void invalidateItem ()
 Notify the render node that its owning item is being destroyed.
 
QSGRenderNode::StateFlags changedStates () const override
 
QSGRenderNode::RenderingFlags flags () const override
 
QRectF rect () const override
 
void prepare () override
 
void render (const RenderState *state) override
 
void releaseResources () override
 
void setUniformExtension (std::shared_ptr< PhosphorShaders::IUniformExtension > extension)
 
std::shared_ptr< PhosphorShaders::IUniformExtensionuniformExtension () const
 Access the currently-installed uniform extension (may be nullptr).
 
void setTime (double time)
 
void setTimeDelta (float delta)
 
void setFrame (int frame)
 
void setResolution (float width, float height)
 
void setMousePosition (const QPointF &pos)
 
void setIsReversed (bool reverse)
 Direction signal for asymmetric leg rendering.
 
void setCustomParams (int index, const QVector4D &params)
 
void setCustomColor (int index, const QColor &color)
 
void setAppField0 (int value)
 Write the consumer's two int slots inside BaseUniforms (offsets 88, 92).
 
void setAppField1 (int value)
 
bool setExtraBinding (int binding, QRhiTexture *texture, QRhiSampler *sampler)
 Bind a consumer-owned texture/sampler at the given binding number.
 
bool removeExtraBinding (int binding)
 
void setAudioSpectrum (const QVector< float > &spectrum)
 
void setUserTexture (int slot, const QImage &image)
 
void setUserTextureWrap (int slot, const QString &wrap)
 Set per-slot sampler address mode.
 
void setWallpaperTexture (const QImage &image)
 
void setUseWallpaper (bool use)
 
void setUseDepthBuffer (bool use)
 
void setSourceTextureProvider (QSGTextureProvider *provider)
 Live texture-provider override for user-texture slot 0 (SRB binding 7 / uTexture0).
 
QSGTextureProvider * sourceTextureProvider () const
 
void setBufferShaderPath (const QString &path)
 
void setBufferShaderPaths (const QStringList &paths)
 
void setBufferFeedback (bool enable)
 
void setBufferScale (qreal scale)
 
void setBufferWrap (const QString &wrap)
 
void setBufferWraps (const QStringList &wraps)
 
void setBufferFilter (const QString &filter)
 
void setBufferFilters (const QStringList &filters)
 
bool loadVertexShader (const QString &path)
 
bool loadFragmentShader (const QString &path)
 
void setVertexShaderSource (const QString &source)
 
void setFragmentShaderSource (const QString &source)
 
bool isShaderReady () const
 
QString shaderError () const
 
void invalidateShader ()
 
void invalidateUniforms ()
 
void setShaderIncludePaths (const QStringList &paths)
 

Static Public Member Functions

static QString normalizeWrapMode (const QString &wrap)
 Normalize wrap mode string to "clamp", "repeat", or "mirror" (static helper, safe to call from any thread — operates on its arguments only).
 
static QString normalizeFilterMode (const QString &filter)
 Normalize filter mode string to "nearest", "linear", or "mipmap".
 
static QRhiSampler::AddressMode wrapModeToRhiAddress (const QString &wrap)
 Map a normalized wrap-mode string to QRhiSampler::AddressMode.
 

Protected Member Functions

QRhi * safeRhi () const
 Thread-safe QRhi accessor.
 

Detailed Description

QSGRenderNode for fullscreen-quad shader rendering via Qt RHI (Vulkan / OpenGL)

Generalized render node extracted from PlasmaZones' ZoneShaderNodeRhi. Manages a Shadertoy-compatible UBO (BaseUniforms), multipass buffer system, texture bindings (audio, user, wallpaper, depth), and shader baking.

Application-specific UBO data is appended via IUniformExtension. Application-specific texture bindings use setExtraBinding() / removeExtraBinding().

Uses QRhi and QShaderBaker (runtime SPIR-V + GLSL 330 bake). Requires Qt 6.6+ (commandBuffer(), renderTarget()).

Threading contract
Setters on this class (ShaderNodeRhi — setTime, setResolution, setCustomParams, setExtraBinding, etc.) must be called from QQuickItem::updatePaintNode() during the scene graph sync phase — the GUI thread is blocked and the render thread is idle at that point. Calling these setters outside updatePaintNode() is a data race with prepare()/render() on the render thread. Only invalidateItem() is safe to call from the GUI thread outside the sync phase (it is the only flag exposed as std::atomic).

(Setters on the sibling ShaderEffect class are a different story — those run on the GUI thread and stage their changes into ShaderEffect's own members, to be pushed down to this node during the next sync phase.)

Extra binding lifetime (CRITICAL)
The consumer-owned QRhiTexture/QRhiSampler pointers passed to setExtraBinding() are stored as raw pointers and re-bound on every prepare() until removeExtraBinding() is called. If the consumer drops the texture/sampler (e.g. by calling unique_ptr::reset() or letting it fall out of scope) without first calling removeExtraBinding(), the next prepare() will dereference a dangling pointer — undefined behaviour, typically a crash inside the RHI backend. ALWAYS call removeExtraBinding(binding) before destroying the underlying QRhiTexture/QRhiSampler. No automatic lifetime tracking exists — callers are solely responsible for the remove-before-destroy contract.

Constructor & Destructor Documentation

◆ ShaderNodeRhi()

PhosphorRendering::ShaderNodeRhi::ShaderNodeRhi ( QQuickItem *  item)
explicit

◆ ~ShaderNodeRhi()

PhosphorRendering::ShaderNodeRhi::~ShaderNodeRhi ( )
override

Member Function Documentation

◆ changedStates()

QSGRenderNode::StateFlags PhosphorRendering::ShaderNodeRhi::changedStates ( ) const
override

◆ flags()

QSGRenderNode::RenderingFlags PhosphorRendering::ShaderNodeRhi::flags ( ) const
override

◆ invalidateItem()

void PhosphorRendering::ShaderNodeRhi::invalidateItem ( )

Notify the render node that its owning item is being destroyed.

Called from the owning QQuickItem destructor on the GUI thread. After this call, the render node will no longer dereference m_item. Thread-safe: uses an atomic flag checked by prepare()/render().

◆ invalidateShader()

void PhosphorRendering::ShaderNodeRhi::invalidateShader ( )

◆ invalidateUniforms()

void PhosphorRendering::ShaderNodeRhi::invalidateUniforms ( )

◆ isShaderReady()

bool PhosphorRendering::ShaderNodeRhi::isShaderReady ( ) const

◆ loadFragmentShader()

bool PhosphorRendering::ShaderNodeRhi::loadFragmentShader ( const QString &  path)

◆ loadVertexShader()

bool PhosphorRendering::ShaderNodeRhi::loadVertexShader ( const QString &  path)

◆ normalizeFilterMode()

static QString PhosphorRendering::ShaderNodeRhi::normalizeFilterMode ( const QString &  filter)
static

Normalize filter mode string to "nearest", "linear", or "mipmap".

◆ normalizeWrapMode()

static QString PhosphorRendering::ShaderNodeRhi::normalizeWrapMode ( const QString &  wrap)
static

Normalize wrap mode string to "clamp", "repeat", or "mirror" (static helper, safe to call from any thread — operates on its arguments only).

Unknown / empty inputs fall back to "clamp" — that fallback is load-bearing for legacy callers that pass an empty string when no wrap is configured.

◆ prepare()

void PhosphorRendering::ShaderNodeRhi::prepare ( )
override

◆ rect()

QRectF PhosphorRendering::ShaderNodeRhi::rect ( ) const
override

◆ releaseResources()

void PhosphorRendering::ShaderNodeRhi::releaseResources ( )
override

◆ removeExtraBinding()

bool PhosphorRendering::ShaderNodeRhi::removeExtraBinding ( int  binding)
Returns
true if a binding existed at that slot and was removed.

◆ render()

void PhosphorRendering::ShaderNodeRhi::render ( const RenderState *  state)
override

◆ safeRhi()

QRhi * PhosphorRendering::ShaderNodeRhi::safeRhi ( ) const
protected

Thread-safe QRhi accessor.

Returns
The active QRhi for the owning window, or nullptr when the item has been invalidated or has no window. Subclasses that override prepare() should route through this helper rather than commandBuffer()->rhi() so the post-invalidateItem() guard stays uniform.

◆ setAppField0()

void PhosphorRendering::ShaderNodeRhi::setAppField0 ( int  value)

Write the consumer's two int slots inside BaseUniforms (offsets 88, 92).

See PhosphorShaders::BaseUniforms for the full escape-hatch rationale. Updating these fields is cheap: the library uploads only the 8-byte K_APP_FIELDS region rather than the full scene header.

◆ setAppField1()

void PhosphorRendering::ShaderNodeRhi::setAppField1 ( int  value)

◆ setAudioSpectrum()

void PhosphorRendering::ShaderNodeRhi::setAudioSpectrum ( const QVector< float > &  spectrum)

◆ setBufferFeedback()

void PhosphorRendering::ShaderNodeRhi::setBufferFeedback ( bool  enable)

◆ setBufferFilter()

void PhosphorRendering::ShaderNodeRhi::setBufferFilter ( const QString &  filter)

◆ setBufferFilters()

void PhosphorRendering::ShaderNodeRhi::setBufferFilters ( const QStringList &  filters)

◆ setBufferScale()

void PhosphorRendering::ShaderNodeRhi::setBufferScale ( qreal  scale)

◆ setBufferShaderPath()

void PhosphorRendering::ShaderNodeRhi::setBufferShaderPath ( const QString &  path)

◆ setBufferShaderPaths()

void PhosphorRendering::ShaderNodeRhi::setBufferShaderPaths ( const QStringList &  paths)

◆ setBufferWrap()

void PhosphorRendering::ShaderNodeRhi::setBufferWrap ( const QString &  wrap)

◆ setBufferWraps()

void PhosphorRendering::ShaderNodeRhi::setBufferWraps ( const QStringList &  wraps)

◆ setCustomColor()

void PhosphorRendering::ShaderNodeRhi::setCustomColor ( int  index,
const QColor &  color 
)

◆ setCustomParams()

void PhosphorRendering::ShaderNodeRhi::setCustomParams ( int  index,
const QVector4D &  params 
)

◆ setExtraBinding()

bool PhosphorRendering::ShaderNodeRhi::setExtraBinding ( int  binding,
QRhiTexture *  texture,
QRhiSampler *  sampler 
)

Bind a consumer-owned texture/sampler at the given binding number.

Warning
The texture and sampler are stored as raw pointers and reused across frames. The consumer MUST call removeExtraBinding(binding) before destroying the underlying QRhiTexture/QRhiSampler — failing to do so leaves a dangling pointer that will be dereferenced inside the RHI on the next prepare() (UB, typically a crash).
Returns
true on success; false if binding collides with a library- managed slot (0, 2-12) or falls outside the supported range. A true return for an identical (binding, texture, sampler) triple is a no-op — the SRB/pipeline is NOT rebuilt when nothing actually changed.

◆ setFragmentShaderSource()

void PhosphorRendering::ShaderNodeRhi::setFragmentShaderSource ( const QString &  source)

◆ setFrame()

void PhosphorRendering::ShaderNodeRhi::setFrame ( int  frame)

◆ setIsReversed()

void PhosphorRendering::ShaderNodeRhi::setIsReversed ( bool  reverse)

Direction signal for asymmetric leg rendering.

Forward through to BaseUniforms::iIsReversed at offset 660. SurfaceAnimator pushes this from the leg's isShowLeg flag (false = reverse = hide leg); kwin-effect parity is handled directly via setUniform on the kwin path.

◆ setMousePosition()

void PhosphorRendering::ShaderNodeRhi::setMousePosition ( const QPointF &  pos)

◆ setResolution()

void PhosphorRendering::ShaderNodeRhi::setResolution ( float  width,
float  height 
)

◆ setShaderIncludePaths()

void PhosphorRendering::ShaderNodeRhi::setShaderIncludePaths ( const QStringList &  paths)

◆ setSourceTextureProvider()

void PhosphorRendering::ShaderNodeRhi::setSourceTextureProvider ( QSGTextureProvider *  provider)

Live texture-provider override for user-texture slot 0 (SRB binding 7 / uTexture0).

When set, every SRB rebuild reads provider->texture()->rhiTexture() and binds that — superseding whatever QImage was uploaded via setUserTexture(0, ...). The provider must outlive the node OR be cleared with nullptr before destruction; we hold a QPointer so a torn-down provider nulls out cleanly. Designed for QQuickItem::textureProvider() returns from layer-enabled items, where the underlying QSGTexture identity changes when the FBO is recreated (resize, device-loss); the SRB-rebuild detection in prepare() notices that change and refreshes the binding without the consumer having to re-call this setter every frame.

◆ setTime()

void PhosphorRendering::ShaderNodeRhi::setTime ( double  time)

◆ setTimeDelta()

void PhosphorRendering::ShaderNodeRhi::setTimeDelta ( float  delta)

◆ setUniformExtension()

void PhosphorRendering::ShaderNodeRhi::setUniformExtension ( std::shared_ptr< PhosphorShaders::IUniformExtension extension)

◆ setUseDepthBuffer()

void PhosphorRendering::ShaderNodeRhi::setUseDepthBuffer ( bool  use)

◆ setUserTexture()

void PhosphorRendering::ShaderNodeRhi::setUserTexture ( int  slot,
const QImage &  image 
)

◆ setUserTextureWrap()

void PhosphorRendering::ShaderNodeRhi::setUserTextureWrap ( int  slot,
const QString &  wrap 
)

Set per-slot sampler address mode.

Accepts "clamp", "repeat", or "mirror" (case-sensitive); other values fall back to "clamp" via normalizeWrapMode.

◆ setUseWallpaper()

void PhosphorRendering::ShaderNodeRhi::setUseWallpaper ( bool  use)

◆ setVertexShaderSource()

void PhosphorRendering::ShaderNodeRhi::setVertexShaderSource ( const QString &  source)

◆ setWallpaperTexture()

void PhosphorRendering::ShaderNodeRhi::setWallpaperTexture ( const QImage &  image)

◆ shaderError()

QString PhosphorRendering::ShaderNodeRhi::shaderError ( ) const

◆ sourceTextureProvider()

QSGTextureProvider * PhosphorRendering::ShaderNodeRhi::sourceTextureProvider ( ) const
inline

◆ uniformExtension()

std::shared_ptr< PhosphorShaders::IUniformExtension > PhosphorRendering::ShaderNodeRhi::uniformExtension ( ) const
inline

Access the currently-installed uniform extension (may be nullptr).

◆ wrapModeToRhiAddress()

static QRhiSampler::AddressMode PhosphorRendering::ShaderNodeRhi::wrapModeToRhiAddress ( const QString &  wrap)
static

Map a normalized wrap-mode string to QRhiSampler::AddressMode.

Single source of truth for sampler address-mode selection so callers can't drift on the "mirror" / "repeat" / "clamp" mapping.


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