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

IUniformExtension that appends animation-shader spatial uniforms after PhosphorShaders::BaseUniforms in the UBO. More...

#include <phosphor-animation/include/PhosphorAnimation/AnimationUniformExtension.h>

Inheritance diagram for PhosphorAnimation::AnimationUniformExtension:
[legend]

Public Member Functions

 AnimationUniformExtension ()
 
int extensionSize () const override
 Size in bytes of the extension region (must respect std140 alignment).
 
void write (char *buffer, int offset) const override
 Write extension data into buffer starting at offset.
 
bool isDirty () const override
 Whether the extension data has changed since the last write.
 
void clearDirty () override
 Mark as clean after a successful write.
 
bool requiresPhysicalResolution () const override
 Animation shaders pair iResolution with logical-pixel extension fields (iAnchorSize, iAnchorPosInFbo, iSurfaceScreenPos) for UV / clip-space ratios, and use the vertex-stage vTexCoord instead of gl_FragCoord — so the legacy DPR-scaling of iResolution would mismatch units across the UBO and shrink the rendered card by 1/DPR (fly-in) or shift the anchor UV remap by the same factor (broken-glass, morph).
 
void setISurfaceScreenPos (const QVector4D &pos)
 Surface origin in logical screen pixels (.xy) plus host screen dimensions (.zw).
 
void setIAnchorSize (const QSizeF &size)
 Anchor (card) pixel size in logical pixels.
 
void setIAnchorPosInFbo (const QPointF &pos)
 Anchor's top-left position inside the shader item's FBO, in logical pixels.
 
void setIAnchorRectInTexture (const QVector4D &rect)
 Card's UV sub-rect within uTexture0, as (x, y, width, height) in the captured texture's [0, 1] space.
 
- Public Member Functions inherited from PhosphorShaders::IUniformExtension
virtual ~IUniformExtension ()=default
 

Detailed Description

IUniformExtension that appends animation-shader spatial uniforms after PhosphorShaders::BaseUniforms in the UBO.

Carries the surface-on- screen rect (iSurfaceScreenPos), the captured card's pixel size (iAnchorSize), its top-left within the FBO (iAnchorPosInFbo), and its UV sub-rect within the captured texture (iAnchorRectInTexture) — read by vertex shaders that map the FBO quad onto the card and by fragment shaders that want card-space sampling and screen-relative noise / edge fades.

Why an extension and not a BaseUniforms member: the zone-shader path (ZoneShaderItem via ZoneUniformExtension) shares BaseUniforms with the animation path. An earlier revision grew BaseUniforms to 704 bytes to add these two fields directly; that change broke zone- shader rendering on multi-VS setups in a way the team couldn't reproduce in a controlled test (likely a transitively-included- common.glsl cache-key gap in shaderCacheKey, but unconfirmed). Keeping BaseUniforms at 672 bytes and routing animation-only fields through this extension isolates the two pipelines: zone shaders attach ZoneUniformExtension (4096 bytes after base) and never observe these fields at all; animation shaders attach AnimationUniformExtension (48 bytes after base) — iSurfaceScreenPos at offset 672, iAnchorSize at 688, iAnchorPosInFbo at 696, iAnchorRectInTexture at 704 — matching the trailing-field layout data/animations/shared/animation_uniforms.glsl's UBO branch declares.

