colorfilter's program returns a color

Change-Id: I4fd4b7b2c18327f484119d4977ff362602679ffe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/277063
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Reed 2020-03-15 08:54:03 -04:00
parent 6352f00c59
commit 7e0a7dbd22
7 changed files with 40 additions and 62 deletions

View File

@ -26,6 +26,7 @@ namespace skvm {
class Builder; class Builder;
struct F32; struct F32;
struct Uniforms; struct Uniforms;
struct Color;
} }
/** /**
@ -62,10 +63,8 @@ public:
bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const; bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const;
bool program(skvm::Builder*, skvm::Color program(skvm::Builder*, SkColorSpace* dstCS, skvm::Uniforms*,
SkColorSpace* dstCS, SkArenaAlloc*, skvm::Color) const;
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
enum Flags { enum Flags {
/** If set the filter methods will not change the alpha channel of the colors. /** If set the filter methods will not change the alpha channel of the colors.
@ -149,10 +148,8 @@ private:
virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0; virtual bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const = 0;
virtual bool onProgram(skvm::Builder*, virtual skvm::Color onProgram(skvm::Builder*, SkColorSpace* dstCS, skvm::Uniforms*,
SkColorSpace* dstCS, SkArenaAlloc*, skvm::Color) const;
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
friend class SkComposeColorFilter; friend class SkComposeColorFilter;

View File

@ -43,26 +43,22 @@ bool SkColorFilter::appendStages(const SkStageRec& rec, bool shaderIsOpaque) con
return this->onAppendStages(rec, shaderIsOpaque); return this->onAppendStages(rec, shaderIsOpaque);
} }
bool SkColorFilter::program(skvm::Builder* p, skvm::Color SkColorFilter::program(skvm::Builder* p, SkColorSpace* dstCS, skvm::Uniforms* uniforms,
SkColorSpace* dstCS, SkArenaAlloc* alloc, skvm::Color c) const {
skvm::Uniforms* uniforms, SkArenaAlloc* alloc, skvm::F32 original = c.a;
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const { if ((c = this->onProgram(p, dstCS, uniforms,alloc, c))) {
skvm::F32 original = *a;
if (this->onProgram(p, dstCS, uniforms,alloc, r,g,b,a)) {
if (this->getFlags() & kAlphaUnchanged_Flag) { if (this->getFlags() & kAlphaUnchanged_Flag) {
*a = original; c.a = original;
} }
return true; return c;
} }
return false; return {};
} }
bool SkColorFilter::onProgram(skvm::Builder*, skvm::Color SkColorFilter::onProgram(skvm::Builder*, SkColorSpace*, skvm::Uniforms*,
SkColorSpace* dstCS, SkArenaAlloc*, skvm::Color) const {
skvm::Uniforms* uniforms, SkArenaAlloc*,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
//SkDebugf("cannot onProgram %s\n", this->getTypeName()); //SkDebugf("cannot onProgram %s\n", this->getTypeName());
return false; return {};
} }
SkColor SkColorFilter::filterColor(SkColor c) const { SkColor SkColorFilter::filterColor(SkColor c) const {

View File

@ -80,33 +80,27 @@ bool SkColorFilter_Matrix::onAppendStages(const SkStageRec& rec, bool shaderIsOp
return true; return true;
} }
bool SkColorFilter_Matrix::onProgram(skvm::Builder* p, skvm::Color SkColorFilter_Matrix::onProgram(skvm::Builder* p,
SkColorSpace* /*dstCS*/, SkColorSpace* /*dstCS*/,
skvm::Uniforms* uniforms, SkArenaAlloc*, skvm::Uniforms* uniforms, SkArenaAlloc*,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const { skvm::Color c) const {
// TODO: specialize generated code on the 0/1 values of fMatrix? // TODO: specialize generated code on the 0/1 values of fMatrix?
if (fDomain == Domain::kRGBA) { if (fDomain == Domain::kRGBA) {
p->unpremul(r,g,b,*a); c = p->unpremul(c);
auto m = [&](int i) { return p->uniformF(uniforms->pushF(fMatrix[i])); }; auto m = [&](int i) { return p->uniformF(uniforms->pushF(fMatrix[i])); };
skvm::F32 rgba[4]; skvm::F32 rgba[4];
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
rgba[j] = m(4+j*5); rgba[j] = m(4+j*5);
rgba[j] = p->mad(m(3+j*5), *a, rgba[j]); rgba[j] = p->mad(m(3+j*5), c.a, rgba[j]);
rgba[j] = p->mad(m(2+j*5), *b, rgba[j]); rgba[j] = p->mad(m(2+j*5), c.b, rgba[j]);
rgba[j] = p->mad(m(1+j*5), *g, rgba[j]); rgba[j] = p->mad(m(1+j*5), c.g, rgba[j]);
rgba[j] = p->mad(m(0+j*5), *r, rgba[j]); rgba[j] = p->mad(m(0+j*5), c.r, rgba[j]);
} }
*r = rgba[0]; return p->premul({rgba[0], rgba[1], rgba[2], rgba[3]});
*g = rgba[1];
*b = rgba[2];
*a = rgba[3];
p->premul(r,g,b,*a);
return true;
} }
return false; return {};
} }
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU

View File

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

View File

@ -399,11 +399,9 @@ namespace {
}; };
struct NoopColorFilter : public SkColorFilter { struct NoopColorFilter : public SkColorFilter {
bool onProgram(skvm::Builder*, skvm::Color onProgram(skvm::Builder*, SkColorSpace*, skvm::Uniforms*,
SkColorSpace*, SkArenaAlloc*, skvm::Color c) const override {
skvm::Uniforms*, SkArenaAlloc*, return c;
skvm::F32*, skvm::F32*, skvm::F32*, skvm::F32*) const override {
return true;
} }
bool onAppendStages(const SkStageRec&, bool) const override { return true; } bool onAppendStages(const SkStageRec&, bool) const override { return true; }

View File

@ -123,8 +123,8 @@ public:
return true; return true;
} }
bool onProgram(skvm::Builder* p, SkColorSpace* dstCS, skvm::Uniforms* uniforms, SkArenaAlloc*, skvm::Color onProgram(skvm::Builder* p, SkColorSpace* dstCS, skvm::Uniforms* uniforms,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override { SkArenaAlloc*, skvm::Color c) const override {
auto apply_table_to_component = [&](skvm::F32 c, const uint8_t* bytePtr) -> skvm::F32 { auto apply_table_to_component = [&](skvm::F32 c, const uint8_t* bytePtr) -> skvm::F32 {
c = p->clamp(c, p->splat(0.f), p->splat(1.0f)); c = p->clamp(c, p->splat(0.f), p->splat(1.0f));
@ -135,27 +135,25 @@ public:
return p->from_unorm(8, byte); return p->from_unorm(8, byte);
}; };
p->unpremul(r,g,b,*a); c = p->unpremul(c);
const uint8_t* ptr = fStorage; const uint8_t* ptr = fStorage;
if (fFlags & kA_Flag) { if (fFlags & kA_Flag) {
*a = apply_table_to_component(*a, ptr); c.a = apply_table_to_component(c.a, ptr);
ptr += 256; ptr += 256;
} }
if (fFlags & kR_Flag) { if (fFlags & kR_Flag) {
*r = apply_table_to_component(*r, ptr); c.r = apply_table_to_component(c.r, ptr);
ptr += 256; ptr += 256;
} }
if (fFlags & kG_Flag) { if (fFlags & kG_Flag) {
*g = apply_table_to_component(*g, ptr); c.g = apply_table_to_component(c.g, ptr);
ptr += 256; ptr += 256;
} }
if (fFlags & kB_Flag) { if (fFlags & kB_Flag) {
*b = apply_table_to_component(*b, ptr); c.b = apply_table_to_component(c.b, ptr);
} }
return p->premul(c);
p->premul(r,g,b,*a);
return true;
} }
protected: protected:

View File

@ -81,10 +81,7 @@ skvm::Color SkColorFilterShader::onProgram(skvm::Builder* p,
} }
// Finally run that through the color filter. // Finally run that through the color filter.
if (fFilter->program(p, dstCS, uniforms,alloc, &c.r,&c.g,&c.b,&c.a)) { return fFilter->program(p, dstCS, uniforms,alloc, c);
return c;
}
return {};
} }
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU