| 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));
|
| + }
|
| + return ctx != NULL;
|
| }
|
|
|