Chromium Code Reviews| Index: src/core/SkBlitter.cpp |
| diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp |
| index 74cd29824e1bf4f08b4b4701da2efea9862a1a44..0e12a627d0ef2e5c17bd39ee488d28e66d5f98be 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)); |
|
scroggo
2014/05/05 16:02:47
Can't this just be an SkShader::Context? It seems
|
| + } |
| + return ctx != NULL; |
| } |