Cross-runtime parity: the kwin-effect path uses classic GL setUniform lookups for these names (see paint_pipeline.cpp

  • shader_transitions.cpp) — independent of the UBO mechanism, works without any extension. Author-side GLSL is identical across runtimes (the #ifdef PLASMAZONES_KWIN branch of animation_uniforms.glsl declares them as default-block uniforms; the UBO branch declares them inside AnimationUniforms { ... }).

Ownership: created per-leg by SurfaceAnimator::attachShaderToAnchor and installed on the plain ShaderEffect it creates via ShaderEffect::setUniformExtension(shared_ptr). The shared_ptr stays alive in the animator's per-track storage, so consumer-side updates (syncShaderGeometryNow calls setISurfaceScreenPos / setIAnchorSize) reach the same instance the render thread reads.

Threading: write is called on the render thread during prepare(); setI* is called on the GUI thread from syncShaderGeometryNow. m_mutex serializes both — sync phase normally blocks the render thread but some Qt render loops can advance through prepare() before the next sync fires, so the lock is required to prevent torn copies.

Constructor & Destructor Documentation

◆ AnimationUniformExtension()

PhosphorAnimation::AnimationUniformExtension::AnimationUniformExtension ( )
inline

Member Function Documentation

◆ clearDirty()

void PhosphorAnimation::AnimationUniformExtension::clearDirty ( )
inlineoverridevirtual

Mark as clean after a successful write.

Implements PhosphorShaders::IUniformExtension.

◆ extensionSize()

int PhosphorAnimation::AnimationUniformExtension::extensionSize ( ) const
inlineoverridevirtual

Size in bytes of the extension region (must respect std140 alignment).

Must be stable for the lifetime of the extension instance: the render node sizes the UBO and its staging buffer once when the extension is installed (via setUniformExtension) and reuses both across frames. A changing size silently bypasses the resize path and risks UBO write overruns. To change the size, install a fresh IUniformExtension instance with the new size — that triggers UBO recreation.

Implements PhosphorShaders::IUniformExtension.

◆ isDirty()

bool PhosphorAnimation::AnimationUniformExtension::isDirty ( ) const
inlineoverridevirtual

Whether the extension data has changed since the last write.

Implements PhosphorShaders::IUniformExtension.

◆ requiresPhysicalResolution()

bool PhosphorAnimation::AnimationUniformExtension::requiresPhysicalResolution ( ) const
inlineoverridevirtual

Animation shaders pair iResolution with logical-pixel extension fields (iAnchorSize, iAnchorPosInFbo, iSurfaceScreenPos) for UV / clip-space ratios, and use the vertex-stage vTexCoord instead of gl_FragCoord — so the legacy DPR-scaling of iResolution would mismatch units across the UBO and shrink the rendered card by 1/DPR (fly-in) or shift the anchor UV remap by the same factor (broken-glass, morph).

Override to publish iResolution in logical pixels so every ratio in animation shaders is dimensionally consistent.

Reimplemented from PhosphorShaders::IUniformExtension.

◆ setIAnchorPosInFbo()

void PhosphorAnimation::AnimationUniformExtension::setIAnchorPosInFbo ( const QPointF &  pos)
inline

Anchor's top-left position inside the shader item's FBO, in logical pixels.

Combined with iAnchorSize and the FBO size — both in the same logical unit — shaders can compute the anchor's UV region inside the FBO:

vec2 anchorTopLeftUv = iAnchorPosInFbo / iResolution;
vec2 anchorSizeUv = iAnchorSize / iResolution;
vec2 anchorUv = (vTexCoord - anchorTopLeftUv) / anchorSizeUv;

This generalises the previous customParams[7].x-based ring- padding remap (morph, broken-glass) AND the surface-extent vertex remap (fly-in) onto a single math contract that works for any FBO size the runtime decides to allocate.

Values per FBO-extent mode:

  • Anchor extent, no padding: (0, 0). Anchor == FBO.
  • Anchor extent with ring (e.g. anchor+0.5): (padW, padH) where padW = anchor.width * pad, padH = anchor.height * pad.
  • Surface extent: anchor's position relative to the FBO's origin, which under the daemon's shaderItem-parented-to- anchor->parentItem() convention equals anchor->x() / anchor->y() (the shaderItem is at (0,0) in parent's coords for surface extent, so anchor's local-to-parent coords ARE anchor's local-to-FBO coords).

◆ setIAnchorRectInTexture()

void PhosphorAnimation::AnimationUniformExtension::setIAnchorRectInTexture ( const QVector4D &  rect)
inline

Card's UV sub-rect within uTexture0, as (x, y, width, height) in the captured texture's [0, 1] space.

The daemon renders the shader anchor into uTexture0; when the anchor is larger than the visible card — a PopupFrame capture item that bundles the glow margin so the glow animates with the card — this rect is the card's region within that texture. animation.vert divides texCoord by it so anchor-extent shaders see vTexCoord as [0, 1] over the card (the glow margin falls outside [0, 1]), and surfaceColor() multiplies by it so card-space samples address the card region of the texture. A bare card-sized anchor carries the (0, 0, 1, 1) identity, which makes both folds a passthrough. Pushed by syncShaderGeometryNow alongside iAnchorSize. Mirrors the kwin-effect's same-named uniform (frame's sub-rect within KWin's shadow-padded redirected FBO).

◆ setIAnchorSize()

void PhosphorAnimation::AnimationUniformExtension::setIAnchorSize ( const QSizeF &  size)
inline

Anchor (card) pixel size in logical pixels.

Decoupled from iResolution because Qt auto-resets iResolution to the shader item's bounds on any geometry event. For a fboExtentKind: Surface shader item that auto-reset would clobber any anchor- size override. Pushed alongside iSurfaceScreenPos from syncShaderGeometryNow. Logical-pixel units to keep magic- constant tuning that consumes this as a standalone pixel count stable across DPR settings (broken-glass's uSize, tv-glitch's row offsets). Shaders that need to compute ratios involving FBO size should pair this with iSurfaceScreenPos.zw (also logical), NOT with iResolution (physical).

◆ setISurfaceScreenPos()

void PhosphorAnimation::AnimationUniformExtension::setISurfaceScreenPos ( const QVector4D &  pos)
inline

Surface origin in logical screen pixels (.xy) plus host screen dimensions (.zw).

Pushed by SurfaceAnimator on every leg attach and on each anchor / window geometry signal. Logical- pixel units; iResolution lands in the UBO multiplied by DPR (shadereffect.cpp::syncCustomNode) so its units differ — shaders that need FBO size to be in the SAME unit as the extension fields should read it from .zw here (which mirrors the QQuickWindow's contentItem size and equals the wl_surface rect for screen-sized OSD / popup surfaces on the daemon path). Initial value (0,0,0,0) — vertex shaders that read .zw for screen size MUST guard against zero (max(.z, 1.0)) to avoid NaN before the first push lands.

◆ write()

void PhosphorAnimation::AnimationUniformExtension::write ( char *  buffer,
int  offset 
) const
inlineoverridevirtual

Write extension data into buffer starting at offset.

Called on the render thread during prepare().

Implements PhosphorShaders::IUniformExtension.


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