[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 {
//--------------------------------------------------------------------------------------------------
// TODO: For the sprint we unify all the gradient uniforms into a standard set of 6:
// kMaxStops colors
// kMaxStops offsets
@ -32,49 +33,63 @@ namespace {
// 2 radii
static constexpr int kNumGradientUniforms = 6;
static constexpr SkUniform kGradientUniforms[kNumGradientUniforms] = {
{"colors", SkSLType::kHalf4, GradientData::kMaxStops },
{"offsets", SkSLType::kFloat, GradientData::kMaxStops },
{"point0", SkSLType::kFloat2 },
{"point1", SkSLType::kFloat2 },
{"radius0", SkSLType::kFloat },
{"radius1", SkSLType::kFloat },
{ "colors", SkSLType::kHalf4, GradientData::kMaxStops },
{ "offsets", SkSLType::kFloat, GradientData::kMaxStops },
{ "point0", SkSLType::kFloat2 },
{ "point1", SkSLType::kFloat2 },
{ "radius0", 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 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 SkUniform kImageUniforms[kNumImageUniforms] = {
};
static const char* kGradientSkSL =
// 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* kImageName = "image_shader";
static const char* kImageSkSL =
"half4 image_shader() {\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
// 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";
} // 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) {
case CodeSnippetID::kDepthStencilOnlyDraw:
return kNoneSkSL;
return { kNoneName, kNoneSkSL};
case CodeSnippetID::kLinearGradientShader: [[fallthrough]];
case CodeSnippetID::kRadialGradientShader: [[fallthrough]];
case CodeSnippetID::kSweepGradientShader: [[fallthrough]];
case CodeSnippetID::kConicalGradientShader:
return kGradientSkSL;
return { kLinearGradient4Name, kLinearGradient4SkSL };
case CodeSnippetID::kImageShader:
return kImageSkSL;
return { kImageName, kImageSkSL };
case CodeSnippetID::kSolidColorShader: [[fallthrough]];
default:
return kSolidColorSkSL;
return { kSolidColorName, kSolidColorSkSL };
}
}
} // 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"
// 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".
const char* GetShaderSkSL(CodeSnippetID);
std::tuple<const char*, const char*> GetShaderSkSL(CodeSnippetID);
} // namespace skgpu

View File

@ -197,10 +197,13 @@ std::string get_sksl_fs(const SkShaderCodeDictionary* dictionary,
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 += "void main() {\n"
" half4 outColor;\n";
sksl += GetShaderSkSL(codeSnippetID);
SkSL::String::appendf(&sksl, "outColor = %s();\n", name);
sksl += " sk_FragColor = outColor;\n"
"}\n";