Shader-effect registry, base UBO layout, the
IUniformExtensioncontract, GLSL#includeresolution, and the abstract wallpaper provider. The shared shader-domain pieces every consumer of `phosphor-rendering` builds on.
The render node in phosphor-rendering is generic. It owns the QRhi pipeline and a UBO of unspecified shape. phosphor-shaders ships the shape: the std140 base UBO every shader effect inherits, the extension contract that lets a consumer append application-specific data after the base region, and the metadata that turns a directory of shader files into a discoverable, parameterised effect.
Consumed by `phosphor-rendering` (writes the base UBO, calls IUniformExtension::write() for the remainder), `phosphor-animation` (whose AnimationShaderRegistry reuses the same strategy), and the Phosphor overlay (hosts ShaderEffect items in QML).
| Type | Purpose |
|---|---|
PhosphorShaders::BaseUniforms | std140 base UBO layout. Shadertoy-compatible block + two appField ints for cheap consumer-defined state |
PhosphorShaders::IUniformExtension | Contract for appending custom uniform data after BaseUniforms, where extensionSize() is fixed for the lifetime of the instance |
| PhosphorShaders::CustomParams / CustomColors | Canonical key formats (customParams<N>_<x|y|z|w>, customColor<N>) for the per-effect parameter sub-slots in BaseUniforms (namespaces in CustomParamsKey.h) | | PhosphorShaders::ShaderRegistry | Discovers shader effects from search paths via metadata-pack scanning. Per-process instance, no singleton | | PhosphorShaders::ShaderRegistry::ParameterInfo | Parameter declaration: name, type, default, range, UBO uniform name | | PhosphorShaders::ShaderIncludeResolver | #include "path" / #include <path> expansion with depth limit | | PhosphorShaders::IWallpaperProvider | Abstract source for the active desktop wallpaper image path | | PhosphorShaders::createWallpaperProvider| Factory that auto-detects KDE / Hyprland / Sway / GNOME | | PhosphorShaders::buildParamPreamble | Generates the per-effect #define preamble that maps declared parameter ids onto UBO lanes | | PhosphorShaders::spliceAfterVersion | Inserts generated GLSL directly after a source's #version line | | PhosphorShaders::BaseUniformProfile | Describes which base-UBO regions a consumer actually uploads | | PhosphorShaders::IUboProfile | Contract for a bounded set of UBO upload regions (kCapacity of them) | | PhosphorShaders::ShaderEntryPoint | Which entry point a pack's stage declares, so the loader can wrap it correctly |
Wire up a shader effect in QML, with a per-process registry and a wallpaper provider for effects that sample the desktop background:
#include <PhosphorShaders/ShaderRegistry.h>
#include <PhosphorShaders/IWallpaperProvider.h>
using namespace PhosphorShaders;
ShaderRegistry registry;
registry.addSearchPath(QStringLiteral("/usr/share/myapp/shaders"));
registry.setUserPath(QStandardPaths::writableLocation(
QStandardPaths::AppDataLocation) + QStringLiteral("/shaders"));
registry.refresh();
auto wallpaper = createWallpaperProvider();
QString path = wallpaper->wallpaperPath(); // "" if unsupported DEImplement an IUniformExtension to append per-zone data to the UBO:
class MyExtension : public PhosphorShaders::IUniformExtension {
public:
int extensionSize() const override { return sizeof(MyTail); }
bool isDirty() const override { return m_dirty.exchange(false); }
void write(void* dst) override { std::memcpy(dst, &m_tail, sizeof(MyTail)); }
private:
MyTail m_tail;
mutable std::atomic<bool> m_dirty{true};
};ShaderRegistry instance and register search paths explicitly. Tests construct a per-fixture registry, and downstream consumers do the same.extensionSize() is fixed for the instance lifetime.** The render node sizes the UBO and staging buffer once when an extension is installed via setUniformExtension() and reuses both across frames. To resize, install a fresh extension instance, which triggers UBO recreation.appField0 / appField1 exist regardless of use.** They fill the std140 alignment slot between iResolution (vec2) and iMouse (vec4), and removing them would break the layout. Repurpose them for small (≤2 ints) frequently-updated state that needs to live inside BaseUniforms rather than the extension region.Registry<ShaderPack> inside ShaderRegistry, rebuilt on the GUI thread inside the rescan. The public lookup methods (availableShaders, shader, shaderInfo, shaderUrl) read it without synchronisation. searchPaths() returns a by-value snapshot suitable for handing to worker threads (the shader-warming path).PhosphorRegistry::MetadataPackLoader. Search-path management is in phosphor-fsloader, and ShaderRegistry adds only the shader-specific lookup surface.QtCore, QtGuiphosphor-registry's MetadataPackLoaderRegistry<T> + MetadataPackLoader<T>, both reached through ShaderRegistry's public headers, so this is a PUBLIC dependencyShaderEffect + ShaderNodeRhi consume BaseUniforms and IUniformExtension.AnimationShaderRegistry is a parallel registry for transition effects.