Remove SkShader virtual method validContext
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 5 May 2014 18:39:18 +0000 (18:39 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 5 May 2014 18:39:18 +0000 (18:39 +0000)
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

28 files changed:
include/core/SkColorShader.h
include/core/SkComposeShader.h
include/core/SkEmptyShader.h
include/core/SkShader.h
include/effects/SkPerlinNoiseShader.h
include/effects/SkTransparentShader.h
src/core/SkBitmapProcShader.cpp
src/core/SkBitmapProcShader.h
src/core/SkBlitter.cpp
src/core/SkComposeShader.cpp
src/core/SkDraw.cpp
src/core/SkFilterShader.cpp
src/core/SkFilterShader.h
src/core/SkPictureShader.cpp
src/core/SkPictureShader.h
src/core/SkShader.cpp
src/effects/SkPerlinNoiseShader.cpp
src/effects/SkTransparentShader.cpp
src/effects/gradients/SkLinearGradient.cpp
src/effects/gradients/SkLinearGradient.h
src/effects/gradients/SkRadialGradient.cpp
src/effects/gradients/SkRadialGradient.h
src/effects/gradients/SkSweepGradient.cpp
src/effects/gradients/SkSweepGradient.h
src/effects/gradients/SkTwoPointConicalGradient.cpp
src/effects/gradients/SkTwoPointConicalGradient.h
src/effects/gradients/SkTwoPointRadialGradient.cpp
src/effects/gradients/SkTwoPointRadialGradient.h

index f993959715efa581e0b6b9e92e67679ea752aff6..be59627bc6517b6efda0884ac6264bd0a5accd18 100644 (file)
@@ -27,8 +27,6 @@ public:
 
     virtual bool isOpaque() const SK_OVERRIDE;
 
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
-
     virtual size_t contextSize() const SK_OVERRIDE {
         return sizeof(ColorShaderContext);
     }
@@ -64,6 +62,7 @@ public:
 protected:
     SkColorShader(SkReadBuffer&);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     SkColor     fColor;         // ignored if fInheritColor is true
index ac3c32b7311ae697a3b57a97069ba4aba62468b4..cfb03b9fc0a55d76172e1f1b2c1740e773bbf7e5 100644 (file)
@@ -34,8 +34,6 @@ public:
     SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL);
     virtual ~SkComposeShader();
 
