create struct to hold all the params passed around for shader::context

BUG=skia:
R=scroggo@google.com, dominikg@chromium.org

Author: reed@google.com

Review URL: https://codereview.chromium.org/264843006

git-svn-id: http://skia.googlecode.com/svn/trunk@14514 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 44bdc6d..46cf7db 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -97,10 +97,7 @@
     return true;
 }
 
-bool SkBitmapProcShader::validInternal(const SkBitmap& device,
-                                       const SkPaint& paint,
-                                       const SkMatrix& matrix,
-                                       SkMatrix* totalInverse,
+bool SkBitmapProcShader::validInternal(const ContextRec& rec, SkMatrix* totalInverse,
                                        SkBitmapProcState* state) const {
     if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) {
         return false;
@@ -113,7 +110,7 @@
     }
 
     // Do this first, so we know the matrix can be inverted.
-    if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+    if (!this->INHERITED::validContext(rec, totalInverse)) {
         return false;
     }
 
@@ -121,28 +118,23 @@
     state->fTileModeX = fTileModeX;
     state->fTileModeY = fTileModeY;
     state->fOrigBitmap = fRawBitmap;
-    return state->chooseProcs(*totalInverse, paint);
+    return state->chooseProcs(*totalInverse, *rec.fPaint);
 }
 
-bool SkBitmapProcShader::validContext(const SkBitmap& device,
-                                      const SkPaint& paint,
-                                      const SkMatrix& matrix,
-                                      SkMatrix* totalInverse) const {
+bool SkBitmapProcShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
     SkBitmapProcState state;
-    return this->validInternal(device, paint, matrix, totalInverse, &state);
+    return this->validInternal(rec, totalInverse, &state);
 }
 
-SkShader::Context* SkBitmapProcShader::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                     const SkMatrix& matrix, void* storage) const {
+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(device, paint, matrix, NULL, state)) {
+    if (!this->validInternal(rec, NULL, state)) {
         state->~SkBitmapProcState();
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext,
-                                (*this, device, paint, matrix, state));
+    return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, rec, state));
 }
 
 size_t SkBitmapProcShader::contextSize() const {
@@ -152,9 +144,8 @@
 }
 
 SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
-        const SkBitmapProcShader& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix, SkBitmapProcState* state)
-    : INHERITED(shader, device, paint, matrix)
+        const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state)
+    : INHERITED(shader, rec)
     , fState(state)
 {
     const SkBitmap& bitmap = *fState->fBitmap;
@@ -182,7 +173,7 @@
             break;
     }
 
-    if (paint.isDither() && bitmap.colorType() != kRGB_565_SkColorType) {
+    if (rec.fPaint->isDither() && bitmap.colorType() != kRGB_565_SkColorType) {
         // gradients can auto-dither in their 16bit sampler, but we don't so
         // we clear the flag here.
         flags &= ~kHasSpan16_Flag;
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 78b46ce..e32d35e 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -23,12 +23,8 @@
     virtual bool isOpaque() const SK_OVERRIDE;
     virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE;
 
-    virtual bool validContext(const SkBitmap& device,
-                              const SkPaint& paint,
-                              const SkMatrix& matrix,
-                              SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
-    virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&,
-                                             const SkMatrix&, void* storage) 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);
@@ -44,11 +40,7 @@
     public:
         // The context takes ownership of the state. It will call its destructor
         // but will NOT free the memory.
-        BitmapProcShaderContext(const SkBitmapProcShader& shader,
-                                const SkBitmap& device,
-                                const SkPaint& paint,
-                                const SkMatrix& matrix,
-                                SkBitmapProcState* state);
+        BitmapProcShaderContext(const SkBitmapProcShader&, const ContextRec&, SkBitmapProcState*);
         virtual ~BitmapProcShaderContext();
 
         virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
@@ -72,9 +64,7 @@
     uint8_t     fTileModeX, fTileModeY;
 
 private:
-    bool validInternal(const SkBitmap& device, const SkPaint& paint,
-                       const SkMatrix& matrix, SkMatrix* totalInverse,
-                       SkBitmapProcState* state) const;
+    bool validInternal(const ContextRec&, SkMatrix* totalInverse, SkBitmapProcState*) const;
 
     typedef SkShader INHERITED;
 };
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index 41f37e6..74cd298 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -591,51 +591,44 @@
         return size;
     }
 
