Phosphor
Qt6 / Wayland library suite for window-management tools
 
Loading...
Searching...
No Matches
PhosphorShaders Namespace Reference

Namespaces

namespace  CustomColors
 Canonical key format for the customColors[N] slots in BaseUniforms.
 
namespace  CustomParams
 Canonical key format for the customParams[N].
 
namespace  UboRegions
 UBO region offsets and sizes for partial updates (reduces GPU bandwidth).
 

Classes

class  BaseUniformProfile
 IUboProfile implementation for the overlay/animation runtime — the legacy 672-byte BaseUniforms layout. More...
 
struct  BaseUniforms
 GPU uniform buffer layout following std140 rules (base region). More...
 
struct  EntryCandidate
 One candidate entry function the author may define, paired with the void main() the harness generates when that function is present and the source defines no main() of its own (T1.4). More...
 
class  IUboProfile
 Pluggable UBO concern for the shared shader render engine. More...
 
class  IUniformExtension
 Interface for appending custom uniform data after the base UBO layout. More...
 
class  IWallpaperProvider
 Abstract wallpaper provider interface. More...
 
struct  PreambleParam
 
class  ShaderIncludeResolver
 Resolves #include directives in GLSL shader source. More...
 
class  ShaderRegistry
 Registry of available shader effects. More...
 
struct  UboDirtyFlags
 Which conceptual blocks of the UBO changed since the last upload. More...
 
struct  UboFrameState
 Snapshot of every node-side value a UBO profile's fill() may read for a single frame. More...
 
struct  UboUploadRegion
 A contiguous byte range inside the UBO to (re)upload via QRhiResourceUpdateBatch::updateDynamicBuffer. More...
 
class  UboUploadRegionList
 Fixed-capacity list of upload regions. More...
 

Functions

bool isValidWrapToken (const QString &wrap)
 The accepted texture / buffer wrap vocabulary, shared by every validation site across the shader registries (overlay image-param parse, surface metadata parse, per-slot texture parse, and runtime override translation).
 
bool isValidFilterToken (const QString &filter)
 The accepted buffer filter vocabulary: linear / nearest / mipmap.
 
PHOSPHORSHADERS_EXPORT std::unique_ptr< IWallpaperProvidercreateWallpaperProvider ()
 Create the default wallpaper provider for the current desktop environment.
 
QLatin1String pixelUnit ()
 The unit a parameter declares when its value is logical pixels of the real surface the shader draws on, which is the screen for a zone/overlay pack.
 
PHOSPHORSHADERS_EXPORT void scalePixelParams (const QVariantList &parameterInfos, QVariantMap &values, double factor)
 Scale every px-denominated parameter for a host that renders the shader on a surface smaller than the real thing.
 
PHOSPHORSHADERS_EXPORT bool definesMain (const QString &expandedSource)
 True if expandedSource defines void main() at top level.
 
PHOSPHORSHADERS_EXPORT bool definesFunction (const QString &expandedSource, const QString &functionName)
 True if expandedSource defines a function named functionName.
 
PHOSPHORSHADERS_EXPORT QString composeEntryPoint (const QString &expandedSource, const QList< EntryCandidate > &candidates)
 Compose the fragment entry point (T1.4).
 
PHOSPHORSHADERS_EXPORT QString assembleEntryPoint (const QString &raw, const QString &prologue, const QList< EntryCandidate > &candidates)
 Convenience wrapper for the full assembly: when candidates is empty or raw already defines main(), returns raw unchanged; otherwise returns composeEntryPoint(prologue + raw, candidates).
 
