Add additional boilerplate for Graphite RuntimeShader.

We continue to draw a solid magenta placeholder, but we now use a
RuntimeShaderBlock and dedicated RuntimeShader code-snippet to do it.
We no longer use the SolidColor shader or data structures.

Change-Id: Ib5a707596dda593c515f4da5eabd4f6b5efd889c
Bug: skia:13405
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/548836
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
John Stiles 2022-06-10 14:18:07 -04:00 committed by SkCQ
parent dbcc328fb0
commit 4804c02ae9
7 changed files with 1746 additions and 1629 deletions

View File

@ -31,6 +31,7 @@ enum class SkBuiltInCodeSnippetID : uint8_t {
kLocalMatrixShader, kLocalMatrixShader,
kImageShader, kImageShader,
kBlendShader, // aka ComposeShader kBlendShader, // aka ComposeShader
kRuntimeShader,
// BlendMode code snippets // BlendMode code snippets
kFixedFunctionBlender, kFixedFunctionBlender,

View File

@ -8,10 +8,13 @@
#include "src/core/SkKeyHelpers.h" #include "src/core/SkKeyHelpers.h"
#include "include/core/SkCombinationBuilder.h" #include "include/core/SkCombinationBuilder.h"
#include "include/core/SkData.h"
#include "include/effects/SkRuntimeEffect.h"
#include "src/core/SkDebugUtils.h" #include "src/core/SkDebugUtils.h"
#include "src/core/SkKeyContext.h" #include "src/core/SkKeyContext.h"
#include "src/core/SkPaintParamsKey.h" #include "src/core/SkPaintParamsKey.h"
#include "src/core/SkPipelineData.h" #include "src/core/SkPipelineData.h"
#include "src/core/SkRuntimeEffectPriv.h"
#include "src/core/SkShaderCodeDictionary.h" #include "src/core/SkShaderCodeDictionary.h"
#include "src/core/SkUniform.h" #include "src/core/SkUniform.h"
@ -563,6 +566,53 @@ void BlendModeBlock::BeginBlock(const SkKeyContext& keyContext,
} }
} }
RuntimeShaderBlock::ShaderData::ShaderData(sk_sp<const SkRuntimeEffect> effect)
: fEffect(std::move(effect)) {}
RuntimeShaderBlock::ShaderData::ShaderData(sk_sp<const SkRuntimeEffect> effect,
sk_sp<const SkData> uniforms)
: fEffect(std::move(effect))
, fUniforms(std::move(uniforms)) {}
static bool skdata_matches(const SkData* a, const SkData* b) {
// Returns true if both SkData objects hold the same contents, or if they are both null.
// (SkData::equals supports passing null, and returns false.)
return a ? a->equals(b) : (a == b);
}
bool RuntimeShaderBlock::ShaderData::operator==(const ShaderData& rhs) const {
return fEffect == rhs.fEffect &&
skdata_matches(fUniforms.get(), rhs.fUniforms.get());
}
void RuntimeShaderBlock::BeginBlock(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder,
SkPipelineDataGatherer* gatherer,
const ShaderData& shaderData) {
switch (builder->backend()) {
case SkBackend::kGraphite: {
#ifdef SK_GRAPHITE_ENABLED
// TODO(skia:13405): add support for uniforms
// TODO(skia:13405): add support for child effects
if (gatherer) {
[[maybe_unused]] const SkShaderCodeDictionary* dict = keyContext.dict();
VALIDATE_UNIFORMS(gatherer, dict, SkBuiltInCodeSnippetID::kRuntimeShader)
}
// Until we support uniforms here, we don't have much else to do.
builder->beginBlock(SkBuiltInCodeSnippetID::kRuntimeShader);
#endif // SK_GRAPHITE_ENABLED
break;
}
case SkBackend::kSkVM:
case SkBackend::kGanesh:
// TODO: add implementation for other backends
SolidColorShaderBlock::BeginBlock(keyContext, builder, gatherer, kErrorColor);
break;
}
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// TODO: we need to feed the number of stops in the gradients into this method from the // TODO: we need to feed the number of stops in the gradients into this method from the
// combination code // combination code
@ -646,10 +696,17 @@ SkUniquePaintParamsID CreateKey(const SkKeyContext& keyContext,
builder->endBlock(); builder->endBlock();
break; break;
case SkShaderType::kRuntimeShader: case SkShaderType::kRuntimeShader:
// TODO(skia:13405): replace with RuntimeShader-specific data {
SolidColorShaderBlock::BeginBlock(keyContext, builder, nullptr, static sk_sp<SkRuntimeEffect> effect = SkMakeRuntimeEffect(
/* unused */ kErrorColor); SkRuntimeEffect::MakeForShader, R"(
builder->endBlock(); half4 main(float2 coords) {
return half4(coords.xy01);
}
)");
RuntimeShaderBlock::BeginBlock(keyContext, builder, nullptr,
{effect, /*uniforms=*/nullptr});
builder->endBlock();
}
break; break;
} }