-    virtual bool validContext(const SkBitmap& device, const SkPaint& paint,
-                              const SkMatrix& matrix, SkMatrix* totalInverse = NULL) const
-            SK_OVERRIDE
-    {
-        if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+    virtual bool validContext(const ContextRec& rec, SkMatrix* totalInverse) const SK_OVERRIDE {
+        if (!this->INHERITED::validContext(rec, totalInverse)) {
             return false;
         }
         if (fProxy) {
-            return fProxy->validContext(device, paint, matrix);
+            return fProxy->validContext(rec);
         }
         return true;
     }
 
-    virtual SkShader::Context* createContext(const SkBitmap& device,
-                                             const SkPaint& paint,
-                                             const SkMatrix& matrix,
-                                             void* storage) const SK_OVERRIDE
+    virtual SkShader::Context* createContext(const ContextRec& rec, void* storage) const SK_OVERRIDE
     {
-        if (!this->validContext(device, paint, matrix)) {
+        if (!this->validContext(rec, NULL)) {
             return NULL;
         }
 
         SkShader::Context* proxyContext;
         if (fProxy) {
             char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext);
-            proxyContext = fProxy->createContext(device, paint, matrix, proxyContextStorage);
+            proxyContext = fProxy->createContext(rec, proxyContextStorage);
             SkASSERT(proxyContext);
         } else {
             proxyContext = NULL;
         }
-        return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, device, paint, matrix,
-                                                                 proxyContext));
+        return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, rec, proxyContext));
     }
 
     class Sk3DShaderContext : public SkShader::Context {
     public:
         // Calls proxyContext's destructor but will NOT free its memory.
-        Sk3DShaderContext(const Sk3DShader& shader, const SkBitmap& device, const SkPaint& paint,
-                          const SkMatrix& matrix, SkShader::Context* proxyContext)
-            : INHERITED(shader, device, paint, matrix)
+        Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec,
+                          SkShader::Context* proxyContext)
+            : INHERITED(shader, rec)
             , fMask(NULL)
             , fProxyContext(proxyContext)
         {
             if (!fProxyContext) {
-                fPMColor = SkPreMultiplyColor(paint.getColor());
+                fPMColor = SkPreMultiplyColor(rec.fPaint->getColor());
             }
         }
 
