[graphite] Reorganize code snippets a bit

This inches us towards the model of the code snippets being subroutines that are then glued together in a main method.

Bug: skia:12701
Change-Id: I49c39636debd2dbe512c7d5f9bc401dd899df1dd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/504556
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2022-02-04 13:23:44 -05:00 committed by SkCQ
parent 324e00243f
commit 6c28bd97fe
3 changed files with 57 additions and 35 deletions

View File

@ -25,6 +25,7 @@ using GradientData = GradientShaderBlocks::GradientData;
namespace { namespace {
//--------------------------------------------------------------------------------------------------
// TODO: For the sprint we unify all the gradient uniforms into a standard set of 6: // TODO: For the sprint we unify all the gradient uniforms into a standard set of 6:
// kMaxStops colors // kMaxStops colors
// kMaxStops offsets // kMaxStops offsets
@ -32,49 +33,63 @@ namespace {
// 2 radii // 2 radii
static constexpr int kNumGradientUniforms = 6; static constexpr int kNumGradientUniforms = 6;
static constexpr SkUniform kGradientUniforms[kNumGradientUniforms] = { static constexpr SkUniform kGradientUniforms[kNumGradientUniforms] = {
{"colors", SkSLType::kHalf4, GradientData::kMaxStops }, { "colors", SkSLType::kHalf4, GradientData::kMaxStops },
{"offsets", SkSLType::kFloat, GradientData::kMaxStops }, { "offsets", SkSLType::kFloat, GradientData::kMaxStops },
{"point0", SkSLType::kFloat2 }, { "point0", SkSLType::kFloat2 },
{"point1", SkSLType::kFloat2 }, { "point1", SkSLType::kFloat2 },
{"radius0", SkSLType::kFloat }, { "radius0", SkSLType::kFloat },
{"radius1", SkSLType::kFloat }, { "radius1", SkSLType::kFloat },
}; };
static const char *kLinearGradient4Name = "linear_grad_4_shader";
static const char *kLinearGradient4SkSL =
// TODO: This should use local coords
"half4 linear_grad_4_shader() {\n"
" float2 pos = sk_FragCoord.xy;\n"
" float2 delta = point1 - point0;\n"
" float2 pt = pos - point0;\n"
" float t = dot(pt, delta) / dot(delta, delta);\n"
" float4 result = colors[0];\n"
" result = mix(result, colors[1],\n"
" clamp((t-offsets[0])/(offsets[1]-offsets[0]),\n"
" 0, 1));\n"
" result = mix(result, colors[2],\n"
" clamp((t-offsets[1])/(offsets[2]-offsets[1]),\n"
" 0, 1));\n"
" result = mix(result, colors[3],\n"
" clamp((t-offsets[2])/(offsets[3]-offsets[2]),\n"
" 0, 1));\n"
" return half4(result);\n"
"}\n";
//--------------------------------------------------------------------------------------------------
static constexpr int kNumSolidUniforms = 1; static constexpr int kNumSolidUniforms = 1;
static constexpr SkUniform kSolidUniforms[kNumSolidUniforms] = { static constexpr SkUniform kSolidUniforms[kNumSolidUniforms] = {
{"color", SkSLType::kFloat4 } { "color", SkSLType::kFloat4 }
}; };
static const char* kSolidColorName = "solid_shader";
static const char* kSolidColorSkSL =
"half4 solid_shader() {\n"
" return half4(color);\n"
"}\n";
//--------------------------------------------------------------------------------------------------
static constexpr int kNumImageUniforms = 0; static constexpr int kNumImageUniforms = 0;
static constexpr SkUniform kImageUniforms[kNumImageUniforms] = { static constexpr SkUniform kImageUniforms[kNumImageUniforms] = {
}; };
static const char* kGradientSkSL = static const char* kImageName = "image_shader";
// TODO: This should use local coords
"float2 pos = sk_FragCoord.xy;\n"
"float2 delta = point1 - point0;\n"
"float2 pt = pos - point0;\n"
"float t = dot(pt, delta) / dot(delta, delta);\n"
"float4 result = colors[0];\n"
"result = mix(result, colors[1],\n"
" clamp((t-offsets[0])/(offsets[1]-offsets[0]),\n"
" 0, 1));\n"
"result = mix(result, colors[2],\n"
" clamp((t-offsets[1])/(offsets[2]-offsets[1]),\n"
" 0, 1));\n"
"result = mix(result, colors[3],\n"
" clamp((t-offsets[2])/(offsets[3]-offsets[2]),\n"
" 0, 1));\n"
"outColor = half4(result);\n";
static const char* kSolidColorSkSL = " outColor = half4(color);\n";
static const char* kImageSkSL = static const char* kImageSkSL =
"half4 image_shader() {\n"
" float r = fract(abs(sk_FragCoord.x/10.0));\n" " float r = fract(abs(sk_FragCoord.x/10.0));\n"
" outColor = half4(r, 0.0, 0.0, 1.0);\n"; " return half4(r, 0.0, 0.0, 1.0);\n"
"}\n";
//--------------------------------------------------------------------------------------------------
// TODO: kNone is for depth-only draws, so should actually have a fragment output type // TODO: kNone is for depth-only draws, so should actually have a fragment output type
// that only defines a [[depth]] attribute but no color calculation. // that only defines a [[depth]] attribute but no color calculation.
static const char* kNoneName = "none";
static const char* kNoneSkSL = "outColor = half4(0.0, 0.0, 1.0, 1.0);\n"; static const char* kNoneSkSL = "outColor = half4(0.0, 0.0, 1.0, 1.0);\n";
} // anonymous namespace } // anonymous namespace
@ -110,21 +125,25 @@ SkSpan<const SkUniform> GetUniforms(CodeSnippetID snippetID) {
} }
} }
const char* GetShaderSkSL(CodeSnippetID snippetID) { // TODO: move this to the dictionary
std::tuple<const char*, const char*> GetShaderSkSL(CodeSnippetID snippetID) {
switch (snippetID) { switch (snippetID) {
case CodeSnippetID::kDepthStencilOnlyDraw: case CodeSnippetID::kDepthStencilOnlyDraw:
return kNoneSkSL; return { kNoneName, kNoneSkSL};
case CodeSnippetID::kLinearGradientShader: [[fallthrough]]; case CodeSnippetID::kLinearGradientShader: [[fallthrough]];
case CodeSnippetID::kRadialGradientShader: [[fallthrough]]; case CodeSnippetID::kRadialGradientShader: [[fallthrough]];
case CodeSnippetID::kSweepGradientShader: [[fallthrough]]; case CodeSnippetID::kSweepGradientShader: [[fallthrough]];
case CodeSnippetID::kConicalGradientShader: case CodeSnippetID::kConicalGradientShader:
return kGradientSkSL; return { kLinearGradient4Name, kLinearGradient4SkSL };
case CodeSnippetID::kImageShader: case CodeSnippetID::kImageShader:
return kImageSkSL; return { kImageName, kImageSkSL };
case CodeSnippetID::kSolidColorShader: [[fallthrough]]; case CodeSnippetID::kSolidColorShader: [[fallthrough]];
default: default:
return kSolidColorSkSL; return { kSolidColorName, kSolidColorSkSL };
} }
} }
} // namespace skgpu } // namespace skgpu

