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:
parent
23607a9a77
commit
1cc6067757
@ -30,11 +30,11 @@ struct Fade : public SkShaderBase {
|
||||
|
||||
bool onProgram(skvm::Builder* p,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override {
|
||||
if (as_SB(fShader)->program(p, dstCS,
|
||||
uniforms, buf,
|
||||
uniforms,
|
||||
x,y, r,g,b,a)) {
|
||||
// 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)));
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkFlattenable.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/SkTDArray.h"
|
||||
|
||||
class GrColorInfo;
|
||||
class GrFragmentProcessor;
|
||||
@ -28,6 +27,7 @@ namespace skvm {
|
||||
struct Arg;
|
||||
struct I32;
|
||||
struct F32;
|
||||
struct Uniforms;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,7 +66,7 @@ public:
|
||||
|
||||
virtual bool program(skvm::Builder*,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>*,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const;
|
||||
|
||||
enum Flags {
|
||||
|
@ -46,7 +46,7 @@ bool SkColorFilter::appendStages(const SkStageRec& rec, bool shaderIsOpaque) con
|
||||
|
||||
bool SkColorFilter::program(skvm::Builder*,
|
||||
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 {
|
||||
return false;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ bool SkColorFilter_Matrix::onAppendStages(const SkStageRec& rec, bool shaderIsOp
|
||||
|
||||
bool SkColorFilter_Matrix::program(skvm::Builder* p,
|
||||
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 {
|
||||
// TODO: specialize generated code on the 0/1 values of fMatrix?
|
||||
if (fDomain == Domain::kRGBA) {
|
||||
@ -99,9 +99,8 @@ bool SkColorFilter_Matrix::program(skvm::Builder* p,
|
||||
B = p->mul(B, invA);
|
||||
|
||||
// Apply matrix.
|
||||
const size_t offset = buf->bytes();
|
||||
memcpy(buf->append(20), &fMatrix, sizeof(fMatrix));
|
||||
auto m = [&](int i) { return p->bit_cast(p->uniform32(uniforms, offset + 4*i)); };
|
||||
skvm::Builder::Uniform u = uniforms->pushF(fMatrix, 20);
|
||||
auto m = [&](int i) { return p->bit_cast(p->uniform32(u.ptr, u.offset + 4*i)); };
|
||||
|
||||
skvm::F32 rgba[4];
|
||||
for (int j = 0; j < 4; j++) {
|
||||
|
@ -35,7 +35,7 @@ private:
|
||||
bool onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const override;
|
||||
bool program(skvm::Builder*,
|
||||
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;
|
||||
|
||||
float fMatrix[20];
|
||||
|
@ -338,6 +338,14 @@ namespace skvm {
|
||||
I32 uniform16(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.
|
||||
I32 splat(int n);
|
||||
I32 splat(unsigned u) { return this->splat((int)u); }
|
||||
@ -473,6 +481,27 @@ namespace skvm {
|
||||
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;
|
||||
|
||||
class Program {
|
||||
|
@ -17,14 +17,13 @@
|
||||
namespace {
|
||||
|
||||
// Uniforms set by the Blitter itself,
|
||||
// rather than by the Shader, which follow this struct in the buffer.
|
||||
struct Uniforms {
|
||||
// rather than by the Shader, which follow this struct in the skvm::Uniforms buffer.
|
||||
struct BlitterUniforms {
|
||||
int right; // First device x + blit run length n, used to get device x coordiate.
|
||||
int y; // Device y coordiate.
|
||||
};
|
||||
static_assert(SkIsAlign4(sizeof(Uniforms)), "");
|
||||
static constexpr int kUniformsCount = sizeof(Uniforms) / sizeof(uint32_t);
|
||||
static SkTDArray<uint32_t> uniforms_init() { return {0,0}; }
|
||||
static_assert(SkIsAlign4(sizeof(BlitterUniforms)), "");
|
||||
static constexpr int kBlitterUniformsCount = sizeof(BlitterUniforms) / 4;
|
||||
|
||||
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.
|
||||
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);
|
||||
uint32_t shaderHash = 0;
|
||||
{
|
||||
const SkShaderBase* shader = as_SB(params.shader);
|
||||
skvm::Builder p;
|
||||
skvm::Arg uniforms = skvm::Arg{0};
|
||||
skvm::F32 x = p.to_f32(p.sub(p.uniform32(uniforms, offsetof(Uniforms, right)),
|
||||
skvm::F32 x = p.to_f32(p.sub(p.uniform32(uniforms->ptr,
|
||||
offsetof(BlitterUniforms, right)),
|
||||
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;
|
||||
if (shader->program(&p,
|
||||
params.colorSpace.get(),
|
||||
uniforms, buf,
|
||||
uniforms,
|
||||
x,y, &r,&g,&b,&a)) {
|
||||
shaderHash = p.hash();
|
||||
} else {
|
||||
@ -189,29 +189,29 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
Builder(const Params& params, SkTDArray<uint32_t>* buf) {
|
||||
Builder(const Params& params, skvm::Uniforms* uniforms) {
|
||||
#define TODO SkUNREACHABLE
|
||||
SkDEBUGCODE(
|
||||
bool ok = true;
|
||||
SkTDArray<uint32_t> dummy = uniforms_init();
|
||||
(void)CacheKey(params, &dummy, &ok);
|
||||
SkASSERT(ok);
|
||||
)
|
||||
skvm::Arg uniforms = uniform(),
|
||||
dst_ptr = arg(SkColorTypeBytesPerPixel(params.colorType));
|
||||
// If coverage is Mask3D there'll next come two varyings for mul and add planes,
|
||||
// and then finally if coverage is any Mask?? format, a varying for the mask.
|
||||
// First two arguments are always uniforms and the destination buffer.
|
||||
uniforms->ptr = uniform();
|
||||
skvm::Arg dst_ptr = arg(SkColorTypeBytesPerPixel(params.colorType));
|
||||
// Other arguments depend on params.coverage:
|
||||
// - Full: (no more arguments)
|
||||
// - Mask3D: mul varying, add varying, 8-bit coverage varying
|
||||
// - MaskA8: 8-bit coverage varying
|
||||
// - MaskLCD16: 565 coverage varying
|
||||
// - UniformA8: 8-bit coverage uniform
|
||||
|
||||
Color src;
|
||||
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())),
|
||||
y = to_f32(uniform32(uniforms, offsetof(Uniforms, y)));
|
||||
y = to_f32(uniform32(uniforms->ptr,
|
||||
offsetof(BlitterUniforms, y)));
|
||||
SkAssertResult(as_SB(params.shader)->program(this,
|
||||
params.colorSpace.get(),
|
||||
uniforms, buf,
|
||||
uniforms,
|
||||
x,y, &src.r, &src.g, &src.b, &src.a));
|
||||
SkASSERT(buf->size() == dummy.size());
|
||||
|
||||
if (params.coverage == Coverage::Mask3D) {
|
||||
skvm::I32 M = load8(varying<uint8_t>()),
|
||||
@ -339,14 +339,13 @@ namespace {
|
||||
|
||||
bool onProgram(skvm::Builder* p,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override {
|
||||
if (as_SB(fShader)->program(p, dstCS,
|
||||
uniforms, buf,
|
||||
uniforms,
|
||||
x,y, r,g,b,a)) {
|
||||
skvm::I32 A = p->uniform32(uniforms, buf->bytes());
|
||||
buf->push_back(fAlpha);
|
||||
skvm::I32 A = p->uniform32(uniforms->push(fAlpha));
|
||||
*r = p->scale_unorm8(*r, A);
|
||||
*g = p->scale_unorm8(*g, A);
|
||||
*b = p->scale_unorm8(*b, A);
|
||||
@ -406,7 +405,7 @@ namespace {
|
||||
public:
|
||||
Blitter(const SkPixmap& device, const SkPaint& paint, bool* ok)
|
||||
: fDevice(device)
|
||||
, fUniforms(uniforms_init())
|
||||
, fUniforms(kBlitterUniformsCount)
|
||||
, fParams(effective_params(device, paint))
|
||||
, fKey(Builder::CacheKey(fParams, &fUniforms, ok))
|
||||
{}
|
||||
@ -434,15 +433,15 @@ namespace {
|
||||
}
|
||||
|
||||
private:
|
||||
SkPixmap fDevice; // TODO: can this be const&?
|
||||
SkTDArray<uint32_t> fUniforms;
|
||||
const Params fParams;
|
||||
const Key fKey;
|
||||
skvm::Program fBlitH,
|
||||
fBlitAntiH,
|
||||
fBlitMaskA8,
|
||||
fBlitMask3D,
|
||||
fBlitMaskLCD16;
|
||||
SkPixmap fDevice; // TODO: can this be const&?
|
||||
skvm::Uniforms fUniforms;
|
||||
const Params fParams;
|
||||
const Key fKey;
|
||||
skvm::Program fBlitH,
|
||||
fBlitAntiH,
|
||||
fBlitMaskA8,
|
||||
fBlitMask3D,
|
||||
fBlitMaskLCD16;
|
||||
|
||||
skvm::Program buildProgram(Coverage coverage) {
|
||||
Key key = fKey.withCoverage(coverage);
|
||||
@ -468,10 +467,10 @@ namespace {
|
||||
// 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.
|
||||
// fUniforms should reuse the exact same memory, so this is very cheap.
|
||||
SkDEBUGCODE(size_t prev = fUniforms.size();)
|
||||
fUniforms.setCount(kUniformsCount);
|
||||
SkDEBUGCODE(size_t prev = fUniforms.buf.size();)
|
||||
fUniforms.buf.resize(kBlitterUniformsCount);
|
||||
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());
|
||||
if (!program.hasJIT() && debug_dump(key)) {
|
||||
@ -483,8 +482,8 @@ namespace {
|
||||
}
|
||||
|
||||
void updateUniforms(int right, int y) {
|
||||
Uniforms uniforms{right, y};
|
||||
memcpy(fUniforms.begin(), &uniforms, sizeof(Uniforms));
|
||||
BlitterUniforms uniforms{right, y};
|
||||
memcpy(fUniforms.buf.data(), &uniforms, sizeof(BlitterUniforms));
|
||||
}
|
||||
|
||||
void blitH(int x, int y, int w) override {
|
||||
@ -492,7 +491,7 @@ namespace {
|
||||
fBlitH = this->buildProgram(Coverage::Full);
|
||||
}
|
||||
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 {
|
||||
@ -501,7 +500,7 @@ namespace {
|
||||
}
|
||||
for (int16_t run = *runs; run > 0; run = *runs) {
|
||||
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;
|
||||
runs += run;
|
||||
@ -552,11 +551,11 @@ namespace {
|
||||
|
||||
if (program == &fBlitMask3D) {
|
||||
size_t plane = mask.computeImageSize();
|
||||
program->eval(w, fUniforms.begin(), dptr, mptr + 1*plane
|
||||
, mptr + 2*plane
|
||||
, mptr + 0*plane);
|
||||
program->eval(w, fUniforms.buf.data(), dptr, mptr + 1*plane
|
||||
, mptr + 2*plane
|
||||
, mptr + 0*plane);
|
||||
} else {
|
||||
program->eval(w, fUniforms.begin(), dptr, mptr);
|
||||
program->eval(w, fUniforms.buf.data(), dptr, mptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,18 +62,18 @@ bool SkColorFilterShader::onAppendStages(const SkStageRec& rec) const {
|
||||
|
||||
bool SkColorFilterShader::onProgram(skvm::Builder* p,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Scale that by alpha.
|
||||
if (fAlpha != 1.0f) {
|
||||
skvm::I32 A = p->uniform32(uniforms, buf->bytes());
|
||||
buf->push_back(fAlpha*255 + 0.5f);
|
||||
int alpha = fAlpha*255 + 0.5f;
|
||||
skvm::I32 A = p->uniform32(uniforms->push(alpha));
|
||||
*r = p->scale_unorm8(*r, A);
|
||||
*g = p->scale_unorm8(*g, A);
|
||||
*b = p->scale_unorm8(*b, A);
|
||||
@ -81,7 +81,7 @@ bool SkColorFilterShader::onProgram(skvm::Builder* p,
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ private:
|
||||
|
||||
bool onProgram(skvm::Builder*,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>*,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override;
|
||||
|
||||
|
@ -93,15 +93,13 @@ bool SkColor4Shader::onAppendStages(const SkStageRec& rec) const {
|
||||
static bool common_program(SkColor4f color, SkColorSpace* cs,
|
||||
skvm::Builder* p,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) {
|
||||
SkColorSpaceXformSteps( cs, kUnpremul_SkAlphaType,
|
||||
dstCS, kUnpremul_SkAlphaType).apply(color.vec());
|
||||
|
||||
if (color.fitsInBytes()) {
|
||||
skvm::I32 rgba = p->uniform32(uniforms, buf->bytes());
|
||||
buf->push_back(color.premul().toBytes_RGBA());
|
||||
|
||||
skvm::I32 rgba = p->uniform32(uniforms->push(color.premul().toBytes_RGBA()));
|
||||
*r = p->extract(rgba, 0, p->splat(0xff));
|
||||
*g = p->extract(rgba, 8, 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,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 /*x*/, skvm::F32 /*y*/,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
|
||||
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,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 /*x*/, skvm::F32 /*y*/,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
|
||||
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
|
||||
|
@ -46,7 +46,7 @@ private:
|
||||
|
||||
bool onProgram(skvm::Builder*,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override;
|
||||
|
||||
@ -72,7 +72,7 @@ private:
|
||||
|
||||
bool onProgram(skvm::Builder*,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const override;
|
||||
|
||||
|
@ -194,7 +194,7 @@ bool SkShaderBase::onAppendStages(const SkStageRec& rec) const {
|
||||
|
||||
bool SkShaderBase::program(skvm::Builder* p,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>* buf,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
|
||||
// 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
|
||||
// that bit to make decisions when constructing an SkVMBlitter, like doing
|
||||
// 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()) {
|
||||
*a = p->splat(0xff);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkShader.h"
|
||||
#include "include/private/SkNoncopyable.h"
|
||||
#include "include/private/SkTDArray.h"
|
||||
#include "src/core/SkEffectPriv.h"
|
||||
#include "src/core/SkMask.h"
|
||||
#include "src/core/SkTLazy.h"
|
||||
@ -210,13 +209,13 @@ public:
|
||||
|
||||
bool program(skvm::Builder*,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>*,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const;
|
||||
|
||||
virtual bool onProgram(skvm::Builder*,
|
||||
SkColorSpace* dstCS,
|
||||
skvm::Arg uniforms, SkTDArray<uint32_t>*,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::I32* r, skvm::I32* g, skvm::I32* b, skvm::I32* a) const {
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user