@@ -954,9 +947,10 @@
      */
     SkShader::Context* shaderContext;
     if (shader) {
+        SkShader::ContextRec rec(device, *paint, matrix);
         // Try to create the ShaderContext
         void* storage = allocator->reserveT<SkShader::Context>(shader->contextSize());
-        shaderContext = shader->createContext(device, *paint, matrix, storage);
+        shaderContext = shader->createContext(rec, storage);
         if (!shaderContext) {
             allocator->freeLast();
             blitter = allocator->createT<SkNullBlitter>();
@@ -1040,7 +1034,8 @@
 
 bool SkShaderBlitter::resetShaderContext(const SkBitmap& device, const SkPaint& paint,
                                          const SkMatrix& matrix) {
-    if (!fShader->validContext(device, paint, matrix)) {
+    SkShader::ContextRec rec(device, paint, matrix);
+    if (!fShader->validContext(rec)) {
         return false;
     }
 
@@ -1050,7 +1045,7 @@
     // 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(device, paint, matrix, (void*)fShaderContext);
+    fShaderContext = fShader->createContext(rec, (void*)fShaderContext);
     SkASSERT(fShaderContext);
 
     return true;
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index 2c27c9e..33c0912 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -78,11 +78,8 @@
     really is translucent, then we apply that after the fact.
 
  */
-bool SkComposeShader::validContext(const SkBitmap& device,
-                                   const SkPaint& paint,
-                                   const SkMatrix& matrix,
-                                   SkMatrix* totalInverse) const {
-    if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+bool SkComposeShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+    if (!this->INHERITED::validContext(rec, totalInverse)) {
         return false;
     }
 
@@ -90,48 +87,49 @@
     // before calling our sub-shaders
 
     SkMatrix tmpM;
+    tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix());
 
-    tmpM.setConcat(matrix, this->getLocalMatrix());
+    ContextRec newRec(rec);
+    newRec.fMatrix = &tmpM;
 
-    return fShaderA->validContext(device, paint, tmpM) &&
-           fShaderB->validContext(device, paint, tmpM);
+    return fShaderA->validContext(newRec) && fShaderB->validContext(newRec);
 }
 
-SkShader::Context* SkComposeShader::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                  const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    // we preconcat our localMatrix (if any) with the device matrix
-    // before calling our sub-shaders
-
-    SkMatrix tmpM;
-
-    tmpM.setConcat(matrix, this->getLocalMatrix());
-
-    SkAutoAlphaRestore  restore(const_cast<SkPaint*>(&paint), 0xFF);
+    // TODO : must fix this to not "cheat" and modify fPaint
+    SkAutoAlphaRestore  restore(const_cast<SkPaint*>(rec.fPaint), 0xFF);
 
     char* aStorage = (char*) storage + sizeof(ComposeShaderContext);
     char* bStorage = aStorage + fShaderA->contextSize();
 
-    SkShader::Context* contextA = fShaderA->createContext(device, paint, tmpM, aStorage);
-    SkShader::Context* contextB = fShaderB->createContext(device, paint, tmpM, bStorage);
+    // 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;
+
+    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);
 
-    return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext,
-                                (*this, device, paint, matrix, contextA, contextB));
+    return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, contextA, contextB));
 }
 
 SkComposeShader::ComposeShaderContext::ComposeShaderContext(
-        const SkComposeShader& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix,
+        const SkComposeShader& shader, const ContextRec& rec,
         SkShader::Context* contextA, SkShader::Context* contextB)
-    : INHERITED(shader, device, paint, matrix)
+    : INHERITED(shader, rec)
     , fShaderContextA(contextA)
     , fShaderContextB(contextB) {}
 
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index f9e06e5..c4f5f74 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -2353,14 +2353,12 @@
 public:
     SkTriColorShader() {}
 
-    virtual SkShader::Context* createContext(
-            const SkBitmap&, const SkPaint&, const SkMatrix&, void*) const SK_OVERRIDE;
+    virtual SkShader::Context* createContext(const ContextRec&, void*) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class TriColorShaderContext : public SkShader::Context {
     public:
-        TriColorShaderContext(const SkTriColorShader& shader, const SkBitmap& device,
-                              const SkPaint& paint, const SkMatrix& matrix);
+        TriColorShaderContext(const SkTriColorShader& shader, const ContextRec&);
         virtual ~TriColorShaderContext();
 
         bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
@@ -2384,13 +2382,12 @@
     typedef SkShader INHERITED;
 };
 
-SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                   const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTriColorShader::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, rec));
 }
 
 bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const SkColor colors[],
@@ -2430,10 +2427,9 @@
 }
 
 
-SkTriColorShader::TriColorShaderContext::TriColorShaderContext(
-        const SkTriColorShader& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix) {}
+SkTriColorShader::TriColorShaderContext::TriColorShaderContext(const SkTriColorShader& shader,
+                                                               const ContextRec& rec)
+    : INHERITED(shader, rec) {}
 
 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
 
diff --git a/src/core/SkFilterShader.cpp b/src/core/SkFilterShader.cpp
index 5c5e8f3..f1cc68d 100644
--- a/src/core/SkFilterShader.cpp
+++ b/src/core/SkFilterShader.cpp
@@ -55,41 +55,30 @@
     return shaderF;
 }
 
-SkShader::Context* SkFilterShader::createContext(const SkBitmap& device,
-                                                 const SkPaint& paint,
-                                                 const SkMatrix& matrix,
-                                                 void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkFilterShader::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec, NULL)) {
         return NULL;
     }
 
     char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext);
-    SkShader::Context* shaderContext = fShader->createContext(device, paint, matrix,
-                                                              shaderContextStorage);
+    SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage);
     SkASSERT(shaderContext);
 