-    virtual bool validContext(const ContextRec&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
-    virtual SkShader::Context* createContext(const ContextRec&, void*) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class ComposeShaderContext : public SkShader::Context {
@@ -70,6 +68,7 @@ public:
 protected:
     SkComposeShader(SkReadBuffer& );
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE;
 
 private:
     SkShader*   fShaderA;
index d1a067f432576ceb6987627537f5f478855e1eae..7de3bc1f8f9c2105681d6dde157448e5b4257335 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2011 Google Inc.
  *
@@ -6,13 +5,13 @@
  * found in the LICENSE file.
  */
 
-
-
 #ifndef SkEmptyShader_DEFINED
 #define SkEmptyShader_DEFINED
 
 #include "SkShader.h"
 
+// TODO: move this to private, as there is a public factory on SkShader
+
 /**
  *  \class SkEmptyShader
  *  A Shader that always draws nothing. Its createContext always returns NULL.
@@ -27,21 +26,16 @@ public:
         return sizeof(SkShader::Context);
     }
 
-    virtual bool validContext(const ContextRec&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE {
-        return false;
-    }
-
-    virtual SkShader::Context* createContext(const ContextRec&, void*) const SK_OVERRIDE {
-        // validContext returns false.
-        return NULL;
-    }
-
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
 
 protected:
     SkEmptyShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
 
+    virtual SkShader::Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE {
+        return NULL;
+    }
+
 private:
     typedef SkShader INHERITED;
 };
index bcb229d767143caaa0f68370300ddd610966e800..041730633a606fecdb60ed00636d2dbd3d1502fd 100644 (file)
@@ -212,21 +212,11 @@ public:
         typedef SkNoncopyable INHERITED;
     };
 
-    /**
-     *  Subclasses should be sure to call their INHERITED::validContext() if
-     *  they override this method.
-     */
-    virtual bool validContext(const ContextRec&, SkMatrix* totalInverse = NULL) const;
-
     /**
      *  Create the actual object that does the shading.
-     *  Returns NULL if validContext() returns false.
      *  Size of storage must be >= contextSize.
-     *  Your subclass must also override contextSize() if it overrides createContext().
-     *
-     *  Base class implementation returns NULL.
      */
-    virtual Context* createContext(const ContextRec&, void* storage) const;
+    Context* createContext(const ContextRec&, void* storage) const;
 
     /**
      *  Return the size of a Context returned by createContext.
@@ -374,6 +364,11 @@ public:
     //////////////////////////////////////////////////////////////////////////
     //  Factory methods for stock shaders
 
+    /**
+     *  Call this to create a new "empty" shader, that will not draw anything.
+     */
+    static SkShader* CreateEmptyShader();
+
     /** Call this to create a new shader that will draw with the specified bitmap.
      *
      *  If the bitmap cannot be used (e.g. has no pixels, or its dimensions
@@ -409,14 +404,19 @@ public:
     SK_DEFINE_FLATTENABLE_TYPE(SkShader)
 
 protected:
-
     SkShader(SkReadBuffer& );
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
 
-private:
-    SkMatrix            fLocalMatrix;
+    bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
+
+    /**
+     *  Your subclass must also override contextSize() if it overrides onCreateContext().
+     *  Base class impl returns NULL.
+     */
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const;
 
-    bool computeTotalInverse(const SkMatrix& matrix, SkMatrix* totalInverse) const;
+private:
+    SkMatrix fLocalMatrix;
 
     typedef SkFlattenable INHERITED;
 };
index 2766df0a78fc1f25c4ecb7856bbcdfcb5308a8b5..5082a07f3b3018092eb16312c6439f16acc23c27 100644 (file)
@@ -72,7 +72,6 @@ public:
     }
 
 
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class PerlinNoiseShaderContext : public SkShader::Context {
@@ -104,6 +103,7 @@ public:
 protected:
     SkPerlinNoiseShader(SkReadBuffer&);
     virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX,
index 55513eb53208796f87490a100a5f6d42686bf067..d9a3e5d7a1975523e3b8ac317979d571f57d2486 100644 (file)
@@ -14,8 +14,6 @@ class SK_API SkTransparentShader : public SkShader {
 public:
     SkTransparentShader() {}
 
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const
-            SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class TransparentShaderContext : public SkShader::Context {
@@ -36,6 +34,9 @@ public:
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTransparentShader)
 
+protected:
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
+
 private:
     SkTransparentShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
 
index 46cf7db136d93e8bd2391d134d17e009a666c706..503269ac10690de985354836c32869898672e11c 100644 (file)
@@ -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;
     }
index e32d35e20d9f00a1ec4850fda461dc6a27473c15..0a036d3189ed8b40473815f034b948cac8df1925 100644 (file)
@@ -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;
 };
 
index 74cd29824e1bf4f08b4b4701da2efea9862a1a44..0e12a627d0ef2e5c17bd39ee488d28e66d5f98be 100644 (file)
@@ -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;
 }
index 28511e3e8b4ebc2d8ca7d911dd7dc7432d6d5c5d..7a7dce66a028dcf831b968ea26576d007d99a553 100644 (file)
@@ -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));
 }
index c4f5f74eefb93ea0ca539e28b079d4e4125c4149..a74e3c0f798123845c718fb717a30bba6ca9e4f9 100644 (file)
@@ -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) {
 
index f1cc68d028954abcb9d3f22f82322e75cd234366..5094706ea784d56e8aafe3d398f72ff4894e74bd 100644 (file)
@@ -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)
index 629f3f8c9ecbd702c07a5b60885f7052aec06fa9..3f983e26d93f0d62ef71ff80f35a20ac6df7b0e8 100644 (file)
@@ -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;
index 81f9242854576442f221cce7814261b10bb41817..9555624ffe3ff3a1a2d84e92ab1696dfb1348813 100644 (file)
@@ -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);
 }
 
