|
| | ShaderRegistry (QObject *parent=nullptr) |
| |
| | ~ShaderRegistry () 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< ShaderInfo > | availableShaders () const |
| |
| QVariantList | availableShadersVariant () const |
| |
| ShaderInfo | shader (const QString &id) const |
| |
| QVariantMap | shaderInfo (const QString &id) const |
| |
| QUrl | shaderUrl (const QString &id) const |
| |
| QVariantMap | defaultParams (const QString &id) const |
| |
| bool | validateParams (const QString &id, const QVariantMap ¶ms) const |
| |
| QVariantMap | validateAndCoerceParams (const QString &id, const QVariantMap ¶ms) const |
| |
| QVariantMap | translateParamsToUniforms (const QString &shaderId, const QVariantMap &storedParams) const |
| |
| QVariantMap | presetParams (const QString &shaderId, const QString &presetName) const |
| |
| QStringList | shaderPresetNames (const QString &shaderId) const |
| |
| QVariantList | shaderPresetsVariant (const QString &shaderId) const |
| |
| bool | shadersEnabled () const |
| | Always true — once a ShaderRegistry is constructed, shader discovery and metadata are functional (the registry is purely a metadata-pack walker; actual shader compilation lives in the phosphor-rendering library which carries the Qt6::ShaderTools dependency).
|
| |
| void | reportShaderBakeStarted (const QString &shaderId) |
| |
| void | reportShaderBakeFinished (const QString &shaderId, bool success, const QString &error) |
| |
|
| static QString | noneShaderUuid () |
| |
| static bool | isNoneShader (const QString &id) |
| |
| static QString | paramPreamble (const ShaderInfo &info) |
| | Build the generated #define p_<id> <glsl-accessor> preamble (T1.1) for info's declared parameters, so a zone shader author reads a parameter by name (p_borderRadius) instead of hand-decoding a customParams[N].xyzw lane.
|
| |
| static ShaderInfo | parsePackMetadata (const QString &packDir, QString *error=nullptr, bool validateSchema=true) |
| | Parse a pack directory's metadata.json into a ShaderInfo using the SAME parser the live registry uses (T1.1 auto-slot assignment included), so an offline validator (phosphor-shader-validate) and the daemon agree on what a pack is.
|
| |
| static QString | wallpaperPath () |
| |
| static QImage | loadWallpaperImage () |
| |
| static QImage | loadWallpaperImage (const QRect &subGeom, const QRect &physGeom) |
| | Return the wallpaper image cropped to the portion that a sub-region (subGeom) occupies on a physical screen (physGeom), assuming "cover" scaling (aspect-correct fill, centered, overflow cropped) — the same placement model the wallpaperUv GLSL helper uses.
|
| |
| static QRect | computeWallpaperCropRect (QSize wpSize, const QRect &physGeom, const QRect &subGeom) |
| | Pure geometry helper: compute the pixel rect inside a wallpaper of size wpSize that corresponds to subGeom when the wallpaper covers physGeom under the same "cover" placement used by wallpaperUv.
|
| |
| static std::optional< QRectF > | wallpaperSliceNormalized (QSize wpSize, const QRect &physGeom, const QRect &subGeom) |
| | The same placement as computeWallpaperCropRect, but NORMALIZED and UNCLAMPED: the slice of the wallpaper corresponding to subGeom, in [0,1] texture coords, allowed to run outside that range when subGeom hangs over physGeom.
|
| |
| static void | invalidateWallpaperCache () |
| |
Registry of available shader effects.
Discovers shaders from configured search paths, validates metadata, manages parameter presets, and watches for file changes.
Composition roots own a per-process instance and register search paths explicitly — there is no library-level singleton. Tests construct a per-fixture registry; downstream consumers (Phosphor shell, future plugin compositors) instantiate their own.
Storage + change-notify is the generic PhosphorRegistry::Registry<ShaderPack> (one ShaderPack wraps one discovered ShaderInfo); the on-disk scan + hot-reload is a PhosphorRegistry::MetadataPackLoader<ShaderPack> that parses each pack's metadata.json and reconciles the registry. Search-path management (addSearchPath, addSearchPaths, searchPaths, setUserPath, refresh) forwards to that loader.
Thread safety
GUI-thread only for both reads and mutations. The shader map lives inside the registry and is rebuilt on the GUI thread inside the rescan; the public lookup methods (availableShaders, shader, shaderInfo, shaderUrl) read it without synchronisation.
Two exceptions:
searchPaths() 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 (this is the shader-warming path's contract). Calling searchPaths() from a worker thread concurrently with a GUI-thread mutation is a data race; snapshot on the GUI thread first.
The static wallpaper-path cache (resolveWallpaperPath and friends in shaderregistry_wallpaper.cpp) is guarded by its own process-wide mutex and is safe to call from any thread.
| static QImage PhosphorShaders::ShaderRegistry::loadWallpaperImage |
( |
const QRect & |
subGeom, |
|
|
const QRect & |
physGeom |
|
) |
| |
|
static |
Return the wallpaper image cropped to the portion that a sub-region (subGeom) occupies on a physical screen (physGeom), assuming "cover" scaling (aspect-correct fill, centered, overflow cropped) — the same placement model the wallpaperUv GLSL helper uses.
Returns the full (uncropped) wallpaper when either rect is invalid or when subGeom covers all of physGeom.
Virtual screens that share a physical monitor need this so each VS samples the wallpaper portion it occupies on the monitor, instead of each getting the center-cropped wallpaper as if it were a full screen.
The result is memoized keyed on (subGeom, physGeom, wallpaper mtime), so repeated calls for the same VS return the same QImage (stable cacheKey()) and avoid re-uploading to the GPU each frame.
| static ShaderInfo PhosphorShaders::ShaderRegistry::parsePackMetadata |
( |
const QString & |
packDir, |
|
|
QString * |
error = nullptr, |
|
|
bool |
validateSchema = true |
|
) |
| |
|
static |
Parse a pack directory's metadata.json into a ShaderInfo using the SAME parser the live registry uses (T1.1 auto-slot assignment included), so an offline validator (phosphor-shader-validate) and the daemon agree on what a pack is.
Returns an invalid ShaderInfo and sets error on a missing/unreadable/oversized file, non-object JSON root, or a root failing the same structural schema gate the live scan applies. Two live rejections are deliberately NOT reproduced here — a missing fragment shader and a multipass pack with no surviving buffer shader — because the offline validator reports those as its own lints with file context.
Existence is checked unevenly, and a caller cannot infer "not declared" from an empty field: the FRAGMENT path is returned whether or not the file is there (that one is a validator lint), a declared-but-missing vertexShader is DROPPED, and a missing buffer shader clears the whole bufferShaderPaths list.
Declared paths are containment-checked: a fragmentShader, vertexShader or bufferShaders entry resolving outside the pack directory is refused, because these name files that get compiled and run on the GPU. A refused sourcePath comes back EMPTY, and a refused entry drops the whole bufferShaderPaths list (they are positionally aligned with the per-buffer wrap/filter overrides, so compacting one out would shift the rest onto the wrong buffer). Pack-declared image PRESET values ARE containment-checked here, with the Reject policy, because their provenance is only known to be the pack at parse time; a refused entry is dropped from the preset. Image PARAM values are a separate matter and are resolved, and containment-checked, in translateParamsToUniforms.
- Parameters
-
| validateSchema | when true (the default), the metadata is first run through the shared shader-metadata JSON schema and REJECTED on any violation — the same gate the daemon's live scan applies, so the offline validator refuses exactly the packs the daemon refuses. The shader-render preview tool passes false: it is a developer aid that tolerantly previews whatever metadata it is handed (defaulting names, dropping out-of-range slots) rather than gatekeeping, and its own parse defaults already mirror the tolerant behaviour. Path-traversal confinement is applied either way. |
| static std::optional< QRectF > PhosphorShaders::ShaderRegistry::wallpaperSliceNormalized |
( |
QSize |
wpSize, |
|
|
const QRect & |
physGeom, |
|
|
const QRect & |
subGeom |
|
) |
| |
|
static |
The same placement as computeWallpaperCropRect, but NORMALIZED and UNCLAMPED: the slice of the wallpaper corresponding to subGeom, in [0,1] texture coords, allowed to run outside that range when subGeom hangs over physGeom.
For a caller that maps the result across a whole quad rather than cropping an image out of it. computeWallpaperCropRect intersects subGeom with physGeom, which is right for producing an image but wrong here: the shader spreads uv over the FULL surface regardless, so a clamped slice would be stretched to cover an overhanging one, shifting and mis-scaling the result. Letting the rect run out of range instead lets the sampler's edge clamp handle the overhang, which is what an outer glow reaching past the screen should look like.
Returns a null optional only for degenerate inputs. A surface exactly covering the screen is NOT degenerate here — it legitimately maps to the whole cover region — which is the other reason this cannot reuse computeWallpaperCropRect, whose contract treats that as "use the full
image".