-    return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext,
-                                (*this, shaderContext, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext, (*this, shaderContext, rec));
 }
 
 size_t SkFilterShader::contextSize() const {
     return sizeof(FilterShaderContext) + fShader->contextSize();
 }
 
-bool SkFilterShader::validContext(const SkBitmap& device,
-                                  const SkPaint& paint,
-                                  const SkMatrix& matrix,
-                                  SkMatrix* totalInverse) const {
-    return this->INHERITED::validContext(device, paint, matrix, totalInverse) &&
-           fShader->validContext(device, paint, matrix);
+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 SkBitmap& device,
-                                                         const SkPaint& paint,
-                                                         const SkMatrix& matrix)
-    : INHERITED(filterShader, device, paint, matrix)
+                                                         const ContextRec& rec)
+    : INHERITED(filterShader, rec)
     , fShaderContext(shaderContext) {}
 
 SkFilterShader::FilterShaderContext::~FilterShaderContext() {
diff --git a/src/core/SkFilterShader.h b/src/core/SkFilterShader.h
index 4ef4577..629f3f8 100644
--- a/src/core/SkFilterShader.h
+++ b/src/core/SkFilterShader.h
@@ -17,17 +17,14 @@
     SkFilterShader(SkShader* shader, SkColorFilter* filter);
     virtual ~SkFilterShader();
 
-    virtual bool validContext(const SkBitmap&, const SkPaint&,
-                              const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
-    virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&,
-                                             const SkMatrix&, void* storage) 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;
 
     class FilterShaderContext : public SkShader::Context {
     public:
         // Takes ownership of shaderContext and calls its destructor.
-        FilterShaderContext(const SkFilterShader& filterShader, SkShader::Context* shaderContext,
-                            const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix);
+        FilterShaderContext(const SkFilterShader&, SkShader::Context*, const ContextRec&);
         virtual ~FilterShaderContext();
 
         virtual uint32_t getFlags() const SK_OVERRIDE;
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index 466c5e1..27cbb00 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -106,35 +106,31 @@
     return fCachedBitmapShader;
 }
 
-SkShader* SkPictureShader::validInternal(const SkBitmap& device, const SkPaint& paint,
-                                         const SkMatrix& matrix, SkMatrix* totalInverse) const {
-    if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) {
+SkShader* SkPictureShader::validInternal(const ContextRec& rec, SkMatrix* totalInverse) const {
+    if (!this->INHERITED::validContext(rec, totalInverse)) {
         return NULL;
     }
 
-    SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(matrix));
-    if (!bitmapShader || !bitmapShader->validContext(device, paint, matrix)) {
+    SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix));
+    if (!bitmapShader || !bitmapShader->validContext(rec)) {
         return NULL;
     }
 
     return bitmapShader.detach();
 }
 
-bool SkPictureShader::validContext(const SkBitmap& device, const SkPaint& paint,
-                                   const SkMatrix& matrix, SkMatrix* totalInverse) const {
-    SkAutoTUnref<SkShader> shader(this->validInternal(device, paint, matrix, totalInverse));
+bool SkPictureShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+    SkAutoTUnref<SkShader> shader(this->validInternal(rec, totalInverse));
     return shader != NULL;
 }
 
-SkShader::Context* SkPictureShader::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                  const SkMatrix& matrix, void* storage) const {
-    SkAutoTUnref<SkShader> bitmapShader(this->validInternal(device, paint, matrix, NULL));
+SkShader::Context* SkPictureShader::createContext(const ContextRec& rec, void* storage) const {
+    SkAutoTUnref<SkShader> bitmapShader(this->validInternal(rec, NULL));
     if (!bitmapShader) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext,
-                                (*this, device, paint, matrix, bitmapShader.detach()));
+    return SkNEW_PLACEMENT_ARGS(storage, PictureShaderContext, (*this, rec, bitmapShader.detach()));
 }
 
 size_t SkPictureShader::contextSize() const {
@@ -142,15 +138,13 @@
 }
 
 SkPictureShader::PictureShaderContext::PictureShaderContext(
-        const SkPictureShader& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix, SkShader* bitmapShader)
-    : INHERITED(shader, device, paint, matrix)
+        const SkPictureShader& shader, const ContextRec& rec, SkShader* bitmapShader)
+    : INHERITED(shader, rec)
     , fBitmapShader(bitmapShader)
 {
     SkASSERT(fBitmapShader);
     fBitmapShaderContextStorage = sk_malloc_throw(fBitmapShader->contextSize());
-    fBitmapShaderContext = fBitmapShader->createContext(
-            device, paint, matrix, fBitmapShaderContextStorage);
+    fBitmapShaderContext = fBitmapShader->createContext(rec, fBitmapShaderContextStorage);
     SkASSERT(fBitmapShaderContext);
 }
 
diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h
index d1be059..510c988 100644
--- a/src/core/SkPictureShader.h
+++ b/src/core/SkPictureShader.h
@@ -24,18 +24,13 @@
     static SkPictureShader* Create(SkPicture*, TileMode, TileMode);
     virtual ~SkPictureShader();
 
-    virtual bool validContext(const SkBitmap&, const SkPaint&,
-                              const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
-    virtual SkShader::Context* createContext(const SkBitmap& device, const SkPaint& paint,
-                                             const SkMatrix& matrix, void* storage) 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;
 
     class PictureShaderContext : public SkShader::Context {
     public:
-        PictureShaderContext(const SkPictureShader& shader, const SkBitmap& device,
-                             const SkPaint& paint, const SkMatrix& matrix,
-                             SkShader* bitmapShader);
+        PictureShaderContext(const SkPictureShader&, const ContextRec&, SkShader* bitmapShader);
         virtual ~PictureShaderContext();
 
         virtual uint32_t getFlags() const SK_OVERRIDE;
@@ -66,9 +61,7 @@
 private:
     SkPictureShader(SkPicture*, TileMode, TileMode);
 
-    SkShader* validInternal(const SkBitmap& device, const SkPaint& paint,
-                            const SkMatrix& matrix, SkMatrix* totalInverse) const;
-
+    SkShader* validInternal(const ContextRec&, SkMatrix* totalInverse) const;
     SkShader* refBitmapShader(const SkMatrix&) const;
 
     SkPicture*  fPicture;
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index a449d0f..0f6ba4c 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -56,15 +56,11 @@
     return m->invert(totalInverse);
 }
 
-bool SkShader::validContext(const SkBitmap& device,
-                            const SkPaint& paint,
-                            const SkMatrix& matrix,
-                            SkMatrix* totalInverse) const {
-    return this->computeTotalInverse(matrix, totalInverse);
+bool SkShader::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
+    return this->computeTotalInverse(*rec.fMatrix, totalInverse);
 }
 
-SkShader::Context* SkShader::createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
-                                           void* storage) const {
+SkShader::Context* SkShader::createContext(const ContextRec&, void* storage) const {
     return NULL;
 }
 
@@ -72,18 +68,17 @@
     return 0;
 }
 
-SkShader::Context::Context(const SkShader& shader, const SkBitmap& device,
-                           const SkPaint& paint, const SkMatrix& matrix)
+SkShader::Context::Context(const SkShader& shader, const ContextRec& rec)
     : fShader(shader)
 {
-    SkASSERT(fShader.validContext(device, paint, matrix));
+    SkASSERT(fShader.validContext(rec));
 
     // Because the context parameters must be valid at this point, we know that the matrix is
     // invertible.
-    SkAssertResult(fShader.computeTotalInverse(matrix, &fTotalInverse));
+    SkAssertResult(fShader.computeTotalInverse(*rec.fMatrix, &fTotalInverse));
     fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
 
-    fPaintAlpha = paint.getAlpha();
+    fPaintAlpha = rec.fPaint->getAlpha();
 }
 
 SkShader::Context::~Context() {}
@@ -250,23 +245,20 @@
     return SkGetPackedA32(fPMColor);
 }
 
-SkShader::Context* SkColorShader::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkColorShader::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, rec));
 }
 
 SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader,
-                                                      const SkBitmap& device,
-                                                      const SkPaint& paint,
-                                                      const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix)
+                                                      const ContextRec& rec)
+    : INHERITED(shader, rec)
 {
     SkColor color = shader.fColor;
-    unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(paint.getAlpha()));
+    unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha()));
 
     unsigned r = SkColorGetR(color);
     unsigned g = SkColorGetG(color);