View File

@ -21,8 +21,10 @@
enum class SkBackend : uint8_t; enum class SkBackend : uint8_t;
enum class SkShaderType : uint32_t; enum class SkShaderType : uint32_t;
class SkData;
class SkPaintParamsKeyBuilder; class SkPaintParamsKeyBuilder;
class SkPipelineDataGatherer; class SkPipelineDataGatherer;
class SkRuntimeEffect;
class SkUniquePaintParamsID; class SkUniquePaintParamsID;
class SkKeyContext; class SkKeyContext;
@ -165,7 +167,29 @@ struct BlendModeBlock {
SkPaintParamsKeyBuilder*, SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*, SkPipelineDataGatherer*,
SkBlendMode); SkBlendMode);
};
struct RuntimeShaderBlock {
struct ShaderData {
// This ctor is used during pre-compilation when we don't have enough information to
// extract uniform data.
ShaderData(sk_sp<const SkRuntimeEffect> effect);
// This ctor is used when extracting information from PaintParams.
ShaderData(sk_sp<const SkRuntimeEffect> effect, sk_sp<const SkData> uniforms);
bool operator==(const ShaderData& rhs) const;
bool operator!=(const ShaderData& rhs) const { return !(*this == rhs); }
// Runtime shader data.
sk_sp<const SkRuntimeEffect> fEffect;
sk_sp<const SkData> fUniforms;
};
static void BeginBlock(const SkKeyContext&,
SkPaintParamsKeyBuilder*,
SkPipelineDataGatherer*,
const ShaderData&);
}; };
// Bridge between the combinations system and the SkPaintParamsKey // Bridge between the combinations system and the SkPaintParamsKey

View File

@ -1156,9 +1156,7 @@ public:
void addToKey(const SkKeyContext& keyContext, void addToKey(const SkKeyContext& keyContext,
SkPaintParamsKeyBuilder* builder, SkPaintParamsKeyBuilder* builder,
SkPipelineDataGatherer* gatherer) const override { SkPipelineDataGatherer* gatherer) const override {
// TODO(skia:13405): this is currently displaying solid magenta, not our Runtime Shader RuntimeShaderBlock::BeginBlock(keyContext, builder, gatherer, {fEffect, fUniforms});
constexpr SkPMColor4f kRuntimeShaderColor = {1, 0, 1, 1};
SolidColorShaderBlock::BeginBlock(keyContext, builder, gatherer, kRuntimeShaderColor);
builder->endBlock(); builder->endBlock();
} }

View File

@ -538,6 +538,9 @@ static constexpr int kNumBlendShaderChildren = 2;
static constexpr char kBlendShaderName[] = "sk_blend_shader"; static constexpr char kBlendShaderName[] = "sk_blend_shader";
//--------------------------------------------------------------------------------------------------
static constexpr char kRuntimeShaderName[] = "sk_runtime_placeholder";
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
static constexpr char kErrorName[] = "sk_error"; static constexpr char kErrorName[] = "sk_error";
@ -813,6 +816,16 @@ SkShaderCodeDictionary::SkShaderCodeDictionary() {
kNumBlendShaderChildren, kNumBlendShaderChildren,
{ } { }
}; };
fBuiltInCodeSnippets[(int) SkBuiltInCodeSnippetID::kRuntimeShader] = {
"RuntimeShader",
{ }, // no uniforms
SnippetRequirementFlags::kNone,
{ }, // no samplers
kRuntimeShaderName,
GenerateDefaultGlueCode,
kNoChildren,
{ }
};
fBuiltInCodeSnippets[(int) SkBuiltInCodeSnippetID::kFixedFunctionBlender] = { fBuiltInCodeSnippets[(int) SkBuiltInCodeSnippetID::kFixedFunctionBlender] = {
"FixedFunctionBlender", "FixedFunctionBlender",
{ }, // no uniforms { }, // no uniforms

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,11 @@ half4 sk_error() {
return half4(1.0, 0.0, 1.0, 1.0); return half4(1.0, 0.0, 1.0, 1.0);
} }
half4 sk_runtime_placeholder() {
// TODO(skia:13405): remove me when RuntimeShader is implemented
return half4(0.75, 0.0, 1.0, 1.0);
}
half4 sk_solid_shader(float4 colorParam) { half4 sk_solid_shader(float4 colorParam) {
return half4(colorParam); return half4(colorParam);
} }