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

Registry of available animation shader transition effects. More...

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

Inheritance diagram for PhosphorAnimationShaders::AnimationShaderRegistry:
[legend]

Classes

class  AnimationPack
 Registry entry: a discovered animation effect as a PhosphorRegistry factory. More...
 

Signals

void effectsChanged ()
 

Public Member Functions

 AnimationShaderRegistry (QObject *parent=nullptr)
 
 ~AnimationShaderRegistry () override
 
void addSearchPath (const QString &path, PhosphorFsLoader::LiveReload liveReload=PhosphorFsLoader::LiveReload::On)
 
void addSearchPaths (const QStringList &paths, PhosphorFsLoader::LiveReload liveReload=PhosphorFsLoader::LiveReload::On, PhosphorFsLoader::RegistrationOrder order=PhosphorFsLoader::RegistrationOrder::LowestPriorityFirst)
 
QStringList searchPaths () const
 
void setUserPath (const QString &path)
 
void refresh ()
 
QList< AnimationShaderEffectavailableEffects () const
 
AnimationShaderEffect effect (const QString &id) const
 
bool hasEffect (const QString &id) const
 
QStringList effectIds () const
 
QVariantMap translateAnimationParams (const QString &effectId, const QVariantMap &friendlyParams) const
 Translate a friendly parameter map into the canonical slot keys consumed by both runtimes that drive animation shaders.
 

Static Public Member Functions

