friendly wrapper to allocate uniforms

This basically wraps up the old `uniforms` and `buf` params
into a new type that has push() and pushF() methods that return
a value you can pass directly to Builder::uniform32() and co.

I think this has uniforms about as streamlined as they can get.

Change-Id: I8f611f91b4a2d7cdb8f05ce0333669d2e3930be8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/252937
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2019-11-05 14:19:58 -06:00 committed by Skia Commit-Bot
parent 23607a9a77
commit 1cc6067757
13 changed files with 105 additions and 81 deletions

View File

@ -30,11 +30,11 @@ struct Fade : public SkShaderBase {
bool onProgram(skvm::Builder* p, bool onProgram(skvm::Builder* p,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override {
if (as_SB(fShader)->program(p, dstCS, if (as_SB(fShader)->program(p, dstCS,
uniforms, buf, uniforms,
x,y, r,g,b,a)) { x,y, r,g,b,a)) {
// In this GM `y` will range over 0-50 and `x` over 50-100. // In this GM `y` will range over 0-50 and `x` over 50-100.
*r = p->to_i32(p->mul(y, p->splat(255/ 50.0f))); *r = p->to_i32(p->mul(y, p->splat(255/ 50.0f)));

View File

@ -12,7 +12,6 @@
#include "include/core/SkColor.h" #include "include/core/SkColor.h"
#include "include/core/SkFlattenable.h" #include "include/core/SkFlattenable.h"
#include "include/core/SkRefCnt.h" #include "include/core/SkRefCnt.h"
#include "include/private/SkTDArray.h"
class GrColorInfo; class GrColorInfo;
class GrFragmentProcessor; class GrFragmentProcessor;
@ -28,6 +27,7 @@ namespace skvm {
struct Arg; struct Arg;
struct I32; struct I32;
struct F32; struct F32;
struct Uniforms;
} }
/** /**
@ -66,7 +66,7 @@ public:
virtual bool program(skvm::Builder*, virtual bool program(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>*, skvm::Uniforms* uniforms,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const; skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const;
enum Flags { enum Flags {

View File

@ -46,7 +46,7 @@ bool SkColorFilter::appendStages(const SkStageRec& rec, bool shaderIsOpaque) con
bool SkColorFilter::program(skvm::Builder*, bool SkColorFilter::program(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
return false; return false;
} }

View File

@ -81,7 +81,7 @@ bool SkColorFilter_Matrix::onAppendStages(const SkStageRec& rec, bool shaderIsOp
bool SkColorFilter_Matrix::program(skvm::Builder* p, bool SkColorFilter_Matrix::program(skvm::Builder* p,
SkColorSpace* /*dstCS*/, SkColorSpace* /*dstCS*/,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) 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) {
@ -99,9 +99,8 @@ bool SkColorFilter_Matrix::program(skvm::Builder* p,
B = p->mul(B, invA); B = p->mul(B, invA);
// Apply matrix. // Apply matrix.
const size_t offset = buf->bytes(); skvm::Builder::Uniform u = uniforms->pushF(fMatrix, 20);
memcpy(buf->append(20), &fMatrix, sizeof(fMatrix)); auto m = [&](int i) { return p->bit_cast(p->uniform32(u.ptr, u.offset + 4*i)); };
auto m = [&](int i) { return p->bit_cast(p->uniform32(uniforms, offset + 4*i)); };
skvm::F32 rgba[4]; skvm::F32 rgba[4];
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {

View File

@ -35,7 +35,7 @@ private:
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override; bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override;
bool program(skvm::Builder*, bool program(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>*, skvm::Uniforms* uniforms,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override; skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override;
float fMatrix[20]; float fMatrix[20];

View File

@ -338,6 +338,14 @@ namespace skvm {
I32 uniform16(Arg ptr, int offset=0); I32 uniform16(Arg ptr, int offset=0);
I32 uniform32(Arg ptr, int offset=0); I32 uniform32(Arg ptr, int offset=0);
struct Uniform {
Arg ptr;
int offset;
};
I32 uniform8 (Uniform u) { return this->uniform8 (u.ptr, u.offset); }
I32 uniform16(Uniform u) { return this->uniform16(u.ptr, u.offset); }
I32 uniform32(Uniform u) { return this->uniform32(u.ptr, u.offset); }
// Load an immediate constant. // Load an immediate constant.
I32 splat(int n); I32 splat(int n);
I32 splat(unsigned u) { return this->splat((int)u); } I32 splat(unsigned u) { return this->splat((int)u); }
@ -473,6 +481,27 @@ namespace skvm {
uint32_t fHash{0}; uint32_t fHash{0};
}; };
// Helper to streamline allocating and working with uniforms.
struct Uniforms {
Arg ptr;
std::vector<int> buf;
explicit Uniforms(int init) : ptr(Arg{0}), buf(init) {}
Builder::Uniform push(const int* vals, int n) {
int offset = sizeof(int)*buf.size();
buf.insert(buf.end(), vals, vals+n);
return {ptr, offset};
}
Builder::Uniform pushF(const float* vals, int n) {
return this->push((const int*)vals, n);
}
Builder::Uniform push (int val) { return this->push (&val, 1); }
Builder::Uniform pushF(float val) { return this->pushF(&val, 1); }
};
using Reg = int; using Reg = int;
class Program { class Program {

View File

@ -17,14 +17,13 @@
namespace { namespace {
// Uniforms set by the Blitter itself, // Uniforms set by the Blitter itself,
// rather than by the Shader, which follow this struct in the buffer. // rather than by the Shader, which follow this struct in the skvm::Uniforms buffer.
struct Uniforms { struct BlitterUniforms {
int right; // First device x + blit run length n, used to get device x coordiate. int right; // First device x + blit run length n, used to get device x coordiate.
int y; // Device y coordiate. int y; // Device y coordiate.
}; };
static_assert(SkIsAlign4(sizeof(Uniforms)), ""); static_assert(SkIsAlign4(sizeof(BlitterUniforms)), "");
static constexpr int kUniformsCount = sizeof(Uniforms) / sizeof(uint32_t); static constexpr int kBlitterUniformsCount = sizeof(BlitterUniforms) / 4;
static SkTDArray<uint32_t> uniforms_init() { return {0,0}; }
enum class Coverage { Full, UniformA8, MaskA8, MaskLCD16, Mask3D }; enum class Coverage { Full, UniformA8, MaskA8, MaskLCD16, Mask3D };
@ -143,20 +142,21 @@ namespace {
} }
// If Builder can't build this program, CacheKey() sets *ok to false. // If Builder can't build this program, CacheKey() sets *ok to false.
static Key CacheKey(const Params& params, SkTDArray<uint32_t>* buf, bool* ok) { static Key CacheKey(const Params& params, skvm::Uniforms* uniforms, bool* ok) {
SkASSERT(params.shader); SkASSERT(params.shader);
uint32_t shaderHash = 0; uint32_t shaderHash = 0;
{ {
const SkShaderBase* shader = as_SB(params.shader); const SkShaderBase* shader = as_SB(params.shader);
skvm::Builder p; skvm::Builder p;
skvm::Arg uniforms = skvm::Arg{0}; skvm::F32 x = p.to_f32(p.sub(p.uniform32(uniforms->ptr,
skvm::F32 x = p.to_f32(p.sub(p.uniform32(uniforms, offsetof(Uniforms, right)), offsetof(BlitterUniforms, right)),
p.index())), p.index())),
y = p.to_f32(p.uniform32(uniforms, offsetof(Uniforms, y))); y = p.to_f32(p.uniform32(uniforms->ptr,
offsetof(BlitterUniforms, y)));
skvm::I32 r,g,b,a; skvm::I32 r,g,b,a;
if (shader->program(&p, if (shader->program(&p,
params.colorSpace.get(), params.colorSpace.get(),
uniforms, buf, uniforms,
x,y, &r,&g,&b,&a)) { x,y, &r,&g,&b,&a)) {
shaderHash = p.hash(); shaderHash = p.hash();
} else { } else {
@ -189,29 +189,29 @@ namespace {
}; };
} }
Builder(const Params& params, SkTDArray<uint32_t>* buf) { Builder(const Params& params, skvm::Uniforms* uniforms) {
#define TODO SkUNREACHABLE #define TODO SkUNREACHABLE
SkDEBUGCODE( // First two arguments are always uniforms and the destination buffer.
bool ok = true; uniforms->ptr = uniform();
SkTDArray<uint32_t> dummy = uniforms_init(); skvm::Arg dst_ptr = arg(SkColorTypeBytesPerPixel(params.colorType));
(void)CacheKey(params, &dummy, &ok); // Other arguments depend on params.coverage:
SkASSERT(ok); // - Full: (no more arguments)
) // - Mask3D: mul varying, add varying, 8-bit coverage varying
skvm::Arg uniforms = uniform(), // - MaskA8: 8-bit coverage varying
dst_ptr = arg(SkColorTypeBytesPerPixel(params.colorType)); // - MaskLCD16: 565 coverage varying
// If coverage is Mask3D there'll next come two varyings for mul and add planes, // - UniformA8: 8-bit coverage uniform
// and then finally if coverage is any Mask?? format, a varying for the mask.
Color src; Color src;
SkASSERT(params.shader); SkASSERT(params.shader);
skvm::F32 x = to_f32(sub(uniform32(uniforms, offsetof(Uniforms, right)), skvm::F32 x = to_f32(sub(uniform32(uniforms->ptr,
offsetof(BlitterUniforms, right)),
index())), index())),
y = to_f32(uniform32(uniforms, offsetof(Uniforms, y))); y = to_f32(uniform32(uniforms->ptr,
offsetof(BlitterUniforms, y)));
SkAssertResult(as_SB(params.shader)->program(this, SkAssertResult(as_SB(params.shader)->program(this,
params.colorSpace.get(), params.colorSpace.get(),
uniforms, buf, uniforms,
x,y, &src.r, &src.g, &src.b, &src.a)); x,y, &src.r, &src.g, &src.b, &src.a));
SkASSERT(buf->size() == dummy.size());
if (params.coverage == Coverage::Mask3D) { if (params.coverage == Coverage::Mask3D) {
skvm::I32 M = load8(varying<uint8_t>()), skvm::I32 M = load8(varying<uint8_t>()),
@ -339,14 +339,13 @@ namespace {
bool onProgram(skvm::Builder* p, bool onProgram(skvm::Builder* p,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override {
if (as_SB(fShader)->program(p, dstCS, if (as_SB(fShader)->program(p, dstCS,
uniforms, buf, uniforms,
x,y, r,g,b,a)) { x,y, r,g,b,a)) {
skvm::I32 A = p->uniform32(uniforms, buf->bytes()); skvm::I32 A = p->uniform32(uniforms->push(fAlpha));
buf->push_back(fAlpha);
*r = p->scale_unorm8(*r, A); *r = p->scale_unorm8(*r, A);
*g = p->scale_unorm8(*g, A); *g = p->scale_unorm8(*g, A);
*b = p->scale_unorm8(*b, A); *b = p->scale_unorm8(*b, A);
@ -406,7 +405,7 @@ namespace {
public: public:
Blitter(const SkPixmap& device, const SkPaint& paint, bool* ok) Blitter(const SkPixmap& device, const SkPaint& paint, bool* ok)
: fDevice(device) : fDevice(device)
, fUniforms(uniforms_init()) , fUniforms(kBlitterUniformsCount)
, fParams(effective_params(device, paint)) , fParams(effective_params(device, paint))
, fKey(Builder::CacheKey(fParams, &fUniforms, ok)) , fKey(Builder::CacheKey(fParams, &fUniforms, ok))
{} {}
@ -434,15 +433,15 @@ namespace {
} }
private: private:
SkPixmap fDevice; // TODO: can this be const&? SkPixmap fDevice; // TODO: can this be const&?
SkTDArray<uint32_t> fUniforms; skvm::Uniforms fUniforms;
const Params fParams; const Params fParams;
const Key fKey; const Key fKey;
skvm::Program fBlitH, skvm::Program fBlitH,
fBlitAntiH, fBlitAntiH,
fBlitMaskA8, fBlitMaskA8,
fBlitMask3D, fBlitMask3D,
fBlitMaskLCD16; fBlitMaskLCD16;
skvm::Program buildProgram(Coverage coverage) { skvm::Program buildProgram(Coverage coverage) {
Key key = fKey.withCoverage(coverage); Key key = fKey.withCoverage(coverage);
@ -468,10 +467,10 @@ namespace {
// It's just more natural to have effects unconditionally emit them, // It's just more natural to have effects unconditionally emit them,
// and more natural to rebuild fUniforms than to emit them into a dummy buffer. // and more natural to rebuild fUniforms than to emit them into a dummy buffer.
// fUniforms should reuse the exact same memory, so this is very cheap. // fUniforms should reuse the exact same memory, so this is very cheap.
SkDEBUGCODE(size_t prev = fUniforms.size();) SkDEBUGCODE(size_t prev = fUniforms.buf.size();)
fUniforms.setCount(kUniformsCount); fUniforms.buf.resize(kBlitterUniformsCount);
Builder builder{fParams.withCoverage(coverage), &fUniforms}; Builder builder{fParams.withCoverage(coverage), &fUniforms};
SkASSERT(fUniforms.size() == prev); SkASSERT(fUniforms.buf.size() == prev);
skvm::Program program = builder.done(debug_name(key).c_str()); skvm::Program program = builder.done(debug_name(key).c_str());
if (!program.hasJIT() && debug_dump(key)) { if (!program.hasJIT() && debug_dump(key)) {
@ -483,8 +482,8 @@ namespace {
} }
void updateUniforms(int right, int y) { void updateUniforms(int right, int y) {
Uniforms uniforms{right, y}; BlitterUniforms uniforms{right, y};
memcpy(fUniforms.begin(), &uniforms, sizeof(Uniforms)); memcpy(fUniforms.buf.data(), &uniforms, sizeof(BlitterUniforms));
} }
void blitH(int x, int y, int w) override { void blitH(int x, int y, int w) override {
@ -492,7 +491,7 @@ namespace {
fBlitH = this->buildProgram(Coverage::Full); fBlitH = this->buildProgram(Coverage::Full);
} }
this->updateUniforms(x+w, y); this->updateUniforms(x+w, y);
fBlitH.eval(w, fUniforms.begin(), fDevice.addr(x,y)); fBlitH.eval(w, fUniforms.buf.data(), fDevice.addr(x,y));
} }
void blitAntiH(int x, int y, const SkAlpha cov[], const int16_t runs[]) override { void blitAntiH(int x, int y, const SkAlpha cov[], const int16_t runs[]) override {
@ -501,7 +500,7 @@ namespace {
} }
for (int16_t run = *runs; run > 0; run = *runs) { for (int16_t run = *runs; run > 0; run = *runs) {
this->updateUniforms(x+run, y); this->updateUniforms(x+run, y);
fBlitAntiH.eval(run, fUniforms.begin(), fDevice.addr(x,y), cov); fBlitAntiH.eval(run, fUniforms.buf.data(), fDevice.addr(x,y), cov);
x += run; x += run;
runs += run; runs += run;
@ -552,11 +551,11 @@ namespace {
if (program == &fBlitMask3D) { if (program == &fBlitMask3D) {
size_t plane = mask.computeImageSize(); size_t plane = mask.computeImageSize();
program->eval(w, fUniforms.begin(), dptr, mptr + 1*plane program->eval(w, fUniforms.buf.data(), dptr, mptr + 1*plane
, mptr + 2*plane , mptr + 2*plane
, mptr + 0*plane); , mptr + 0*plane);
} else { } else {
program->eval(w, fUniforms.begin(), dptr, mptr); program->eval(w, fUniforms.buf.data(), dptr, mptr);
} }
} }
} }

View File

@ -62,18 +62,18 @@ bool SkColorFilterShader::onAppendStages(const SkStageRec& rec) const {
bool SkColorFilterShader::onProgram(skvm::Builder* p, bool SkColorFilterShader::onProgram(skvm::Builder* p,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
// Run the shader. // Run the shader.
if (!as_SB(fShader)->program(p, dstCS, uniforms,buf, x,y, r,g,b,a)) { if (!as_SB(fShader)->program(p, dstCS, uniforms, x,y, r,g,b,a)) {
return false; return false;
} }
// Scale that by alpha. // Scale that by alpha.
if (fAlpha != 1.0f) { if (fAlpha != 1.0f) {
skvm::I32 A = p->uniform32(uniforms, buf->bytes()); int alpha = fAlpha*255 + 0.5f;
buf->push_back(fAlpha*255 + 0.5f); skvm::I32 A = p->uniform32(uniforms->push(alpha));
*r = p->scale_unorm8(*r, A); *r = p->scale_unorm8(*r, A);
*g = p->scale_unorm8(*g, A); *g = p->scale_unorm8(*g, A);
*b = p->scale_unorm8(*b, A); *b = p->scale_unorm8(*b, A);
@ -81,7 +81,7 @@ bool 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,buf, r,g,b,a)) { if (!fFilter->program(p, dstCS, uniforms, r,g,b,a)) {
return false; return false;
} }

View File

@ -28,7 +28,7 @@ private:
bool onProgram(skvm::Builder*, bool onProgram(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>*, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override; skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override;

View File

@ -93,15 +93,13 @@ bool SkColor4Shader::onAppendStages(const SkStageRec& rec) const {
static bool common_program(SkColor4f color, SkColorSpace* cs, static bool common_program(SkColor4f color, SkColorSpace* cs,
skvm::Builder* p, skvm::Builder* p,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) {
SkColorSpaceXformSteps( cs, kUnpremul_SkAlphaType, SkColorSpaceXformSteps( cs, kUnpremul_SkAlphaType,
dstCS, kUnpremul_SkAlphaType).apply(color.vec()); dstCS, kUnpremul_SkAlphaType).apply(color.vec());
if (color.fitsInBytes()) { if (color.fitsInBytes()) {
skvm::I32 rgba = p->uniform32(uniforms, buf->bytes()); skvm::I32 rgba = p->uniform32(uniforms->push(color.premul().toBytes_RGBA()));
buf->push_back(color.premul().toBytes_RGBA());
*r = p->extract(rgba, 0, p->splat(0xff)); *r = p->extract(rgba, 0, p->splat(0xff));
*g = p->extract(rgba, 8, p->splat(0xff)); *g = p->extract(rgba, 8, p->splat(0xff));
*b = p->extract(rgba, 16, p->splat(0xff)); *b = p->extract(rgba, 16, p->splat(0xff));
@ -113,19 +111,19 @@ static bool common_program(SkColor4f color, SkColorSpace* cs,
bool SkColorShader::onProgram(skvm::Builder* p, bool SkColorShader::onProgram(skvm::Builder* p,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 /*x*/, skvm::F32 /*y*/, skvm::F32 /*x*/, skvm::F32 /*y*/,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
return common_program(SkColor4f::FromColor(fColor), sk_srgb_singleton(), return common_program(SkColor4f::FromColor(fColor), sk_srgb_singleton(),
p, dstCS, uniforms,buf, r,g,b,a); p, dstCS, uniforms, r,g,b,a);
} }
bool SkColor4Shader::onProgram(skvm::Builder* p, bool SkColor4Shader::onProgram(skvm::Builder* p,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 /*x*/, skvm::F32 /*y*/, skvm::F32 /*x*/, skvm::F32 /*y*/,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
return common_program(fColor, fColorSpace.get(), return common_program(fColor, fColorSpace.get(),
p, dstCS, uniforms,buf, r,g,b,a); p, dstCS, uniforms, r,g,b,a);
} }
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU

View File

@ -46,7 +46,7 @@ private:
bool onProgram(skvm::Builder*, bool onProgram(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override; skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override;
@ -72,7 +72,7 @@ private:
bool onProgram(skvm::Builder*, bool onProgram(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override; skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override;

View File

@ -194,7 +194,7 @@ bool SkShaderBase::onAppendStages(const SkStageRec& rec) const {
bool SkShaderBase::program(skvm::Builder* p, bool SkShaderBase::program(skvm::Builder* p,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>* buf, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
// Force opaque alpha for all opaque shaders. // Force opaque alpha for all opaque shaders.
@ -209,7 +209,7 @@ bool SkShaderBase::program(skvm::Builder* p,
// shader program hash and blitter Key. This makes it safe for us to use // shader program hash and blitter Key. This makes it safe for us to use
// that bit to make decisions when constructing an SkVMBlitter, like doing // that bit to make decisions when constructing an SkVMBlitter, like doing
// SrcOver -> Src strength reduction. // SrcOver -> Src strength reduction.
if (this->onProgram(p, dstCS, uniforms,buf, x,y, r,g,b,a)) { if (this->onProgram(p, dstCS, uniforms, x,y, r,g,b,a)) {
if (this->isOpaque()) { if (this->isOpaque()) {
*a = p->splat(0xff); *a = p->splat(0xff);
} }

View File

@ -12,7 +12,6 @@
#include "include/core/SkMatrix.h" #include "include/core/SkMatrix.h"
#include "include/core/SkShader.h" #include "include/core/SkShader.h"
#include "include/private/SkNoncopyable.h" #include "include/private/SkNoncopyable.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkEffectPriv.h" #include "src/core/SkEffectPriv.h"
#include "src/core/SkMask.h" #include "src/core/SkMask.h"
#include "src/core/SkTLazy.h" #include "src/core/SkTLazy.h"
@ -210,13 +209,13 @@ public:
bool program(skvm::Builder*, bool program(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>*, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const; skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const;
virtual bool onProgram(skvm::Builder*, virtual bool onProgram(skvm::Builder*,
SkColorSpace* dstCS, SkColorSpace* dstCS,
skvm::Arg uniforms, SkTDArray<uint32_t>*, skvm::Uniforms* uniforms,
skvm::F32 x, skvm::F32 y, skvm::F32 x, skvm::F32 y,
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const { skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
return false; return false;