diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-05 18:39:18 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-05-05 18:39:18 +0000 |
commit | ce56d965069c1649afe14319cb239e6ad670682a (patch) | |
tree | c9d656d7eeb1cc623fb7f0e0c32725ee11cf4bf5 /src/core | |
parent | 58e428729b8819c35092684034983973ed43ebb2 (diff) |
Remove SkShader virtual method validContext
patch from issue 267923005
BUG=skia:
R=scroggo@google.com
Author: reed@google.com
Review URL: https://codereview.chromium.org/261773005
git-svn-id: http://skia.googlecode.com/svn/trunk@14573 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkBitmapProcShader.cpp | 34 | ||||
-rw-r--r-- | src/core/SkBitmapProcShader.h | 5 | ||||
-rw-r--r-- | src/core/SkBlitter.cpp | 52 | ||||
-rw-r--r-- | src/core/SkComposeShader.cpp | 38 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 13 | ||||
-rw-r--r-- | src/core/SkFilterShader.cpp | 10 | ||||
-rw-r--r-- | src/core/SkFilterShader.h | 4 | ||||
-rw-r--r-- | src/core/SkPictureShader.cpp | 51 | ||||
-rw-r--r-- | src/core/SkPictureShader.h | 46 | ||||
-rw-r--r-- | src/core/SkShader.cpp | 31 |
10 files changed, 116 insertions, 168 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 46cf7db136..503269ac10 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -97,39 +97,25 @@ static bool valid_for_drawing(const SkBitmap& bm) { return true; } -bool SkBitmapProcShader::validInternal(const ContextRec& rec, SkMatrix* totalInverse, - SkBitmapProcState* state) const { +SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const { if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { - return false; - } - - // Make sure we can use totalInverse as a cache. - SkMatrix totalInverseLocal; - if (NULL == totalInverse) { - totalInverse = &totalInverseLocal; + return NULL; } - + + SkMatrix totalInverse; // Do this first, so we know the matrix can be inverted. - if (!this->INHERITED::validContext(rec, totalInverse)) { - return false; + if (!this->computeTotalInverse(rec, &totalInverse)) { + return NULL; } + + void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); + SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState); SkASSERT(state); state->fTileModeX = fTileModeX; state->fTileModeY = fTileModeY; state->fOrigBitmap = fRawBitmap; - return state->chooseProcs(*totalInverse, *rec.fPaint); -} - -bool SkBitmapProcShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const { - SkBitmapProcState state; - return this->validInternal(rec, totalInverse, &state); -} - -SkShader::Context* SkBitmapProcShader::createContext(const ContextRec& rec, void* storage) const { - void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); - SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState); - if (!this->validInternal(rec, NULL, state)) { + if (!state->chooseProcs(totalInverse, *rec.fPaint)) { state->~SkBitmapProcState(); return NULL; } diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index e32d35e20d..0a036d3189 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -23,8 +23,6 @@ public: virtual bool isOpaque() const SK_OVERRIDE; virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE; - virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE; - virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE; virtual size_t contextSize() const SK_OVERRIDE; static bool CanDo(const SkBitmap&, TileMode tx, TileMode ty); @@ -59,13 +57,12 @@ public: protected: SkBitmapProcShader(SkReadBuffer& ); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; + virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE; SkBitmap fRawBitmap; // experimental for RLE encoding uint8_t fTileModeX, fTileModeY; private: - bool validInternal(const ContextRec&, SkMatrix* totalInverse, SkBitmapProcState*) const; - typedef SkShader INHERITED; }; diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 74cd29824e..0e12a627d0 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -591,29 +591,14 @@ public: return size; } - virtual bool validContext(const ContextRec& rec, SkMatrix* totalInverse) const SK_OVERRIDE { - if (!this->INHERITED::validContext(rec, totalInverse)) { - return false; - } - if (fProxy) { - return fProxy->validContext(rec); - } - return true; - } - - virtual SkShader::Context* createContext(const ContextRec& rec, void* storage) const SK_OVERRIDE - { - if (!this->validContext(rec, NULL)) { - return NULL; - } - - SkShader::Context* proxyContext; + virtual Context* onCreateContext(const ContextRec& rec, void* storage) const SK_OVERRIDE { + SkShader::Context* proxyContext = NULL; if (fProxy) { char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext); proxyContext = fProxy->createContext(rec, proxyContextStorage); - SkASSERT(proxyContext); - } else { - proxyContext = NULL; + if (!proxyContext) { + return NULL; + } } return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, rec, proxyContext)); } @@ -1016,6 +1001,19 @@ const uint32_t gMask_00FF00FF = 0xFF00FF; /////////////////////////////////////////////////////////////////////////////// +class SkTransparentShaderContext : public SkShader::Context { +public: + SkTransparentShaderContext(const SkShader& shader, const SkShader::ContextRec& rec) + : INHERITED(shader, rec) {} + + virtual void shadeSpan(int x, int y, SkPMColor colors[], int count) SK_OVERRIDE { + sk_bzero(colors, count * sizeof(SkPMColor)); + } + +private: + typedef SkShader::Context INHERITED; +}; + SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint, SkShader::Context* shaderContext) : INHERITED(device) @@ -1035,9 +1033,6 @@ SkShaderBlitter::~SkShaderBlitter() { bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix) { SkShader::ContextRec rec(device, paint, matrix); - if (!fShader->validContext(rec)) { - return false; - } // 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 @@ -1045,8 +1040,11 @@ bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& // The new context will be of the same size as the old one because we use the same // shader to create it. It is therefore safe to re-use the storage. fShaderContext->~Context(); - fShaderContext = fShader->createContext(rec, (void*)fShaderContext); - SkASSERT(fShaderContext); - - return true; + SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext); + if (NULL == ctx) { + // 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 ctx != NULL; } diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp index 28511e3e8b..7a7dce66a0 100644 --- a/src/core/SkComposeShader.cpp +++ b/src/core/SkComposeShader.cpp @@ -73,33 +73,13 @@ void SkComposeShader::flatten(SkWriteBuffer& buffer) const { buffer.writeFlattenable(fMode); } -/* We call validContext/createContext on our two worker shaders. - However, we always let them see opaque alpha, and if the paint - really is translucent, then we apply that after the fact. - - */ -bool SkComposeShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const { - if (!this->INHERITED::validContext(rec, totalInverse)) { - return false; +template <typename T> void safe_call_destructor(T* obj) { + if (obj) { + obj->~T(); } - - // we preconcat our localMatrix (if any) with the device matrix - // before calling our sub-shaders - - SkMatrix tmpM; - tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); - - ContextRec newRec(rec); - newRec.fMatrix = &tmpM; - - return fShaderA->validContext(newRec) && fShaderB->validContext(newRec); } -SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* storage) const { - if (!this->validContext(rec)) { - return NULL; - } - +SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void* storage) const { char* aStorage = (char*) storage + sizeof(ComposeShaderContext); char* bStorage = aStorage + fShaderA->contextSize(); @@ -120,11 +100,11 @@ SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* s SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); - - // Both functions must succeed; otherwise validContext should have returned - // false. - SkASSERT(contextA); - SkASSERT(contextB); + if (!contextA || !contextB) { + safe_call_destructor(contextA); + safe_call_destructor(contextB); + return NULL; + } return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, contextA, contextB)); } diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index c4f5f74eef..a74e3c0f79 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -2353,7 +2353,6 @@ class SkTriColorShader : public SkShader { public: SkTriColorShader() {} - virtual SkShader::Context* createContext(const ContextRec&, void*) const SK_OVERRIDE; virtual size_t contextSize() const SK_OVERRIDE; class TriColorShaderContext : public SkShader::Context { @@ -2378,18 +2377,14 @@ public: protected: SkTriColorShader(SkReadBuffer& buffer) : SkShader(buffer) {} + virtual Context* onCreateContext(const ContextRec& rec, void* storage) const SK_OVERRIDE { + return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec)); + } + private: typedef SkShader INHERITED; }; -SkShader::Context* SkTriColorShader::createContext(const ContextRec& rec, void* storage) const { - if (!this->validContext(rec)) { - return NULL; - } - - return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec)); -} - bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const SkColor colors[], int index0, int index1, int index2) { diff --git a/src/core/SkFilterShader.cpp b/src/core/SkFilterShader.cpp index f1cc68d028..5094706ea7 100644 --- a/src/core/SkFilterShader.cpp +++ b/src/core/SkFilterShader.cpp @@ -55,11 +55,7 @@ uint32_t SkFilterShader::FilterShaderContext::getFlags() const { return shaderF; } -SkShader::Context* SkFilterShader::createContext(const ContextRec& rec, void* storage) const { - if (!this->validContext(rec, NULL)) { - return NULL; - } - +SkShader::Context* SkFilterShader::onCreateContext(const ContextRec& rec, void* storage) const { char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext); SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage); SkASSERT(shaderContext); @@ -71,10 +67,6 @@ size_t SkFilterShader::contextSize() const { return sizeof(FilterShaderContext) + fShader->contextSize(); } -bool SkFilterShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const { - return this->INHERITED::validContext(rec, totalInverse) && fShader->validContext(rec); -} - SkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader, SkShader::Context* shaderContext, const ContextRec& rec) diff --git a/src/core/SkFilterShader.h b/src/core/SkFilterShader.h index 629f3f8c9e..3f983e26d9 100644 --- a/src/core/SkFilterShader.h +++ b/src/core/SkFilterShader.h @@ -17,8 +17,6 @@ public: SkFilterShader(SkShader* shader, SkColorFilter* filter); virtual ~SkFilterShader(); - virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE; - virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE; virtual size_t contextSize() const SK_OVERRIDE; class FilterShaderContext : public SkShader::Context { @@ -44,6 +42,8 @@ public: protected: SkFilterShader(SkReadBuffer& ); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; + virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE; + private: SkShader* fShader; diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index 81f9242854..9555624ffe 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -110,58 +110,55 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix) const { return fCachedBitmapShader; } -SkShader* SkPictureShader::validInternal(const ContextRec& rec, SkMatrix* totalInverse) const { - if (!this->INHERITED::validContext(rec, totalInverse)) { - return NULL; - } +size_t SkPictureShader::contextSize() const { + return sizeof(PictureShaderContext); +} +SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* storage) const { SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix)); - if (!bitmapShader || !bitmapShader->validContext(rec)) { + if (NULL == bitmapShader.get()) { return NULL; } - - return bitmapShader.detach(); + return PictureShaderContext::Create(storage, *this, rec, bitmapShader.detach()); } -bool SkPictureShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const { - SkAutoTUnref<SkShader> shader(this->validInternal(rec, totalInverse)); - return shader != NULL; -} +///////////////////////////////////////////////////////////////////////////////////////// -SkShader::Context* SkPictureShader::createContext(const ContextRec& rec, void* storage) const { - SkAutoTUnref<SkShader> bitmapShader(this->validInternal(rec, NULL)); - if (!bitmapShader) { - return NULL; +SkShader::Context* SkPictureShader::PictureShaderContext::Create(void* storage, + const SkPictureShader& shader, const ContextRec& rec, SkShader* bitmapShader) { + PictureShaderContext* ctx = SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext, + (shader, rec, bitmapShader)); + if (NULL == ctx->fBitmapShaderContext) { + ctx->~PictureShaderContext(); + ctx = NULL; } - - return SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext, (*this, rec, bitmapShader.detach())); -} - -size_t SkPictureShader::contextSize() const { - return sizeof(PictureShaderContext); + return ctx; } SkPictureShader::PictureShaderContext::PictureShaderContext( const SkPictureShader& shader, const ContextRec& rec, SkShader* bitmapShader) : INHERITED(shader, rec) - , fBitmapShader(bitmapShader) + , fBitmapShader(SkRef(bitmapShader)) { - SkASSERT(fBitmapShader); - fBitmapShaderContextStorage = sk_malloc_throw(fBitmapShader->contextSize()); - fBitmapShaderContext = fBitmapShader->createContext(rec, fBitmapShaderContextStorage); - SkASSERT(fBitmapShaderContext); + fBitmapShaderContextStorage = sk_malloc_throw(bitmapShader->contextSize()); + fBitmapShaderContext = bitmapShader->createContext(rec, fBitmapShaderContextStorage); + //if fBitmapShaderContext is null, we are invalid } SkPictureShader::PictureShaderContext::~PictureShaderContext() { - fBitmapShaderContext->~Context(); + if (fBitmapShaderContext) { + fBitmapShaderContext->~Context(); + } sk_free(fBitmapShaderContextStorage); } uint32_t SkPictureShader::PictureShaderContext::getFlags() const { + SkASSERT(fBitmapShaderContext); return fBitmapShaderContext->getFlags(); } SkShader::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) { + SkASSERT(fBitmapShaderContext); return fBitmapShaderContext->asAShadeProc(ctx); } diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h index 2ef6c1c92a..1788205558 100644 --- a/src/core/SkPictureShader.h +++ b/src/core/SkPictureShader.h @@ -24,29 +24,8 @@ public: static SkPictureShader* Create(SkPicture*, TileMode, TileMode, const SkMatrix* = NULL); virtual ~SkPictureShader(); - virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE; - virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE; virtual size_t contextSize() const SK_OVERRIDE; - class PictureShaderContext : public SkShader::Context { - public: - PictureShaderContext(const SkPictureShader&, const ContextRec&, SkShader* bitmapShader); - virtual ~PictureShaderContext(); - - virtual uint32_t getFlags() const SK_OVERRIDE; - - virtual ShadeProc asAShadeProc(void** ctx) SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE; - virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE; - - private: - SkAutoTUnref<SkShader> fBitmapShader; - SkShader::Context* fBitmapShaderContext; - void* fBitmapShaderContextStorage; - - typedef SkShader::Context INHERITED; - }; - SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureShader) @@ -57,11 +36,11 @@ public: protected: SkPictureShader(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; + virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE; private: SkPictureShader(SkPicture*, TileMode, TileMode, const SkMatrix* = NULL); - SkShader* validInternal(const ContextRec&, SkMatrix* totalInverse) const; SkShader* refBitmapShader(const SkMatrix&) const; SkPicture* fPicture; @@ -72,6 +51,29 @@ private: mutable SkSize fCachedTileScale; mutable SkMatrix fCachedLocalMatrix; + class PictureShaderContext : public SkShader::Context { + public: + static Context* Create(void* storage, const SkPictureShader&, const ContextRec&, + SkShader* bitmapShader); + + virtual ~PictureShaderContext(); + + virtual uint32_t getFlags() const SK_OVERRIDE; + + virtual ShadeProc asAShadeProc(void** ctx) SK_OVERRIDE; + virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE; + virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE; + + private: + PictureShaderContext(const SkPictureShader&, const ContextRec&, SkShader* bitmapShader); + + SkAutoTUnref<SkShader> fBitmapShader; + SkShader::Context* fBitmapShaderContext; + void* fBitmapShaderContextStorage; + + typedef SkShader::Context INHERITED; + }; + typedef SkShader INHERITED; }; diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index 67dd581543..8e6112ae7d 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -6,6 +6,7 @@ */ #include "SkBitmapProcShader.h" +#include "SkEmptyShader.h" #include "SkReadBuffer.h" #include "SkMallocPixelRef.h" #include "SkPaint.h" @@ -44,23 +45,25 @@ void SkShader::flatten(SkWriteBuffer& buffer) const { } } -bool SkShader::computeTotalInverse(const SkMatrix& matrix, SkMatrix* totalInverse) const { - const SkMatrix* m = &matrix; +bool SkShader::computeTotalInverse(const ContextRec& rec, SkMatrix* totalInverse) const { + const SkMatrix* m = rec.fMatrix; SkMatrix total; if (this->hasLocalMatrix()) { - total.setConcat(matrix, this->getLocalMatrix()); + total.setConcat(*m, this->getLocalMatrix()); m = &total; } - return m->invert(totalInverse); } -bool SkShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const { - return this->computeTotalInverse(*rec.fMatrix, totalInverse); +SkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const { + if (!this->computeTotalInverse(rec, NULL)) { + return NULL; + } + return this->onCreateContext(rec, storage); } -SkShader::Context* SkShader::createContext(const ContextRec&, void* storage) const { +SkShader::Context* SkShader::onCreateContext(const ContextRec&, void*) const { return NULL; } @@ -71,11 +74,9 @@ size_t SkShader::contextSize() const { SkShader::Context::Context(const SkShader& shader, const ContextRec& rec) : fShader(shader) { - SkASSERT(fShader.validContext(rec)); - // Because the context parameters must be valid at this point, we know that the matrix is // invertible. - SkAssertResult(fShader.computeTotalInverse(*rec.fMatrix, &fTotalInverse)); + SkAssertResult(fShader.computeTotalInverse(rec, &fTotalInverse)); fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); fPaintAlpha = rec.fPaint->getAlpha(); @@ -188,6 +189,10 @@ GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { return NULL; } +SkShader* SkShader::CreateEmptyShader() { + return SkNEW(SkEmptyShader); +} + SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy, const SkMatrix* localMatrix) { return ::CreateBitmapShader(src, tmx, tmy, localMatrix, NULL); @@ -246,11 +251,7 @@ uint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const { return SkGetPackedA32(fPMColor); } -SkShader::Context* SkColorShader::createContext(const ContextRec& rec, void* storage) const { - if (!this->validContext(rec)) { - return NULL; - } - +SkShader::Context* SkColorShader::onCreateContext(const ContextRec& rec, void* storage) const { return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, rec)); } |