@@ -285,7 +277,7 @@
     fFlags = kConstInY32_Flag;
     if (255 == a) {
         fFlags |= kOpaqueAlpha_Flag;
-        if (paint.isDither() == false) {
+        if (rec.fPaint->isDither() == false) {
             fFlags |= kHasSpan16_Flag;
         }
     }
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index 5adb582..a4944fb 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -425,13 +425,12 @@
     return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
 }
 
-SkShader::Context* SkPerlinNoiseShader::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                      const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkPerlinNoiseShader::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, PerlinNoiseShaderContext, (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, PerlinNoiseShaderContext, (*this, rec));
 }
 
 size_t SkPerlinNoiseShader::contextSize() const {
@@ -439,11 +438,10 @@
 }
 
 SkPerlinNoiseShader::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
-        const SkPerlinNoiseShader& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix)
+        const SkPerlinNoiseShader& shader, const ContextRec& rec)
+    : INHERITED(shader, rec)
 {
-    SkMatrix newMatrix = matrix;
+    SkMatrix newMatrix = *rec.fMatrix;
     newMatrix.postConcat(shader.getLocalMatrix());
     SkMatrix invMatrix;
     if (!newMatrix.invert(&invMatrix)) {
diff --git a/src/effects/SkTransparentShader.cpp b/src/effects/SkTransparentShader.cpp
index 0997e62..9a390ad 100644
--- a/src/effects/SkTransparentShader.cpp
+++ b/src/effects/SkTransparentShader.cpp
@@ -11,15 +11,12 @@
 #include "SkColorPriv.h"
 #include "SkString.h"
 
-SkShader::Context* SkTransparentShader::createContext(const SkBitmap& device,
-                                                      const SkPaint& paint,
-                                                      const SkMatrix& matrix,
-                                                      void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTransparentShader::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, TransparentShaderContext, (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, TransparentShaderContext, (*this, rec));
 }
 
 size_t SkTransparentShader::contextSize() const {
@@ -27,10 +24,9 @@
 }
 
 SkTransparentShader::TransparentShaderContext::TransparentShaderContext(
-        const SkTransparentShader& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix)
-    , fDevice(&device) {}
+        const SkTransparentShader& shader, const ContextRec& rec)
+    : INHERITED(shader, rec)
+    , fDevice(rec.fDevice) {}
 
 SkTransparentShader::TransparentShaderContext::~TransparentShaderContext() {}
 
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 6d753a9..d376b22 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -253,9 +253,8 @@
 }
 
 SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext(
-        const SkGradientShaderBase& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix)
+        const SkGradientShaderBase& shader, const ContextRec& rec)
+    : INHERITED(shader, rec)
     , fCache(shader.refCache(getPaintAlpha()))
 {
     const SkMatrix& inverse = this->getTotalInverse();
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index c1e253f..a699c4c 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -142,9 +142,7 @@
 
     class GradientShaderBaseContext : public SkShader::Context {
     public:
-        GradientShaderBaseContext(const SkGradientShaderBase& shader, const SkBitmap& device,
-                                  const SkPaint& paint, const SkMatrix& matrix);
-        ~GradientShaderBaseContext() {}
+        GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
 
         virtual uint32_t getFlags() const SK_OVERRIDE { return fFlags; }
 
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 70bbbf3..b9de651 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -76,24 +76,22 @@
     return sizeof(LinearGradientContext);
 }
 
-SkShader::Context* SkLinearGradient::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                   const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkLinearGradient::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, LinearGradientContext, (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, LinearGradientContext, (*this, rec));
 }
 
 SkLinearGradient::LinearGradientContext::LinearGradientContext(
-        const SkLinearGradient& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix)
+        const SkLinearGradient& shader, const ContextRec& rec)
+    : INHERITED(shader, rec)
 {
     unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
     if ((fDstToIndex.getType() & ~mask) == 0) {
         // when we dither, we are (usually) not const-in-Y
-        if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) {
+        if ((fFlags & SkShader::kHasSpan16_Flag) && !rec.fPaint->isDither()) {
             // only claim this if we do have a 16bit mode (i.e. none of our
             // colors have alpha), and if we are not dithering (which obviously
             // is not const in Y).
diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h
index 699d76e..d9ffc77 100644
--- a/src/effects/gradients/SkLinearGradient.h
+++ b/src/effects/gradients/SkLinearGradient.h
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2012 Google Inc.
  *
@@ -15,14 +14,12 @@
 public:
     SkLinearGradient(const SkPoint pts[2], const Descriptor&, const SkMatrix* localMatrix);
 
-    virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
-                                             void* storage) const SK_OVERRIDE;
+    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class LinearGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
     public:
-        LinearGradientContext(const SkLinearGradient& shader, const SkBitmap& device,
-                              const SkPaint& paint, const SkMatrix& matrix);
+        LinearGradientContext(const SkLinearGradient&, const ContextRec&);
         ~LinearGradientContext() {}
 
         virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index f13d55c..07ee680 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -161,19 +161,17 @@
     return sizeof(RadialGradientContext);
 }
 
-SkShader::Context* SkRadialGradient::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                   const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkRadialGradient::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, RadialGradientContext, (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, RadialGradientContext, (*this, rec));
 }
 
 SkRadialGradient::RadialGradientContext::RadialGradientContext(
-        const SkRadialGradient& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix) {}
+        const SkRadialGradient& shader, const ContextRec& rec)
+    : INHERITED(shader, rec) {}
 
 void SkRadialGradient::RadialGradientContext::shadeSpan16(int x, int y, uint16_t* dstCParam,
                                                           int count) {
diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h
index 7aafe2d..8730247 100644
--- a/src/effects/gradients/SkRadialGradient.h
+++ b/src/effects/gradients/SkRadialGradient.h
@@ -16,15 +16,12 @@
     SkRadialGradient(const SkPoint& center, SkScalar radius, const Descriptor&,
                      const SkMatrix* localMatrix);
 
-    virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
-                                             void* storage) const SK_OVERRIDE;
+    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class RadialGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
     public:
