SkColorFilter::onProgram()

Before we write too many of these, let's get a program() / onProgram()
wrapper in place for SkColorFilter.  When a filter claims it doesn't
change alpha, we can skip any work it might do to "calculate" that
unchanged alpha (e.g. 0*r + 0*g + 0*b + 1*a + 0) and instead just
save and restore the orignal alpha.

SkShader already has this same program() / onProgram() setup, and uses
it similarly to force any shader that claims to be opaque to be opaque,
replacing any math (or sometimes even memory loads) that shader may have
done to produce alpha with a simple splat(1.0f).

Change-Id: Ica916926506df3a48b4d718545ea64dd95b457af
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/261134
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2019-12-19 14:18:35 -06:00 committed by Skia Commit-Bot
parent 87e9ddb675
commit 7e2dea5682
4 changed files with 32 additions and 13 deletions

View File

@ -61,10 +61,10 @@ public:
bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const;
virtual bool program(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
bool program(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
enum Flags {
/** If set the filter methods will not change the alpha channel of the colors.
@ -148,6 +148,11 @@ private:
virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0;
virtual bool onProgram(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
friend class SkComposeColorFilter;
typedef SkFlattenable INHERITED;

View File

@ -45,10 +45,24 @@ bool SkColorFilter::appendStages(const SkStageRec& rec, bool shaderIsOpaque) con
return this->onAppendStages(rec, shaderIsOpaque);
}
bool SkColorFilter::program(skvm::Builder*,
bool SkColorFilter::program(skvm::Builder* p,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
skvm::F32 original = *a;
if (this->onProgram(p, dstCS, uniforms, r,g,b,a)) {
if (this->getFlags() & kAlphaUnchanged_Flag) {
*a = original;
}
return true;
}
return false;
}
bool SkColorFilter::onProgram(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
return false;
}

View File

@ -79,10 +79,10 @@ bool SkColorFilter_Matrix::onAppendStages(const SkStageRec& rec, bool shaderIsOp
return true;
}
bool SkColorFilter_Matrix::program(skvm::Builder* p,
SkColorSpace* /*dstCS*/,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
bool SkColorFilter_Matrix::onProgram(skvm::Builder* p,
SkColorSpace* /*dstCS*/,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
// TODO: specialize generated code on the 0/1 values of fMatrix?
if (fDomain == Domain::kRGBA) {
// Unpremul.

View File

@ -33,10 +33,10 @@ private:
SK_FLATTENABLE_HOOKS(SkColorFilter_Matrix)
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override;
bool program(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override;
bool onProgram(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override;
float fMatrix[20];
uint16_t fFlags;