View File

@ -32,7 +32,7 @@ SkSpan<const SkUniform> GetUniforms(CodeSnippetID);
// embedded in the fragment function's body. It has access to the vertex output via a "interpolated" // embedded in the fragment function's body. It has access to the vertex output via a "interpolated"
// variable, and must have a statement that writes to a float4 "out.color". Its uniforms (as defined // variable, and must have a statement that writes to a float4 "out.color". Its uniforms (as defined
// by GetUniforms(type)) are available as a variable named "uniforms". // by GetUniforms(type)) are available as a variable named "uniforms".
const char* GetShaderSkSL(CodeSnippetID); std::tuple<const char*, const char*> GetShaderSkSL(CodeSnippetID);
} // namespace skgpu } // namespace skgpu

View File

@ -197,10 +197,13 @@ std::string get_sksl_fs(const SkShaderCodeDictionary* dictionary,
sksl += emit_SKSL_uniforms(2, "FS", paintUniforms); sksl += emit_SKSL_uniforms(2, "FS", paintUniforms);
} }
auto [name, code] = GetShaderSkSL(codeSnippetID);
sksl += code;
sksl += "layout(location = 0, index = 0) out half4 sk_FragColor;\n"; sksl += "layout(location = 0, index = 0) out half4 sk_FragColor;\n";
sksl += "void main() {\n" sksl += "void main() {\n"
" half4 outColor;\n"; " half4 outColor;\n";
sksl += GetShaderSkSL(codeSnippetID); SkSL::String::appendf(&sksl, "outColor = %s();\n", name);
sksl += " sk_FragColor = outColor;\n" sksl += " sk_FragColor = outColor;\n"
"}\n"; "}\n";