[graphite] Suppress alpha-only image shader logic via runtime effects
This makes results consistent with Ganesh and CPU, where
alpha-only images produce {0,0,0,a} when sampled in raw
mode, or from runtime effects.
Change-Id: I48d1912c4a745cffd8081b3299eff129f56cb3bf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/759516
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/graphite/KeyContext.h b/src/gpu/graphite/KeyContext.h
index 478b70b..8d58ce9 100644
--- a/src/gpu/graphite/KeyContext.h
+++ b/src/gpu/graphite/KeyContext.h
@@ -71,6 +71,13 @@
const SkPMColor4f& paintColor() const { return fPaintColor; }
+ enum class Scope {
+ kDefault,
+ kRuntimeEffect,
+ };
+
+ Scope scope() const { return fScope; }
+
protected:
Recorder* fRecorder = nullptr;
SkM44 fLocal2Dev;
@@ -79,6 +86,7 @@
RuntimeEffectDictionary* fRTEffectDict;
SkColorInfo fDstColorInfo;
SkPMColor4f fPaintColor = SK_PMColor4fBLACK;
+ Scope fScope = Scope::kDefault;
private:
const Caps* fCaps = nullptr;
@@ -119,6 +127,17 @@
KeyContextWithColorInfo& operator=(const KeyContextWithColorInfo&) = delete;
};
+class KeyContextWithScope : public KeyContext {
+public:
+ KeyContextWithScope(const KeyContext& other, KeyContext::Scope scope) : KeyContext(other) {
+ fScope = scope;
+ }
+
+private:
+ KeyContextWithScope(const KeyContextWithScope&) = delete;
+ KeyContextWithScope& operator=(const KeyContextWithScope&) = delete;
+};
+
} // namespace skgpu::graphite
#endif // skgpu_graphite_KeyContext_DEFINED
diff --git a/src/gpu/graphite/KeyHelpers.cpp b/src/gpu/graphite/KeyHelpers.cpp
index 9436b58..a0c9553 100644
--- a/src/gpu/graphite/KeyHelpers.cpp
+++ b/src/gpu/graphite/KeyHelpers.cpp
@@ -1009,34 +1009,37 @@
using ChildType = SkRuntimeEffect::ChildType;
+ KeyContextWithScope childContext(keyContext, KeyContext::Scope::kRuntimeEffect);
+
for (size_t index = 0; index < children.size(); ++index) {
const SkRuntimeEffect::ChildPtr& child = children[index];
std::optional<ChildType> type = child.type();
if (type == ChildType::kShader) {
- AddToKey(keyContext, builder, gatherer, child.shader());
+ AddToKey(childContext, builder, gatherer, child.shader());
} else if (type == ChildType::kColorFilter) {
- AddToKey(keyContext, builder, gatherer, child.colorFilter());
+ AddToKey(childContext, builder, gatherer, child.colorFilter());
} else if (type == ChildType::kBlender) {
- AddToKey(keyContext, builder, gatherer, child.blender());
+ AddToKey(childContext, builder, gatherer, child.blender());
} else {
// We don't have a child effect. Substitute in a no-op effect.
switch (childInfo[index].type) {
case ChildType::kShader:
// A missing shader returns transparent black
- SolidColorShaderBlock::BeginBlock(keyContext, builder, gatherer, {0, 0, 0, 0});
+ SolidColorShaderBlock::BeginBlock(
+ childContext, builder, gatherer, {0, 0, 0, 0});
builder->endBlock();
break;
case ChildType::kColorFilter:
// A "passthrough" color filter returns the input color as-is.
- PriorOutputBlock::BeginBlock(keyContext, builder, gatherer);
+ PriorOutputBlock::BeginBlock(childContext, builder, gatherer);
builder->endBlock();
break;
case ChildType::kBlender:
// A "passthrough" blender performs `blend_src_over(src, dest)`.
BlendModeBlenderBlock::BeginBlock(
- keyContext, builder, gatherer, SkBlendMode::kSrcOver);
+ childContext, builder, gatherer, SkBlendMode::kSrcOver);
builder->endBlock();
break;
}
@@ -1481,7 +1484,7 @@
skgpu::Swizzle readSwizzle = view.swizzle();
// If the color type is alpha-only, propagate the alpha value to the other channels.
if (imageToDraw->isAlphaOnly()) {
- readSwizzle = skgpu::Swizzle::Concat(readSwizzle, skgpu::Swizzle("aaaa"));
+ readSwizzle = skgpu::Swizzle::Concat(readSwizzle, skgpu::Swizzle("000a"));
}
imgData.fReadSwizzle = swizzle_class_to_read_enum(readSwizzle);
@@ -1500,7 +1503,7 @@
keyContext.dstColorInfo().colorSpace(),
keyContext.dstColorInfo().alphaType());
- if (imageToDraw->isAlphaOnly()) {
+ if (imageToDraw->isAlphaOnly() && keyContext.scope() != KeyContext::Scope::kRuntimeEffect) {
Blend(keyContext, builder, gatherer,
/* addBlendToKey= */ [&] () -> void {
AddKnownModeBlend(keyContext, builder, gatherer, SkBlendMode::kDstIn);