IUniformExtension that appends animation-shader spatial uniforms after PhosphorShaders::BaseUniforms in the UBO.
More...
#include <phosphor-animation/include/PhosphorAnimation/AnimationUniformExtension.h>
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 |
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 directly to add the first of these per-leg fields; 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 (kZoneExtensionBytes 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_shader_window.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. The lost-dirty race (a setter landing between the render thread's copy and its dirty-clear) is defended on the consumer side: uploadExtensionToUbo clears the flag BEFORE copying, so such a setter re-arms it and the value uploads next frame.
|
inline |
|
inlineoverridevirtual |
Mark as clean after a successful write.
Implements PhosphorShaders::IUniformExtension.
|
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.
|
inlineoverridevirtual |
Whether the extension data has changed since the last write.
Implements PhosphorShaders::IUniformExtension.
|
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.
|
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:
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->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).
|
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).
|
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). Ratios against iSurfaceScreenPos.zw or against iResolution are both unit-consistent here — the animation path publishes iResolution in logical pixels too (see requiresPhysicalResolution() above).
|
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 — the same unit iResolution carries on this path, because this extension's requiresPhysicalResolution() returns false and shadereffect.cpp::effectiveResolutionScale therefore skips the DPR multiply. .zw mirrors the QQuickWindow's contentItem size and equals the wl_surface rect for screen-sized OSD / popup surfaces on the daemon path, so it is an equivalent screen-size source when a shader wants it independent of the FBO bounds. 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.
|
inlineoverridevirtual |
Write extension data into buffer starting at offset.
Called on the render thread during prepare().
Implements PhosphorShaders::IUniformExtension.