Plumb the full dst color info through color filters in SkVM

Used in https://skia-review.googlesource.com/c/skia/+/406296
to evaluate shaders (as children of color filters) correctly.

Change-Id: I2337b062da3fded9e61efe21c6cf74ef08a56753
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/416998
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2021-06-09 09:46:10 -04:00 committed by Skia Commit-Bot
parent 9173b3ff9a
commit 61c7888dfa
11 changed files with 28 additions and 27 deletions

View File

@ -64,10 +64,10 @@ bool SkColorFilterBase::appendStages(const SkStageRec& rec, bool shaderIsOpaque)
}
skvm::Color SkColorFilterBase::program(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
const SkColorInfo& dst,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const {
skvm::F32 original = c.a;
if ((c = this->onProgram(p,c, dstCS, uniforms,alloc))) {
if ((c = this->onProgram(p,c, dst, uniforms,alloc))) {
if (this->isAlphaUnchanged()) {
c.a = original;
}
@ -116,8 +116,9 @@ SkPMColor4f SkColorFilterBase::onFilterColor4f(const SkPMColor4f& color,
skvm::Builder b;
skvm::Uniforms uni(b.uniform(), 4);
SkColor4f uniColor = {color.fR, color.fG, color.fB, color.fA};
SkColorInfo dstInfo = {kRGBA_F32_SkColorType, kPremul_SkAlphaType, sk_ref_sp(dstCS)};
if (skvm::Color filtered =
as_CFB(this)->program(&b, b.uniformColor(uniColor, &uni), dstCS, &uni, &alloc)) {
as_CFB(this)->program(&b, b.uniformColor(uniColor, &uni), dstInfo, &uni, &alloc)) {
b.store({skvm::PixelFormat::FLOAT, 32,32,32,32, 0,32,64,96},
b.varying<SkColor4f>(), filtered);
@ -150,10 +151,10 @@ public:
}
skvm::Color onProgram(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
const SkColorInfo& dst,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override {
c = fInner->program(p, c, dstCS, uniforms, alloc);
return c ? fOuter->program(p, c, dstCS, uniforms, alloc) : skvm::Color{};
c = fInner->program(p, c, dst, uniforms, alloc);
return c ? fOuter->program(p, c, dst, uniforms, alloc) : skvm::Color{};
}
#if SK_SUPPORT_GPU
@ -271,7 +272,7 @@ public:
return true;
}
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, SkColorSpace* dstCS,
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, const SkColorInfo& dst,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override {
return premul(fSteps.program(p, uniforms, unpremul(c)));
}
@ -364,19 +365,19 @@ struct SkWorkingFormatColorFilter : public SkColorFilterBase {
bool onAppendStages(const SkStageRec&, bool) const override { return false; }
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, SkColorSpace* rawDstCS,
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, const SkColorInfo& rawDst,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override {
sk_sp<SkColorSpace> dstCS = sk_ref_sp(rawDstCS);
sk_sp<SkColorSpace> dstCS = rawDst.refColorSpace();
if (!dstCS) { dstCS = SkColorSpace::MakeSRGB(); }
SkAlphaType workingAT;
sk_sp<SkColorSpace> workingCS = this->workingFormat(dstCS, &workingAT);
SkColorInfo dst = {kUnknown_SkColorType, kPremul_SkAlphaType, dstCS},
working = {kUnknown_SkColorType, workingAT, workingCS};
SkColorInfo dst = {rawDst.colorType(), rawDst.alphaType(), dstCS},
working = {rawDst.colorType(), workingAT, workingCS};
c = SkColorSpaceXformSteps{dst,working}.program(p, uniforms, c);
c = as_CFB(fChild)->program(p, c, working.colorSpace(), uniforms, alloc);
c = as_CFB(fChild)->program(p, c, working, uniforms, alloc);
return c ? SkColorSpaceXformSteps{working,dst}.program(p, uniforms, c)
: c;
}

View File

@ -28,7 +28,7 @@ public:
SK_WARN_UNUSED_RESULT
skvm::Color program(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS, skvm::Uniforms*, SkArenaAlloc*) const;
const SkColorInfo& dst, skvm::Uniforms*, SkArenaAlloc*) const;
/** Returns the flags for this filter. Override in subclasses to return custom flags.
*/
@ -82,7 +82,7 @@ private:
virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0;
virtual skvm::Color onProgram(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS, skvm::Uniforms*, SkArenaAlloc*) const = 0;
const SkColorInfo& dst, skvm::Uniforms*, SkArenaAlloc*) const = 0;
friend class SkColorFilter;

View File

@ -79,7 +79,7 @@ bool SkColorFilter_Matrix::onAppendStages(const SkStageRec& rec, bool shaderIsOp
skvm::Color SkColorFilter_Matrix::onProgram(skvm::Builder* p, skvm::Color c,
SkColorSpace* /*dstCS*/,
const SkColorInfo& /*dst*/,
skvm::Uniforms* uniforms, SkArenaAlloc*) const {
auto apply_matrix = [&](auto xyzw) {
auto dot = [&](int j) {

View File

@ -33,7 +33,7 @@ private:
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override;
skvm::Color onProgram(skvm::Builder*, skvm::Color,
SkColorSpace* dstCS,
const SkColorInfo& dst,
skvm::Uniforms* uniforms, SkArenaAlloc*) const override;
float fMatrix[20];

View File

@ -71,11 +71,11 @@ bool SkModeColorFilter::onAppendStages(const SkStageRec& rec, bool shaderIsOpaqu
}
skvm::Color SkModeColorFilter::onProgram(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
const SkColorInfo& dstInfo,
skvm::Uniforms* uniforms, SkArenaAlloc*) const {
SkColor4f color = SkColor4f::FromColor(fColor);
SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
dstCS, kPremul_SkAlphaType).apply(color.vec());
SkColorSpaceXformSteps( sk_srgb_singleton(), kUnpremul_SkAlphaType,
dstInfo.colorSpace(), kPremul_SkAlphaType).apply(color.vec());
skvm::Color dst = c,
src = p->uniformColor(color, uniforms);
return p->blend(fMode, src,dst);

View File

@ -33,7 +33,7 @@ protected:
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override;
skvm::Color onProgram(skvm::Builder*, skvm::Color,
SkColorSpace*, skvm::Uniforms*, SkArenaAlloc*) const override;
const SkColorInfo&, skvm::Uniforms*, SkArenaAlloc*) const override;
private:
SkColor fColor;

View File

@ -649,9 +649,9 @@ public:
}
skvm::Color onProgram(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
const SkColorInfo& dst,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override {
sk_sp<SkData> inputs = get_xformed_uniforms(fEffect.get(), fUniforms, dstCS);
sk_sp<SkData> inputs = get_xformed_uniforms(fEffect.get(), fUniforms, dst.colorSpace());
SkASSERT(inputs);
// There should be no way for the color filter to use device coords, but we need to supply
@ -660,7 +660,7 @@ public:
auto sampleChild = [&](int ix, skvm::Coord /*coord*/, skvm::Color color) {
if (fChildren[ix]) {
return as_CFB(fChildren[ix])->program(p, color, dstCS, uniforms, alloc);
return as_CFB(fChildren[ix])->program(p, color, dst, uniforms, alloc);
} else {
return color;
}

View File

@ -324,7 +324,7 @@ namespace {
struct NoopColorFilter : public SkColorFilterBase {
skvm::Color onProgram(skvm::Builder*, skvm::Color c,
SkColorSpace*, skvm::Uniforms*, SkArenaAlloc*) const override {
const SkColorInfo&, skvm::Uniforms*, SkArenaAlloc*) const override {
return c;
}

View File

@ -63,7 +63,7 @@ public:
}
skvm::Color onProgram(skvm::Builder* p, skvm::Color c,
SkColorSpace* dstCS,
const SkColorInfo& dst,
skvm::Uniforms* uniforms, SkArenaAlloc*) const override {
auto apply_table_to_component = [&](skvm::F32 c, const uint8_t* bytePtr) -> skvm::F32 {

View File

@ -84,7 +84,7 @@ skvm::Color SkColorFilterShader::onProgram(skvm::Builder* p,
}
// Finally run that through the color filter.
return fFilter->program(p,c, dst.colorSpace(), uniforms,alloc);
return fFilter->program(p,c, dst, uniforms,alloc);
}
#if SK_SUPPORT_GPU

View File

@ -59,7 +59,7 @@ protected:
return true;
}
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, SkColorSpace* dstCS, skvm::Uniforms*,
skvm::Color onProgram(skvm::Builder* p, skvm::Color c, const SkColorInfo& dst, skvm::Uniforms*,
SkArenaAlloc*) const override {
// x = 1 - x;
// exp(-x * x * 4) - 0.018f;