PHOSPHORSHADERS_EXPORT QString stripGlslComments (const QString &source)
 Strip GLSL line (//…) and block (/* … *&zwj;/) comments from source, preserving newlines inside block comments so line numbers are unchanged.
 
PHOSPHORSHADERS_EXPORT QString buildParamPreamble (const QList< PreambleParam > &params)
 Build the generated #define p_<id> <glsl-accessor> preamble for a shader's declared parameters.
 
PHOSPHORSHADERS_EXPORT bool isValidParamId (const QString &id)
 True if id is a valid GLSL identifier body ([A-Za-z0-9_], non-empty) — the p_ prefix supplies the leading character, so a leading digit is fine.
 
PHOSPHORSHADERS_EXPORT QString spliceAfterVersion (const QString &source, const QString &block)
 Splice block into source immediately after its #version line, then emit a #line <n> 0 directive so the author's subsequent lines keep their original numbers (source string 0) despite the inserted block.
 
PHOSPHORSHADERS_EXPORT QString kwinDefineBlock (const QString &eol=QStringLiteral("\n"))
 The preprocessor block that selects the COMPOSITOR branch of a pack's source, newline-terminated with eol and ready for spliceAfterVersion.
 

Variables

constexpr double kShaderTimeWrap = 1024.0
 Time wrap period for float32 precision preservation.
 
constexpr double kMinBufferScale = 0.125
 Lower / upper bounds on a multipass bufferScale (FBO downscale factor).
 
constexpr double kMaxBufferScale = 1.0
 
constexpr int kMaxBufferPasses = 4
 Maximum number of multipass buffer passes a pack may declare.
 
constexpr int kMaxImageSlots = 4
 One declared shader parameter, in metadata declaration order, as fed to buildParamPreamble.
 

Function Documentation

◆ assembleEntryPoint()

PHOSPHORSHADERS_EXPORT QString PhosphorShaders::assembleEntryPoint ( const QString &  raw,
const QString &  prologue,
const QList< EntryCandidate > &  candidates 
)

Convenience wrapper for the full assembly: when candidates is empty or raw already defines main(), returns raw unchanged; otherwise returns composeEntryPoint(prologue + raw, candidates).

This is the single assembly entry point shared by the daemon bake layer and the kwin-effect path so both produce the identical pre-expansion source for an entry-only pack. Apply it to RAW (pre-expansion) source so the prologue's #include is then resolved. Entry-function detection therefore sees only the author's inline body — by convention the entry function (pZone/pImage/pTransition, or a hand-written main()) is authored directly, never pulled from an #include — which is why this wraps RAW rather than the expanded source composeEntryPoint expects.

◆ buildParamPreamble()

PHOSPHORSHADERS_EXPORT QString PhosphorShaders::buildParamPreamble ( const QList< PreambleParam > &  params)

Build the generated #define p_<id> <glsl-accessor> preamble for a shader's declared parameters.

Auto-numbers each pool independently in declaration order for params whose explicitSlot < 0. Returns an empty string for an empty list. A param whose id isn't a valid GLSL identifier body, or whose resolved slot is out of range, is emitted as a // p: skipped ... comment rather than a broken #define, so the block always compiles.

The returned block is newline-terminated and contains no #version or #line directive — the caller splices it after the shader's #version line and is responsible for any #line fixup that restores author line numbers (see the include resolver's #line contract).

◆ composeEntryPoint()

PHOSPHORSHADERS_EXPORT QString PhosphorShaders::composeEntryPoint ( const QString &  expandedSource,
const QList< EntryCandidate > &  candidates 
)

Compose the fragment entry point (T1.4).

• If expandedSource already defines void main(), it is returned unchanged — the author keeps full control (the escape hatch every existing pack uses today). • Otherwise the first candidate whose functionName is defined has its generatedMain appended (separated by a newline) and the result returned. • If no main() and no candidate matches, expandedSource is returned unchanged; the compiler then surfaces the missing-main() error, which the offline validator (T1.2) maps back to the author's file via the resolver's #line legend.

Splice the T1.1 param preamble (spliceAfterVersion) AFTER this, or before — they don't overlap (the preamble sits just after #version; the wrapper is appended at the end), but compose on the include-expanded source so definesMain / definesFunction see any entry point arriving from an include.

◆ createWallpaperProvider()

PHOSPHORSHADERS_EXPORT std::unique_ptr< IWallpaperProvider > PhosphorShaders::createWallpaperProvider ( )

Create the default wallpaper provider for the current desktop environment.

Detects KDE, Hyprland, Sway, GNOME and returns the appropriate implementation. Returns a fallback provider (empty path) if no supported DE is detected.

◆ definesFunction()

PHOSPHORSHADERS_EXPORT bool PhosphorShaders::definesFunction ( const QString &  expandedSource,
const QString &  functionName 
)

True if expandedSource defines a function named functionName.

Matches a definition — <name> ( <params> ) { — not a call: the trailing { distinguishes vec4 pZone(ZoneCtx z) { … } from return pZone(z);. Comments are stripped first. functionName is matched as a whole word. Parameter lists spanning multiple lines are handled.

◆ definesMain()

PHOSPHORSHADERS_EXPORT bool PhosphorShaders::definesMain ( const QString &  expandedSource)

True if expandedSource defines void main() at top level.

Comments are stripped first so a main inside a // or block comment never false-matches, and the match requires the () signature followed by { so a stray main identifier or a forward reference can't trip it. Run on the include-expanded source: a main() can legitimately arrive from an include, and the harness must treat that exactly like an inline one.

◆ isValidFilterToken()

bool PhosphorShaders::isValidFilterToken ( const QString &  filter)
inline

The accepted buffer filter vocabulary: linear / nearest / mipmap.

Same membership and empty-string contract as isValidWrapToken; PhosphorSurfaceShaders::isValidFilterToken forwards to this.

◆ isValidParamId()

PHOSPHORSHADERS_EXPORT bool PhosphorShaders::isValidParamId ( const QString &  id)

True if id is a valid GLSL identifier body ([A-Za-z0-9_], non-empty) — the p_ prefix supplies the leading character, so a leading digit is fine.

Shared so the metadata parser's auto-slot assignment skips exactly the same params buildParamPreamble skips, keeping the two lane-numberings identical.

◆ isValidWrapToken()

bool PhosphorShaders::isValidWrapToken ( const QString &  wrap)
inline

The accepted texture / buffer wrap vocabulary, shared by every validation site across the shader registries (overlay image-param parse, surface metadata parse, per-slot texture parse, and runtime override translation).

Returns true only for the three canonical tokens clamp / repeat / mirror. An empty string is NOT a member — callers treat empty as "use the runtime default" and handle it explicitly before consulting this predicate. Lives here (the lowest shader library) so overlay and surface validation cannot drift apart; PhosphorSurfaceShaders::isValidWrapToken forwards to this. Vocabulary matches the runtime normaliser (ShaderNodeRhi::normalizeWrapMode).

◆ kwinDefineBlock()

PHOSPHORSHADERS_EXPORT QString PhosphorShaders::kwinDefineBlock ( const QString &  eol = QStringLiteral("\n"))

The preprocessor block that selects the COMPOSITOR branch of a pack's source, newline-terminated with eol and ready for spliceAfterVersion.

#define PLASMAZONES_KWIN is the ABI switch itself: the shared uniform headers key their default-block-uniform branch off it. The two ARB directives ride along because KWin 6.7's generateCustomShader recompiles custom effect shaders at GLSL #version 140, where the layout(location = N) qualifiers our vertex stages declare are illegal without them (NVIDIA error C7548). They are a harmless no-op in the fragment stage.

Shared because THREE places must agree on it exactly and they are in different link units: the compositor's own ShaderInternal::injectKwinDefineAfterVersion (which wraps this with the #version-finding walk), the offline validator's compositor bake, and the GPU bake test. A private copy in any of them turns the two checkers into gates that pass source the compositor would reject, or reject source it accepts — the exact failure a reproduce-the-runtime gate exists to rule out.

◆ pixelUnit()

QLatin1String PhosphorShaders::pixelUnit ( )
inline

The unit a parameter declares when its value is logical pixels of the real surface the shader draws on, which is the screen for a zone/overlay pack.

Only zone/overlay pack metadata declares this: the surface schema has no unit field and nothing under libs/phosphor-surface reads one.

Every other parameter is unitless as far as the runtime is concerned: a strength, an angle, a count, a colour. Only px values have to be re-read when the surface is not its real size.

◆ scalePixelParams()

PHOSPHORSHADERS_EXPORT void PhosphorShaders::scalePixelParams ( const QVariantList &  parameterInfos,
QVariantMap &  values,
double  factor 
)

Scale every px-denominated parameter for a host that renders the shader on a surface smaller than the real thing.

A shader's px parameters are absolute against the surface it draws on: a 24px blur radius over a 1000px window is a light frost, and the SAME 24px over a 240px preview card covers a tenth of it and swallows everything underneath. So a preview that shrinks the surface has to shrink the pixel values with it, or it shows a different effect than the one that will run — and, when the same shader is previewed at two sizes, two different effects.

factor is the linear reduction (preview extent / real extent). 1.0, and anything non-finite or non-positive, leaves values untouched.

ONE factor, taken from a single axis (width, at every current call site), is applied to every px parameter. That is exact only while the preview preserves the screen's aspect ratio, which the current preview hosts do NOT — they scale their rects anisotropically, so a px parameter denominating a VERTICAL length is still scaled by the horizontal ratio and comes out slightly off. A second, per-axis factor is not the fix: nothing in the pack metadata says which axis a parameter denominates, so there is no way to pick the right one. The limitation is documented rather than papered over.

A px parameter the caller left out of values is INSERTED at its scaled default rather than skipped: an absent parameter falls back to the pack's declared default further down the pipeline, which is the unscaled value this function exists to avoid. Parameters with any other unit are passed through, values that are not numbers are passed through, and the map keeps every entry the caller put in it. image parameters are skipped outright, even if one declares px: their values are paths, and inserting a default for one would manufacture the "the user set this" provenance that ShaderRegistry::translateParamsToUniforms derives from key presence to pick its absolute-path Trust-vs-Reject policy.

◆ spliceAfterVersion()

PHOSPHORSHADERS_EXPORT QString PhosphorShaders::spliceAfterVersion ( const QString &  source,
const QString &  block 
)

Splice block into source immediately after its #version line, then emit a #line <n> 0 directive so the author's subsequent lines keep their original numbers (source string 0) despite the inserted block.

source is expected to be already include-expanded — the resolver's own #line bracketing uses the raw line positions, so injecting before expansion would corrupt its math; injecting here, after expansion, composes cleanly (the fixup re-anchors source string 0; the resolver's later #line directives are untouched). block must be newline-terminated (as buildParamPreamble returns). An empty block returns source unchanged. If source has no #version line the block is prepended best-effort (such source is not valid GLSL anyway).

The #version line is located by a line-anchored regex, which does NOT track block comments: a line whose non-whitespace prefix is #version INSIDE a /* … *&zwj;/ block, appearing before the real directive, would be matched. (A //-commented line cannot match — its prefix is //.) Such source is not valid GLSL either, since #version must be the first non-comment token, so no well-formed pack can reach it. The compositor's ShaderInternal::injectKwinDefineAfterVersion runs a comment-aware walk instead, because the block it splices is the ABI switch itself and a pack that lost it would compile as the wrong dialect rather than fail.

◆ stripGlslComments()

PHOSPHORSHADERS_EXPORT QString PhosphorShaders::stripGlslComments ( const QString &  source)

Strip GLSL line (//…) and block (/* … *&zwj;/) comments from source, preserving newlines inside block comments so line numbers are unchanged.

Exposed for the detection helpers and for tests; GLSL has no string literals so there is no quoting context to preserve.

Variable Documentation

◆ kMaxBufferPasses

constexpr int PhosphorShaders::kMaxBufferPasses = 4
inlineconstexpr

Maximum number of multipass buffer passes a pack may declare.

Canonical home shared by the overlay parser and the pack validator (the surface tree keeps its own SurfaceShaderEffect::kMaxBufferPasses at the same value, and the animation tree AnimationShaderContract::kMaxBufferPasses); every buffer pass costs a canvas-sized RGBA8 texture, so the cap bounds GPU memory.

◆ kMaxBufferScale

constexpr double PhosphorShaders::kMaxBufferScale = 1.0
inlineconstexpr

◆ kMaxImageSlots

constexpr int PhosphorShaders::kMaxImageSlots = 4
inlineconstexpr

One declared shader parameter, in metadata declaration order, as fed to buildParamPreamble.

The generator turns a list of these into the #define p_<id> <glsl-accessor> block both shader runtimes inject so an author reads a parameter by name (p_speed) instead of hand-decoding a customParams[N].xyzw lane. Image-pool budget: overlay/zone image params bind to uTexture0..3. Animation packs never use the Image pool (their textures are a separate top-level list bound to uTexture1..3), so this cap only governs the zone path. Public so the metadata parser can warn on over-budget slots with the same figure the preamble generator skips at.

◆ kMinBufferScale

constexpr double PhosphorShaders::kMinBufferScale = 0.125
inlineconstexpr

Lower / upper bounds on a multipass bufferScale (FBO downscale factor).

0.125 means a 1/8 downscale on each axis (1/64 area — the lowest cost-floor that still gives Shadertoy-style buffer effects something to work with); 1.0 means full-resolution FBOs. Canonical home for every clamp site (overlay metadata parse, surface SurfaceShaderEffect::kMin/MaxBufferScale forwarders, and the two rendering setters), so the bounds cannot drift per-runtime.

◆ kShaderTimeWrap

constexpr double PhosphorShaders::kShaderTimeWrap = 1024.0
constexpr

Time wrap period for float32 precision preservation.