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;
struct F32;
struct Uniforms;
struct Color;
}
/**
@ -62,10 +63,8 @@ public:
bool appendStages(const SkStageRec& rec, bool shaderIsOpaque) const;
bool program(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
skvm::Color program(skvm::Builder*, SkColorSpace* dstCS, skvm::Uniforms*,
SkArenaAlloc*, skvm::Color) const;
enum Flags {
/** 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 onProgram(skvm::Builder*,
SkColorSpace* dstCS,
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
virtual skvm::Color onProgram(skvm::Builder*, SkColorSpace* dstCS, skvm::Uniforms*,
SkArenaAlloc*, skvm::Color) const;
friend class SkComposeColorFilter;

View File

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

View File

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

View File

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

View File

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

View File

@ -123,8 +123,8 @@ public:
return true;
}
bool onProgram(skvm::Builder* p, SkColorSpace* dstCS, skvm::Uniforms* uniforms, SkArenaAlloc*,
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override {
skvm::Color onProgram(skvm::Builder* p, SkColorSpace* dstCS, skvm::Uniforms* uniforms,
SkArenaAlloc*, skvm::Color c) const override {
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));
@ -135,27 +135,25 @@ public:
return p->from_unorm(8, byte);
};
p->unpremul(r,g,b,*a);
c = p->unpremul(c);
const uint8_t* ptr = fStorage;
if (fFlags & kA_Flag) {
*a = apply_table_to_component(*a, ptr);
c.a = apply_table_to_component(c.a, ptr);
ptr += 256;
}
if (fFlags & kR_Flag) {
*r = apply_table_to_component(*r, ptr);
c.r = apply_table_to_component(c.r, ptr);
ptr += 256;
}
if (fFlags & kG_Flag) {
*g = apply_table_to_component(*g, ptr);
c.g = apply_table_to_component(c.g, ptr);
ptr += 256;
}
if (fFlags & kB_Flag) {
*b = apply_table_to_component(*b, ptr);
c.b = apply_table_to_component(c.b, ptr);
}
p->premul(r,g,b,*a);
return true;
return p->premul(c);
}
protected:

View File

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