Add runtime color filter and shader modes to the SkSL compiler
These enforce stricter rules about the signature of main, and each one
uses a separate pre-include module. That prevents color filters from
being able to reference sk_FragCoord (or coords passed to main) at all.
It also limits the versions of sample() that are exposed.
In the new world, an effect created for a specific stage of the Skia
pipeline can only be used to create instances of that stage (SkShader or
SkColorFilter). For now, SkRuntimeEffect::Make uses kRuntimeEffect,
which continues to be more lenient and allow creation of either shaders
or color filters from a single effect. After we migrate all clients, we
can deprecate and then delete that mode.
Bug: skia:11813
Change-Id: I0afd79a72beeec84da42c86146e8fcd8d0e4c09f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/395716
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index d1a562b..7f64d19 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -63,6 +63,8 @@
#include "src/sksl/generated/sksl_geom.dehydrated.sksl"
#include "src/sksl/generated/sksl_gpu.dehydrated.sksl"
#include "src/sksl/generated/sksl_public.dehydrated.sksl"
+#include "src/sksl/generated/sksl_rt_colorfilter.dehydrated.sksl"
+#include "src/sksl/generated/sksl_rt_shader.dehydrated.sksl"
#include "src/sksl/generated/sksl_runtime.dehydrated.sksl"
#include "src/sksl/generated/sksl_vert.dehydrated.sksl"
@@ -242,39 +244,63 @@
return fPublicModule;
}
+static void add_glsl_type_aliases(SkSL::SymbolTable* symbols, const SkSL::BuiltinTypes& types) {
+ // Add some aliases to the runtime effect modules so that it's friendlier, and more like GLSL
+ symbols->addAlias("vec2", types.fFloat2.get());
+ symbols->addAlias("vec3", types.fFloat3.get());
+ symbols->addAlias("vec4", types.fFloat4.get());
+
+ symbols->addAlias("ivec2", types.fInt2.get());
+ symbols->addAlias("ivec3", types.fInt3.get());
+ symbols->addAlias("ivec4", types.fInt4.get());
+
+ symbols->addAlias("bvec2", types.fBool2.get());
+ symbols->addAlias("bvec3", types.fBool3.get());
+ symbols->addAlias("bvec4", types.fBool4.get());
+
+ symbols->addAlias("mat2", types.fFloat2x2.get());
+ symbols->addAlias("mat3", types.fFloat3x3.get());
+ symbols->addAlias("mat4", types.fFloat4x4.get());
+}
+
const ParsedModule& Compiler::loadRuntimeEffectModule() {
if (!fRuntimeEffectModule.fSymbols) {
- fRuntimeEffectModule = this->parseModule(ProgramKind::kRuntimeEffect, MODULE_DATA(runtime),
- this->loadPublicModule());
-
- // Add some aliases to the runtime effect module so that it's friendlier, and more like GLSL
- fRuntimeEffectModule.fSymbols->addAlias("vec2", fContext->fTypes.fFloat2.get());
- fRuntimeEffectModule.fSymbols->addAlias("vec3", fContext->fTypes.fFloat3.get());
- fRuntimeEffectModule.fSymbols->addAlias("vec4", fContext->fTypes.fFloat4.get());
-
- fRuntimeEffectModule.fSymbols->addAlias("ivec2", fContext->fTypes.fInt2.get());
- fRuntimeEffectModule.fSymbols->addAlias("ivec3", fContext->fTypes.fInt3.get());
- fRuntimeEffectModule.fSymbols->addAlias("ivec4", fContext->fTypes.fInt4.get());
-
- fRuntimeEffectModule.fSymbols->addAlias("bvec2", fContext->fTypes.fBool2.get());
- fRuntimeEffectModule.fSymbols->addAlias("bvec3", fContext->fTypes.fBool3.get());
- fRuntimeEffectModule.fSymbols->addAlias("bvec4", fContext->fTypes.fBool4.get());
-
- fRuntimeEffectModule.fSymbols->addAlias("mat2", fContext->fTypes.fFloat2x2.get());
- fRuntimeEffectModule.fSymbols->addAlias("mat3", fContext->fTypes.fFloat3x3.get());
- fRuntimeEffectModule.fSymbols->addAlias("mat4", fContext->fTypes.fFloat4x4.get());
+ fRuntimeEffectModule = this->parseModule(
+ ProgramKind::kRuntimeEffect, MODULE_DATA(runtime), this->loadPublicModule());
+ add_glsl_type_aliases(fRuntimeEffectModule.fSymbols.get(), fContext->fTypes);
}
return fRuntimeEffectModule;
}
+const ParsedModule& Compiler::loadRuntimeColorFilterModule() {
+ if (!fRuntimeColorFilterModule.fSymbols) {
+ fRuntimeColorFilterModule = this->parseModule(ProgramKind::kRuntimeColorFilter,
+ MODULE_DATA(rt_colorfilter),
+ this->loadPublicModule());
+ add_glsl_type_aliases(fRuntimeColorFilterModule.fSymbols.get(), fContext->fTypes);
+ }
+ return fRuntimeColorFilterModule;
+}
+
+const ParsedModule& Compiler::loadRuntimeShaderModule() {
+ if (!fRuntimeShaderModule.fSymbols) {
+ fRuntimeShaderModule = this->parseModule(
+ ProgramKind::kRuntimeShader, MODULE_DATA(rt_shader), this->loadPublicModule());
+ add_glsl_type_aliases(fRuntimeShaderModule.fSymbols.get(), fContext->fTypes);
+ }
+ return fRuntimeShaderModule;
+}
+
const ParsedModule& Compiler::moduleForProgramKind(ProgramKind kind) {
switch (kind) {
- case ProgramKind::kVertex: return this->loadVertexModule(); break;
- case ProgramKind::kFragment: return this->loadFragmentModule(); break;
- case ProgramKind::kGeometry: return this->loadGeometryModule(); break;
- case ProgramKind::kFragmentProcessor: return this->loadFPModule(); break;
- case ProgramKind::kRuntimeEffect: return this->loadRuntimeEffectModule(); break;
- case ProgramKind::kGeneric: return this->loadPublicModule(); break;
+ case ProgramKind::kVertex: return this->loadVertexModule(); break;
+ case ProgramKind::kFragment: return this->loadFragmentModule(); break;
+ case ProgramKind::kGeometry: return this->loadGeometryModule(); break;
+ case ProgramKind::kFragmentProcessor: return this->loadFPModule(); break;
+ case ProgramKind::kRuntimeEffect: return this->loadRuntimeEffectModule(); break;
+ case ProgramKind::kRuntimeColorFilter: return this->loadRuntimeColorFilterModule(); break;
+ case ProgramKind::kRuntimeShader: return this->loadRuntimeShaderModule(); break;
+ case ProgramKind::kGeneric: return this->loadPublicModule(); break;
}
SkUNREACHABLE;
}