index 2ef6c1c92a57e24afedcdcc76cf4408e55886b65..178820555809f7a9ee9103f10d83ba764c73a7fc 100644 (file)
@@ -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;
 };
 
index 67dd581543e737970b47b2789df3e16d29509f95..8e6112ae7d988add767dd95298a1fe80d05572d3 100644 (file)
@@ -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));
 }
 
index a4944fb8ffdd2efd59d4d54de94aba20aa4e8865..c6d61180029b30d1e28065e46a283387032acf7d 100644 (file)
@@ -425,11 +425,8 @@ SkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade(
     return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
 }
 
-SkShader::Context* SkPerlinNoiseShader::createContext(const ContextRec& rec, void* storage) const {
-    if (!this->validContext(rec)) {
-        return NULL;
-    }
-
+SkShader::Context* SkPerlinNoiseShader::onCreateContext(const ContextRec& rec,
+                                                        void* storage) const {
     return SkNEW_PLACEMENT_ARGS(storage, PerlinNoiseShaderContext, (*this, rec));
 }
 
index 9a390ad6f299f5258579030f9d8abd2dad2d104e..f290d0dcf8d5c0b834b8729e519661f302f31799 100644 (file)
 #include "SkColorPriv.h"
 #include "SkString.h"
 
-SkShader::Context* SkTransparentShader::createContext(const ContextRec& rec, void* storage) const {
-    if (!this->validContext(rec)) {
-        return NULL;
-    }
-
+SkShader::Context* SkTransparentShader::onCreateContext(const ContextRec& rec,
+                                                        void* storage) const {
     return SkNEW_PLACEMENT_ARGS(storage, TransparentShaderContext, (*this, rec));
 }
 
index b9de651fcecac83bc6876cd03d5bbe1a2ac5cd80..f37759c1a94ff416b8ce8b0e19444409fcd7e861 100644 (file)
@@ -76,11 +76,7 @@ size_t SkLinearGradient::contextSize() const {
     return sizeof(LinearGradientContext);
 }
 
-SkShader::Context* SkLinearGradient::createContext(const ContextRec& rec, void* storage) const {
-    if (!this->validContext(rec)) {
-        return NULL;
-    }
-
+SkShader::Context* SkLinearGradient::onCreateContext(const ContextRec& rec, void* storage) const {
     return SkNEW_PLACEMENT_ARGS(storage, LinearGradientContext, (*this, rec));
 }
 
index d9ffc77c1279a007f99760d40f345973478354b7..e892fe33d0b9ee0e80542552997acc1cb3081601 100644 (file)
@@ -14,7 +14,6 @@ class SkLinearGradient : public SkGradientShaderBase {
 public:
     SkLinearGradient(const SkPoint pts[2], const Descriptor&, const SkMatrix* localMatrix);
 
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class LinearGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
@@ -39,6 +38,7 @@ public:
 protected:
     SkLinearGradient(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     typedef SkGradientShaderBase INHERITED;
index 07ee680acad3df254d9830070a51c47183a4d377..e379f36c9577f33490e6ab9b0d86d34aa7835b2b 100644 (file)
@@ -161,11 +161,7 @@ size_t SkRadialGradient::contextSize() const {
     return sizeof(RadialGradientContext);
 }
 
-SkShader::Context* SkRadialGradient::createContext(const ContextRec& rec, void* storage) const {
-    if (!this->validContext(rec)) {
-        return NULL;
-    }
-
+SkShader::Context* SkRadialGradient::onCreateContext(const ContextRec& rec, void* storage) const {
     return SkNEW_PLACEMENT_ARGS(storage, RadialGradientContext, (*this, rec));
 }
 
index 873024730d4678bb7d3ff1d3894d8f2bb8444a1f..2c60ba5e0816d90908cf5e3e29175f7ade5946db 100644 (file)
@@ -16,7 +16,6 @@ public:
     SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor&,
                      const SkMatrix* localMatrix);
 
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class RadialGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
@@ -42,6 +41,7 @@ public:
 protected:
     SkRadialGradient(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     typedef SkGradientShaderBase INHERITED;
index 0baf5c717eec9b6b30c1b5a5880f78fc388d41f6..81ebb3441eb13159399ce771d05c0a5e3402953d 100644 (file)
@@ -56,11 +56,7 @@ size_t SkSweepGradient::contextSize() const {
     return sizeof(SweepGradientContext);
 }
 
-SkShader::Context* SkSweepGradient::createContext(const ContextRec& rec, void* storage) const {
-    if (!this->validContext(rec)) {
-        return NULL;
-    }
-
+SkShader::Context* SkSweepGradient::onCreateContext(const ContextRec& rec, void* storage) const {
     return SkNEW_PLACEMENT_ARGS(storage, SweepGradientContext, (*this, rec));
 }
 
index 9ddd1e25d52e530a8b474627cce06d8e38b5766f..36cdd6381144fc8393c8147d858985f973781fea 100644 (file)
@@ -16,7 +16,6 @@ public:
     SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor&,
                     const SkMatrix* localMatrix);
 
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class SweepGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
@@ -44,6 +43,7 @@ public:
 protected:
     SkSweepGradient(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     const SkPoint fCenter;
index e9c2efe32d3edb3f70a5da97a39194a2cb00ee57..574df08294fb5cdbb2d9de0cbdd760e6f252c39b 100644 (file)
@@ -221,12 +221,8 @@ size_t SkTwoPointConicalGradient::contextSize() const {
     return sizeof(TwoPointConicalGradientContext);
 }
 
-SkShader::Context* SkTwoPointConicalGradient::createContext(const ContextRec& rec,
-                                                            void* storage) const {
-    if (!this->validContext(rec)) {
-        return NULL;
-    }
-
+SkShader::Context* SkTwoPointConicalGradient::onCreateContext(const ContextRec& rec,
+                                                              void* storage) const {
     return SkNEW_PLACEMENT_ARGS(storage, TwoPointConicalGradientContext, (*this, rec));
 }
 
index 1c5e409af00ccc4f44bf852f845d6202fc67cf7f..85e0bc0b4eccd7747e785d27bb1a72fcfcbf9396 100644 (file)
@@ -48,7 +48,6 @@ public:
                               const SkMatrix* localMatrix);
 
 
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class TwoPointConicalGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
@@ -83,6 +82,7 @@ public:
 protected:
     SkTwoPointConicalGradient(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     SkPoint fCenter1;
index f691db291c931e193c7de3095e7d76eb7a8b048e..d85be5d3bab053e407e4b0ee4d4df266c328166d 100644 (file)
@@ -224,21 +224,12 @@ size_t SkTwoPointRadialGradient::contextSize() const {
     return sizeof(TwoPointRadialGradientContext);
 }
 
-bool SkTwoPointRadialGradient::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+SkShader::Context* SkTwoPointRadialGradient::onCreateContext(const ContextRec& rec,
+                                                             void* storage) const {
     // For now, we might have divided by zero, so detect that.
     if (0 == fDiffRadius) {
-        return false;
-    }
-
-    return this->INHERITED::validContext(rec, totalInverse);
-}
-
-SkShader::Context* SkTwoPointRadialGradient::createContext(const ContextRec& rec,
-                                                           void* storage) const {
-    if (!this->validContext(rec, NULL)) {
         return NULL;
     }
-
     return SkNEW_PLACEMENT_ARGS(storage, TwoPointRadialGradientContext, (*this, rec));
 }
 
index de5b5434e17decdfaa6cac61124ec05a034ee3c8..6d36fe448eef35b101e69707ed5b173aeb26d2fd 100644 (file)
@@ -24,8 +24,6 @@ public:
     virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
 
     virtual size_t contextSize() const SK_OVERRIDE;
-    virtual bool validContext(const ContextRec&, SkMatrix* totalInverse) const SK_OVERRIDE;
-    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
     class TwoPointRadialGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
     public:
@@ -47,6 +45,7 @@ public:
 protected:
     SkTwoPointRadialGradient(SkReadBuffer& buffer);
     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE;
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
 
 private:
     const SkPoint fCenter1;