-        RadialGradientContext(const SkRadialGradient& shader, const SkBitmap& device,
-                              const SkPaint& paint, const SkMatrix& matrix);
-        ~RadialGradientContext() {}
+        RadialGradientContext(const SkRadialGradient&, const ContextRec&);
 
         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;
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index a65631c..0baf5c7 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -56,19 +56,17 @@
     return sizeof(SweepGradientContext);
 }
 
-SkShader::Context* SkSweepGradient::createContext(const SkBitmap& device, const SkPaint& paint,
-                                                  const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkSweepGradient::createContext(const ContextRec& rec, void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, SweepGradientContext, (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, SweepGradientContext, (*this, rec));
 }
 
 SkSweepGradient::SweepGradientContext::SweepGradientContext(
-        const SkSweepGradient& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix) {}
+        const SkSweepGradient& shader, const ContextRec& rec)
+    : INHERITED(shader, rec) {}
 
 //  returns angle in a circle [0..2PI) -> [0..255]
 static unsigned SkATan2_255(float y, float x) {
diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h
index 15c5b63..9ddd1e2 100644
--- a/src/effects/gradients/SkSweepGradient.h
+++ b/src/effects/gradients/SkSweepGradient.h
@@ -16,15 +16,12 @@
     SkSweepGradient(SkScalar cx, SkScalar cy, const Descriptor&,
                     const SkMatrix* localMatrix);
 
-    virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
-                                             void* storage) const SK_OVERRIDE;
+    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class SweepGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
     public:
-        SweepGradientContext(const SkSweepGradient& shader, const SkBitmap& device,
-                             const SkPaint& paint, const SkMatrix& matrix);
-        ~SweepGradientContext() {}
+        SweepGradientContext(const SkSweepGradient& shader, const ContextRec&);
 
         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;
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index 9d1f8f1..e9c2efe 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -221,21 +221,18 @@
     return sizeof(TwoPointConicalGradientContext);
 }
 
