diff options
-rw-r--r-- | include/core/SkShader.h | 29 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.h | 5 | ||||
-rw-r--r-- | src/core/SkBlitter.cpp | 13 | ||||
-rw-r--r-- | src/core/SkBlitter.h | 3 | ||||
-rw-r--r-- | src/core/SkCoreBlitters.h | 3 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 26 | ||||
-rw-r--r-- | src/core/SkPictureShader.cpp | 9 | ||||
-rw-r--r-- | src/core/SkPictureShader.h | 2 | ||||
-rw-r--r-- | src/core/SkShader.cpp | 8 |
9 files changed, 46 insertions, 52 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 041730633a..dc93b84749 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -123,17 +123,17 @@ public: * ContextRec acts as a parameter bundle for creating Contexts. */ struct ContextRec { - ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL) {} - ContextRec(const ContextRec& other) - : fDevice(other.fDevice), fPaint(other.fPaint), fMatrix(other.fMatrix) {} + ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL), fLocalMatrix(NULL) {} ContextRec(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix) : fDevice(&device) , fPaint(&paint) - , fMatrix(&matrix) {} + , fMatrix(&matrix) + , fLocalMatrix(NULL) {} - const SkBitmap* fDevice; // the bitmap we are drawing into - const SkPaint* fPaint; // the current paint associated with the draw - const SkMatrix* fMatrix; // the current matrix in the canvas + const SkBitmap* fDevice; // the bitmap we are drawing into + const SkPaint* fPaint; // the current paint associated with the draw + const SkMatrix* fMatrix; // the current matrix in the canvas + const SkMatrix* fLocalMatrix; // optional local matrix }; class Context : public ::SkNoncopyable { @@ -200,14 +200,15 @@ public: }; static MatrixClass ComputeMatrixClass(const SkMatrix&); - uint8_t getPaintAlpha() const { return fPaintAlpha; } - const SkMatrix& getTotalInverse() const { return fTotalInverse; } - MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; } - + uint8_t getPaintAlpha() const { return fPaintAlpha; } + const SkMatrix& getTotalInverse() const { return fTotalInverse; } + MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; } + const SkMatrix& getCTM() const { return fCTM; } private: - SkMatrix fTotalInverse; - uint8_t fPaintAlpha; - uint8_t fTotalInverseClass; + SkMatrix fCTM; + SkMatrix fTotalInverse; + uint8_t fPaintAlpha; + uint8_t fTotalInverseClass; typedef SkNoncopyable INHERITED; }; diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index 0a036d3189..8d31256469 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -71,10 +71,7 @@ private: // an Sk3DBlitter in SkDraw.cpp // Note that some contexts may contain other contexts (e.g. for compose shaders), but we've not // yet found a situation where the size below isn't big enough. -typedef SkSmallAllocator<3, sizeof(SkBitmapProcShader) + - sizeof(SkBitmapProcShader::BitmapProcShaderContext) + - sizeof(SkBitmapProcState) + - sizeof(void*) * 2> SkTBlitterAllocator; +typedef SkSmallAllocator<3, 768> SkTBlitterAllocator; // If alloc is non-NULL, it will be used to allocate the returned SkShader, and MUST outlive // the SkShader. diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 0e12a627d0..81e46c5622 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,7 +5,6 @@ * found in the LICENSE file. */ - #include "SkBlitter.h" #include "SkAntiRun.h" #include "SkColor.h" @@ -26,8 +24,7 @@ SkBlitter::~SkBlitter() {} bool SkBlitter::isNullBlitter() const { return false; } -bool SkBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix) { +bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) { return true; } @@ -1030,10 +1027,7 @@ SkShaderBlitter::~SkShaderBlitter() { fShader->unref(); } -bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix) { - SkShader::ContextRec rec(device, paint, matrix); - +bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) { // Only destroy the old context if we have a new one. We need to ensure to have a // live context in fShaderContext because the storage is owned by an SkSmallAllocator // outside of this class. @@ -1045,6 +1039,7 @@ bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& // Need a valid context in fShaderContext's storage, so we can later (or our caller) call // the in-place destructor. SkNEW_PLACEMENT_ARGS(fShaderContext, SkTransparentShaderContext, (*fShader, rec)); + return false; } - return ctx != NULL; + return true; } diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h index f76839e8b6..a3a2196122 100644 --- a/src/core/SkBlitter.h +++ b/src/core/SkBlitter.h @@ -64,8 +64,7 @@ public: /** * Special methods for SkShaderBlitter. On all other classes this is a no-op. */ - virtual bool resetShaderContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix); + virtual bool resetShaderContext(const SkShader::ContextRec&); virtual SkShader::Context* getShaderContext() const; ///@name non-virtual helpers diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index 2d22d38e78..20f9437ac8 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -41,8 +41,7 @@ public: * Will create the context at the same location as the old one (this is safe * because the shader itself is unchanged). */ - virtual bool resetShaderContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix) SK_OVERRIDE; + virtual bool resetShaderContext(const SkShader::ContextRec&) SK_OVERRIDE; virtual SkShader::Context* getShaderContext() const SK_OVERRIDE { return fShaderContext; } diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 9347efe475..24c8055716 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -2403,7 +2403,13 @@ bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const S if (!m.invert(&im)) { return false; } - fDstToUnit.setConcat(im, this->getTotalInverse()); + // We can't call getTotalInverse(), because we explicitly don't want to look at the localmatrix + // as our interators are intrinsically tied to the vertices, and nothing else. + SkMatrix ctmInv; + if (!this->getCTM().invert(&ctmInv)) { + return false; + } + fDstToUnit.setConcat(im, ctmInv); return true; } @@ -2556,18 +2562,13 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count, VertState::Proc vertProc = state.chooseProc(vmode); if (NULL != textures || NULL != colors) { - SkMatrix tempM; - SkMatrix savedLocalM; - if (shader) { - savedLocalM = shader->getLocalMatrix(); - } - while (vertProc(&state)) { if (NULL != textures) { + SkMatrix tempM; if (texture_to_matrix(state, vertices, textures, &tempM)) { - tempM.postConcat(savedLocalM); - shader->setLocalMatrix(tempM); - if (!blitter->resetShaderContext(*fBitmap, p, *fMatrix)) { + SkShader::ContextRec rec(*fBitmap, p, *fMatrix); + rec.fLocalMatrix = &tempM; + if (!blitter->resetShaderContext(rec)) { continue; } } @@ -2603,11 +2604,6 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count, }; SkScan::FillTriangle(tmp, *fRC, blitter.get()); } - - // now restore the shader's original local matrix - if (NULL != shader) { - shader->setLocalMatrix(savedLocalM); - } } else { // no colors[] and no texture HairProc hairProc = ChooseHairProc(paint.isAntiAlias()); diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index 290baa8284..9655e85bd1 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -52,7 +52,7 @@ void SkPictureShader::flatten(SkWriteBuffer& buffer) const { fPicture->flatten(buffer); } -SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const { +SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatrix* localM) const { SkASSERT(fPicture && fPicture->width() > 0 && fPicture->height() > 0); SkMatrix m; @@ -61,6 +61,9 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const { } else { m = matrix; } + if (localM) { + m.preConcat(*localM); + } // Use a rotation-invariant scale SkPoint scale; @@ -115,7 +118,7 @@ size_t SkPictureShader::contextSize() const { } SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* storage) const { - SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix)); + SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix)); if (NULL == bitmapShader.get()) { return NULL; } @@ -190,7 +193,7 @@ void SkPictureShader::toString(SkString* str) const { #if SK_SUPPORT_GPU GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint) const { - SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(context->getMatrix())); + SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(context->getMatrix(), NULL)); if (!bitmapShader) { return NULL; } diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h index 0fbfbee444..27fb674b01 100644 --- a/src/core/SkPictureShader.h +++ b/src/core/SkPictureShader.h @@ -41,7 +41,7 @@ protected: private: SkPictureShader(SkPicture*, TileMode, TileMode, const SkMatrix* = NULL); - SkShader* refBitmapShader(const SkMatrix&) const; + SkShader* refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix) const; SkPicture* fPicture; TileMode fTmx, fTmy; diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index 8e6112ae7d..0c954f869b 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -53,6 +53,10 @@ bool SkShader::computeTotalInverse(const ContextRec& rec, SkMatrix* totalInverse total.setConcat(*m, this->getLocalMatrix()); m = &total; } + if (rec.fLocalMatrix) { + total.setConcat(*m, *rec.fLocalMatrix); + m = &total; + } return m->invert(totalInverse); } @@ -63,7 +67,7 @@ SkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) return this->onCreateContext(rec, storage); } -SkShader::Context* SkShader::onCreateContext(const ContextRec&, void*) const { +SkShader::Context* SkShader::onCreateContext(const ContextRec& rec, void*) const { return NULL; } @@ -72,7 +76,7 @@ size_t SkShader::contextSize() const { } SkShader::Context::Context(const SkShader& shader, const ContextRec& rec) - : fShader(shader) + : fShader(shader), fCTM(*rec.fMatrix) { // Because the context parameters must be valid at this point, we know that the matrix is // invertible. |