thread an SkArenaAlloc into shaders
We'll need something like this to extend the lifetime of our SkBitmapController::State (and the bitmap and mipmaps it holds) to match the lifetime of the blitter. This is particularly important particularly for kMedium where we're not sampling off the original image. Not sure which other effects will need this sort of thing, if any. I think gradients would just write the colors directly into uniforms. Change-Id: Idefe620f88113ed436e04a101195b27aec1230db Reviewed-on: https://skia-review.googlesource.com/c/skia/+/262522 Auto-Submit: Mike Klein <mtklein@google.com> Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
c21316a73b
commit
3ab7128dfa
@ -28,7 +28,7 @@ struct Fade : public SkShaderBase {
|
||||
bool onProgram(skvm::Builder* p,
|
||||
const SkMatrix&, const SkMatrix*,
|
||||
SkFilterQuality, SkColorSpace*,
|
||||
skvm::Uniforms*,
|
||||
skvm::Uniforms*, SkArenaAlloc*,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override {
|
||||
// In this GM `y` will range over 0-50 and `x` over 50-100.
|
||||
|
@ -127,10 +127,12 @@ namespace {
|
||||
x = p.add(x, p.splat(0.5f));
|
||||
y = p.add(y, p.splat(0.5f));
|
||||
skvm::F32 r,g,b,a;
|
||||
|
||||
SkSTArenaAlloc<2*sizeof(void*)> tmp;
|
||||
if (shader->program(&p,
|
||||
params.ctm, /*localM=*/nullptr,
|
||||
params.quality, params.colorSpace.get(),
|
||||
uniforms,
|
||||
uniforms,&tmp,
|
||||
x,y, &r,&g,&b,&a)) {
|
||||
shaderHash = p.hash();
|
||||
} else {
|
||||
@ -159,7 +161,7 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
Builder(const Params& params, skvm::Uniforms* uniforms) {
|
||||
Builder(const Params& params, skvm::Uniforms* uniforms, SkArenaAlloc* alloc) {
|
||||
// First two arguments are always uniforms and the destination buffer.
|
||||
uniforms->ptr = uniform();
|
||||
skvm::Arg dst_ptr = arg(SkColorTypeBytesPerPixel(params.colorType));
|
||||
@ -182,7 +184,7 @@ namespace {
|
||||
SkAssertResult(as_SB(params.shader)->program(this,
|
||||
params.ctm, /*localM=*/nullptr,
|
||||
params.quality, params.colorSpace.get(),
|
||||
uniforms,
|
||||
uniforms, alloc,
|
||||
x,y, &src.r, &src.g, &src.b, &src.a));
|
||||
// We don't know if the src color is normalized (logical [0,1], premul [0,a]) or not.
|
||||
bool src_is_normalized = false;
|
||||
@ -425,7 +427,8 @@ namespace {
|
||||
|
||||
private:
|
||||
SkPixmap fDevice;
|
||||
skvm::Uniforms fUniforms;
|
||||
skvm::Uniforms fUniforms; // Most data is copied directly into fUniforms,
|
||||
SkArenaAlloc fAlloc{2*sizeof(void*)}; // but a few effects need to ref large content.
|
||||
const Params fParams;
|
||||
const Key fKey;
|
||||
skvm::Program fBlitH,
|
||||
@ -454,7 +457,7 @@ namespace {
|
||||
// fUniforms should reuse the exact same memory, so this is very cheap.
|
||||
SkDEBUGCODE(size_t prev = fUniforms.buf.size();)
|
||||
fUniforms.buf.resize(kBlitterUniformsCount);
|
||||
Builder builder{fParams.withCoverage(coverage), &fUniforms};
|
||||
Builder builder{fParams.withCoverage(coverage), &fUniforms, &fAlloc};
|
||||
SkASSERT(fUniforms.buf.size() == prev);
|
||||
|
||||
skvm::Program program = builder.done(debug_name(key).c_str());
|
||||
|
@ -63,11 +63,11 @@ bool SkColorFilterShader::onAppendStages(const SkStageRec& rec) const {
|
||||
bool SkColorFilterShader::onProgram(skvm::Builder* p,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
|
||||
// Run the shader.
|
||||
if (!as_SB(fShader)->program(p, ctm,localM, quality,dstCS, uniforms, x,y, r,g,b,a)) {
|
||||
if (!as_SB(fShader)->program(p, ctm,localM, quality,dstCS, uniforms,alloc, x,y, r,g,b,a)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ private:
|
||||
bool onProgram(skvm::Builder*,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc*,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override;
|
||||
|
||||
|
@ -108,7 +108,7 @@ static bool common_program(SkColor4f color, SkColorSpace* cs,
|
||||
bool SkColorShader::onProgram(skvm::Builder* p,
|
||||
const SkMatrix& /*ctm*/, const SkMatrix* /*localM*/,
|
||||
SkFilterQuality /*quality*/, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc*,
|
||||
skvm::F32 /*x*/, skvm::F32 /*y*/,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
|
||||
return common_program(SkColor4f::FromColor(fColor), sk_srgb_singleton(),
|
||||
@ -117,7 +117,7 @@ bool SkColorShader::onProgram(skvm::Builder* p,
|
||||
bool SkColor4Shader::onProgram(skvm::Builder* p,
|
||||
const SkMatrix& /*ctm*/, const SkMatrix* /*localM*/,
|
||||
SkFilterQuality /*quality*/, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc*,
|
||||
skvm::F32 /*x*/, skvm::F32 /*y*/,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
|
||||
return common_program(fColor, fColorSpace.get(),
|
||||
|
@ -47,7 +47,7 @@ private:
|
||||
bool onProgram(skvm::Builder*,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc*,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override;
|
||||
|
||||
@ -74,7 +74,7 @@ private:
|
||||
bool onProgram(skvm::Builder*,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc*,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override;
|
||||
|
||||
|
@ -645,7 +645,7 @@ SkStageUpdater* SkImageShader::onAppendUpdatableStages(const SkStageRec& rec) co
|
||||
bool SkImageShader::onProgram(skvm::Builder* p,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
|
||||
SkMatrix inv;
|
||||
@ -653,14 +653,15 @@ bool SkImageShader::onProgram(skvm::Builder* p,
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: need to extend lifetime of this once we start supporting kMedium_SkFilterQuality.
|
||||
SkBitmapController::State state{as_IB(fImage.get()), inv, quality};
|
||||
const SkPixmap& pm = state.pixmap();
|
||||
if (!pm.addr()) {
|
||||
// We use RequestBitmap() to make sure our SkBitmapController::State lives in the alloc.
|
||||
// This lets the SkVMBlitter hang on to this state and keep our image alive.
|
||||
auto state = SkBitmapController::RequestBitmap(as_IB(fImage.get()), inv, quality, alloc);
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
inv = state.invMatrix();
|
||||
quality = state.quality();
|
||||
const SkPixmap& pm = state->pixmap();
|
||||
inv = state->invMatrix();
|
||||
quality = state->quality();
|
||||
tweak_quality_and_inv_matrix(&quality, &inv);
|
||||
|
||||
if (quality != kNone_SkFilterQuality) { return false; }
|
||||
|
@ -50,7 +50,7 @@ private:
|
||||
bool onProgram(skvm::Builder*,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc*,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const override;
|
||||
|
||||
|
@ -200,7 +200,7 @@ bool SkShaderBase::onAppendStages(const SkStageRec& rec) const {
|
||||
bool SkShaderBase::program(skvm::Builder* p,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
|
||||
// Force opaque alpha for all opaque shaders.
|
||||
@ -215,7 +215,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, ctm,localM, quality,dstCS, uniforms, x,y, r,g,b,a)) {
|
||||
if (this->onProgram(p, ctm,localM, quality,dstCS, uniforms,alloc, x,y, r,g,b,a)) {
|
||||
if (this->isOpaque()) {
|
||||
*a = p->splat(1.0f);
|
||||
}
|
||||
|
@ -210,14 +210,14 @@ public:
|
||||
bool program(skvm::Builder*,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const;
|
||||
|
||||
virtual bool onProgram(skvm::Builder*,
|
||||
const SkMatrix& ctm, const SkMatrix* localM,
|
||||
SkFilterQuality quality, SkColorSpace* dstCS,
|
||||
skvm::Uniforms* uniforms,
|
||||
skvm::Uniforms* uniforms, SkArenaAlloc* alloc,
|
||||
skvm::F32 x, skvm::F32 y,
|
||||
skvm::F32* r, skvm::F32* g, skvm::F32* b, skvm::F32* a) const {
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user