-SkShader::Context* SkTwoPointConicalGradient::createContext(
-        const SkBitmap& device, const SkPaint& paint,
-        const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTwoPointConicalGradient::createContext(const ContextRec& rec,
+                                                            void* storage) const {
+    if (!this->validContext(rec)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, TwoPointConicalGradientContext,
-                                (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, TwoPointConicalGradientContext, (*this, rec));
 }
 
 SkTwoPointConicalGradient::TwoPointConicalGradientContext::TwoPointConicalGradientContext(
-        const SkTwoPointConicalGradient& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix)
+        const SkTwoPointConicalGradient& shader, const ContextRec& rec)
+    : INHERITED(shader, rec)
 {
     // we don't have a span16 proc
     fFlags &= ~kHasSpan16_Flag;
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h
index 13ce3ea..1c5e409 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.h
+++ b/src/effects/gradients/SkTwoPointConicalGradient.h
@@ -48,16 +48,12 @@
                               const SkMatrix* localMatrix);
 
 
-    virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
-                                             void* storage) const SK_OVERRIDE;
+    virtual SkShader::Context* createContext(const ContextRec&, void* storage) const SK_OVERRIDE;
     virtual size_t contextSize() const SK_OVERRIDE;
 
     class TwoPointConicalGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
     public:
-        TwoPointConicalGradientContext(const SkTwoPointConicalGradient& shader,
-                                       const SkBitmap& device,
-                                       const SkPaint& paint,
-                                       const SkMatrix& matrix);
+        TwoPointConicalGradientContext(const SkTwoPointConicalGradient&, const ContextRec&);
         ~TwoPointConicalGradientContext() {}
 
         virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 41e577f..f691db2 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -224,31 +224,27 @@
     return sizeof(TwoPointRadialGradientContext);
 }
 
-bool SkTwoPointRadialGradient::validContext(const SkBitmap& device, const SkPaint& paint,
-                                            const SkMatrix& matrix, SkMatrix* totalInverse) const {
+bool SkTwoPointRadialGradient::validContext(const ContextRec& rec, SkMatrix* totalInverse) const {
     // For now, we might have divided by zero, so detect that.
     if (0 == fDiffRadius) {
         return false;
     }
 
-    return this->INHERITED::validContext(device, paint, matrix, totalInverse);
+    return this->INHERITED::validContext(rec, totalInverse);
 }
 
-SkShader::Context* SkTwoPointRadialGradient::createContext(
-        const SkBitmap& device, const SkPaint& paint,
-        const SkMatrix& matrix, void* storage) const {
-    if (!this->validContext(device, paint, matrix)) {
+SkShader::Context* SkTwoPointRadialGradient::createContext(const ContextRec& rec,
+                                                           void* storage) const {
+    if (!this->validContext(rec, NULL)) {
         return NULL;
     }
 
-    return SkNEW_PLACEMENT_ARGS(storage, TwoPointRadialGradientContext,
-                                (*this, device, paint, matrix));
+    return SkNEW_PLACEMENT_ARGS(storage, TwoPointRadialGradientContext, (*this, rec));
 }
 
 SkTwoPointRadialGradient::TwoPointRadialGradientContext::TwoPointRadialGradientContext(
-        const SkTwoPointRadialGradient& shader, const SkBitmap& device,
-        const SkPaint& paint, const SkMatrix& matrix)
-    : INHERITED(shader, device, paint, matrix)
+        const SkTwoPointRadialGradient& shader, const ContextRec& rec)
+    : INHERITED(shader, rec)
 {
     // we don't have a span16 proc
     fFlags &= ~kHasSpan16_Flag;
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h
index 1b387e6..de5b543 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.h
+++ b/src/effects/gradients/SkTwoPointRadialGradient.h
@@ -23,20 +23,13 @@
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
     virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
 
-
     virtual size_t contextSize() const SK_OVERRIDE;
-    virtual bool validContext(const SkBitmap&, const SkPaint&,
-                              const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE;
-    virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, const SkMatrix&,
-                                             void* storage) 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:
-        TwoPointRadialGradientContext(const SkTwoPointRadialGradient& shader,
-                                      const SkBitmap& device,
-                                      const SkPaint& paint,
-                                      const SkMatrix& matrix);
-        ~TwoPointRadialGradientContext() {}
+        TwoPointRadialGradientContext(const SkTwoPointRadialGradient&, const ContextRec&);
 
         virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;