diff options
Diffstat (limited to 'src/shaders/SkLocalMatrixShader.cpp')
-rw-r--r-- | src/shaders/SkLocalMatrixShader.cpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/shaders/SkLocalMatrixShader.cpp b/src/shaders/SkLocalMatrixShader.cpp new file mode 100644 index 0000000000..e21e4a84b7 --- /dev/null +++ b/src/shaders/SkLocalMatrixShader.cpp @@ -0,0 +1,110 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkLocalMatrixShader.h" + +#if SK_SUPPORT_GPU +#include "GrFragmentProcessor.h" +#endif + +#if SK_SUPPORT_GPU +sk_sp<GrFragmentProcessor> SkLocalMatrixShader::asFragmentProcessor(const AsFPArgs& args) const { + SkMatrix tmp = this->getLocalMatrix(); + if (args.fLocalMatrix) { + tmp.preConcat(*args.fLocalMatrix); + } + return as_SB(fProxyShader)->asFragmentProcessor(AsFPArgs( + args.fContext, args.fViewMatrix, &tmp, args.fFilterQuality, args.fDstColorSpace)); +} +#endif + +sk_sp<SkFlattenable> SkLocalMatrixShader::CreateProc(SkReadBuffer& buffer) { + SkMatrix lm; + buffer.readMatrix(&lm); + auto baseShader(buffer.readShader()); + if (!baseShader) { + return nullptr; + } + return baseShader->makeWithLocalMatrix(lm); +} + +void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const { + buffer.writeMatrix(this->getLocalMatrix()); + buffer.writeFlattenable(fProxyShader.get()); +} + +SkShaderBase::Context* SkLocalMatrixShader::onMakeContext( + const ContextRec& rec, SkArenaAlloc* alloc) const +{ + ContextRec newRec(rec); + SkMatrix tmp; + if (rec.fLocalMatrix) { + tmp.setConcat(*rec.fLocalMatrix, this->getLocalMatrix()); + newRec.fLocalMatrix = &tmp; + } else { + newRec.fLocalMatrix = &this->getLocalMatrix(); + } + return as_SB(fProxyShader)->makeContext(newRec, alloc); +} + +SkImage* SkLocalMatrixShader::onIsAImage(SkMatrix* outMatrix, enum TileMode* mode) const { + SkMatrix imageMatrix; + SkImage* image = fProxyShader->isAImage(&imageMatrix, mode); + if (image && outMatrix) { + // Local matrix must be applied first so it is on the right side of the concat. + *outMatrix = SkMatrix::Concat(imageMatrix, this->getLocalMatrix()); + } + + return image; +} + +bool SkLocalMatrixShader::onAppendStages(SkRasterPipeline* p, + SkColorSpace* dst, + SkArenaAlloc* scratch, + const SkMatrix& ctm, + const SkPaint& paint, + const SkMatrix* localM) const { + SkMatrix tmp; + if (localM) { + tmp.setConcat(*localM, this->getLocalMatrix()); + } + return as_SB(fProxyShader)->appendStages(p, dst, scratch, ctm, paint, + localM ? &tmp : &this->getLocalMatrix()); +} + +#ifndef SK_IGNORE_TO_STRING +void SkLocalMatrixShader::toString(SkString* str) const { + str->append("SkLocalMatrixShader: ("); + + as_SB(fProxyShader)->toString(str); + + this->INHERITED::toString(str); + + str->append(")"); +} +#endif + +sk_sp<SkShader> SkShader::makeWithLocalMatrix(const SkMatrix& localMatrix) const { + if (localMatrix.isIdentity()) { + return sk_ref_sp(const_cast<SkShader*>(this)); + } + + const SkMatrix* lm = &localMatrix; + + sk_sp<SkShader> baseShader; + SkMatrix otherLocalMatrix; + sk_sp<SkShader> proxy(as_SB(this)->makeAsALocalMatrixShader(&otherLocalMatrix)); + if (proxy) { + otherLocalMatrix.preConcat(localMatrix); + lm = &otherLocalMatrix; + baseShader = proxy; + } else { + baseShader = sk_ref_sp(const_cast<SkShader*>(this)); + } + + return sk_make_sp<SkLocalMatrixShader>(std::move(baseShader), *lm); +} |