static QVariantMap translateAnimationParams (const AnimationShaderEffect &effect, const QVariantMap &friendlyParams)
 Static counterpart for callers that already hold the resolved AnimationShaderEffect (e.g.
 
static QString paramPreamble (const AnimationShaderEffect &effect)
 Build the generated #define p_<id> <glsl-accessor> preamble for effect's declared parameters so authors read a parameter by name (p_speed) instead of hand-decoding a customParams[N].xyzw lane.
 
static QString animationEntryPrologue ()
 The T1.4/T1.5 entry-point prologue for animation shaders: #version, the animation_uniforms.glsl include (uniforms + legProgress() / p_reversed / surfaceColor()), and the vTexCoord in / fragColor out.
 
static QList< PhosphorShaders::EntryCandidateanimationEntryCandidates ()
 The direction-dispatched entry candidates (T1.5), in priority order: • vec4 pTransition(vec2 uv, float t) — symmetric; the harness keeps the runtime's iTime flip so it auto-mirrors (t is raw iTime).
 

Detailed Description

Registry of available animation shader transition effects.

Discovers shader packs from configured search paths. Each pack is a subdirectory containing a metadata.json describing the effect plus the shader source files it references.

Directory layout

<search-path>/
dissolve/
metadata.json ← { "id": "dissolve", "fragmentShader": "effect.frag", ... }
effect.frag
slide/
metadata.json
effect.frag
AnimationShaderEffect effect(const QString &id) const

The subdirectory name is decorative — the id field in metadata.json is the registry key. This matches PhosphorShaders::ShaderRegistry's convention for zone shaders.

Search paths and live reload

Storage + change-notify is the generic PhosphorRegistry::Registry<AnimationPack> (one AnimationPack wraps one discovered AnimationShaderEffect); the on-disk scan + hot-reload is a PhosphorRegistry::MetadataPackLoader<AnimationPack>. Search-path management (addSearchPath, addSearchPaths, searchPaths, setUserPath, refresh) forwards to that loader. The first addSearchPath[s] call with LiveReload::On (the default) installs a QFileSystemWatcher with the standard 50 ms debounce, parent-watch promotion for missing user-data dirs, per-file watches re-armed on every rescan, and rescan-during-rescan race protection. Forbidden roots ($HOME, /, XDG data/config/cache/temp/runtime, Documents, Downloads) are refused.

effectsChanged fires on every committed rescan (the loader's coarse onCommitted hook) — i.e. whenever the discovered set or any watched-file fingerprint differs from the previous scan, including any metadata.json field edit or shader-source edit.

Thread safety

GUI-thread only for both reads and mutations. The pack map lives inside the registry and is rebuilt on the GUI thread inside the rescan; the public lookup methods read it without synchronisation.

searchPaths() is the one exception: it returns a by-value snapshot of an implicitly-shared QStringList, so a GUI-thread caller can snapshot it and propagate the result to worker threads. Calling it from a worker thread concurrently with a GUI-thread mutation is a data race; snapshot on the GUI thread first.

Constructor & Destructor Documentation

◆ AnimationShaderRegistry()

PhosphorAnimationShaders::AnimationShaderRegistry::AnimationShaderRegistry ( QObject *  parent = nullptr)
explicit

◆ ~AnimationShaderRegistry()

PhosphorAnimationShaders::AnimationShaderRegistry::~AnimationShaderRegistry ( )
override

Member Function Documentation

◆ addSearchPath()

void PhosphorAnimationShaders::AnimationShaderRegistry::addSearchPath ( const QString &  path,
PhosphorFsLoader::LiveReload  liveReload = PhosphorFsLoader::LiveReload::On 
)

◆ addSearchPaths()

void PhosphorAnimationShaders::AnimationShaderRegistry::addSearchPaths ( const QStringList &  paths,
PhosphorFsLoader::LiveReload  liveReload = PhosphorFsLoader::LiveReload::On,
PhosphorFsLoader::RegistrationOrder  order = PhosphorFsLoader::RegistrationOrder::LowestPriorityFirst 
)

◆ animationEntryCandidates()

static QList< PhosphorShaders::EntryCandidate > PhosphorAnimationShaders::AnimationShaderRegistry::animationEntryCandidates ( )
static

The direction-dispatched entry candidates (T1.5), in priority order: • vec4 pTransition(vec2 uv, float t) — symmetric; the harness keeps the runtime's iTime flip so it auto-mirrors (t is raw iTime).

vec4 pIn(vec2,float) + vec4 pOut(vec2,float) — asymmetric; the harness applies legProgress() (so t is always forward 0→1) and calls the right one by p_reversed. Requires BOTH to be defined. A pack defining its own main() is passed through. Install via ShaderEffect::setEntryScaffold (daemon) and apply via PhosphorShaders::assembleEntryPoint (kwin) so both runtimes agree.

◆ animationEntryPrologue()

static QString PhosphorAnimationShaders::AnimationShaderRegistry::animationEntryPrologue ( )
static

The T1.4/T1.5 entry-point prologue for animation shaders: #version, the animation_uniforms.glsl include (uniforms + legProgress() / p_reversed / surfaceColor()), and the vTexCoord in / fragColor out.

Prepended to an entry-only pack before include expansion; identical on both runtimes (the include's #ifdef PLASMAZONES_KWIN branch handles the binding difference).

◆ availableEffects()

QList< AnimationShaderEffect > PhosphorAnimationShaders::AnimationShaderRegistry::availableEffects ( ) const

◆ effect()

AnimationShaderEffect PhosphorAnimationShaders::AnimationShaderRegistry::effect ( const QString &  id) const

◆ effectIds()

QStringList PhosphorAnimationShaders::AnimationShaderRegistry::effectIds ( ) const

◆ effectsChanged

void PhosphorAnimationShaders::AnimationShaderRegistry::effectsChanged ( )
signal

◆ hasEffect()

bool PhosphorAnimationShaders::AnimationShaderRegistry::hasEffect ( const QString &  id) const

◆ paramPreamble()

static QString PhosphorAnimationShaders::AnimationShaderRegistry::paramPreamble ( const AnimationShaderEffect effect)
static

Build the generated #define p_<id> <glsl-accessor> preamble for effect's declared parameters so authors read a parameter by name (p_speed) instead of hand-decoding a customParams[N].xyzw lane.

The slot allocation mirrors translateAnimationParams exactly — color params fill customColors[N], everything else fills customParams[N].<xyzw>, both in metadata declaration order — so the macro a shader reads resolves to the same UBO lane the value is uploaded to. Both runtimes splice the result after the shader's #version line (via PhosphorShaders::spliceAfterVersion). Returns an empty string when the effect declares no parameters.

◆ refresh()

void PhosphorAnimationShaders::AnimationShaderRegistry::refresh ( )

◆ searchPaths()

QStringList PhosphorAnimationShaders::AnimationShaderRegistry::searchPaths ( ) const

◆ setUserPath()

void PhosphorAnimationShaders::AnimationShaderRegistry::setUserPath ( const QString &  path)

◆ translateAnimationParams() [1/2]

static QVariantMap PhosphorAnimationShaders::AnimationShaderRegistry::translateAnimationParams ( const AnimationShaderEffect effect,
const QVariantMap &  friendlyParams 
)
static

Static counterpart for callers that already hold the resolved AnimationShaderEffect (e.g.

the kwin-effect's per-frame translation). Same slot-allocation contract as the registry-keyed overload.

◆ translateAnimationParams() [2/2]

QVariantMap PhosphorAnimationShaders::AnimationShaderRegistry::translateAnimationParams ( const QString &  effectId,
const QVariantMap &  friendlyParams 
) const

Translate a friendly parameter map into the canonical slot keys consumed by both runtimes that drive animation shaders.

Two independent allocators advance in metadata declaration order:

• Float / int / bool parameters fill customParams<N>_<x|y|z|w> — the first declared param lands in customParams1_x, the second in customParams1_y, …, the fifth in customParams2_x, up to 32 slots (AnimationShaderContract::kMaxParameterSlots).

• Color parameters fill customColor<N> — the first declared color lands in customColor1, the second in customColor2, up to 16 slots (AnimationShaderContract::kMaxCustomColors). Color values are coerced to QColor at this boundary — anything QColor::QColor(QString) accepts is accepted here too (the common cases are "#rgb", "#rrggbb", and "#aarrggbb" with alpha FIRST per Qt's convention; the parser also recognises higher-bit-depth "#rrrgggbbb" / "#rrrrggggbbbb", SVG colour names like "red", and the "transparent" keyword) — alongside QColor instances. Everything else falls back to the declared default, then Qt::transparent. CSS-style "#rrggbbaa" (alpha LAST, 9 chars) is NOT accepted — any 9-char hex string is ambiguous between Qt-form and CSS-form, so a rewrite would silently corrupt configs that already use Qt's order; settings UI / config writers MUST emit Qt-form.

The two allocators advance independently — a color parameter does NOT consume a customParams sub-slot, so a [color, float] declaration produces customColor1 + customParams1_x, not customColor1 + customParams1_y.

Bool values become 0.0 or 1.0. Missing float keys fall back to the metadata-declared default, then to 0.0. Unknown parameter ids in friendlyParams are silently ignored. Slot-budget overflows log a warning and drop the offending parameter.

Returns an empty map when effectId resolves to no registered effect or when the effect declares no parameters.


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