Make SkShader store localM directly rather than as a separate alloc.

May cause very slight GM changes in gpu two pt radial/conical radients.
Review URL: https://codereview.appspot.com/6821056

git-svn-id: http://skia.googlecode.com/svn/trunk@6221 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 66d9d76..6ea55bc 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -329,10 +329,9 @@
 
     // add the (optional) matrix
     {
-        SkMatrix m;
-        if (this->getLocalMatrix(&m)) {
+        if (this->hasLocalMatrix()) {
             SkString info;
-            m.toDumpString(&info);
+            this->getLocalMatrix().toDumpString(&info);
             str->appendf(" %s", info.c_str());
         }
     }
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index e925ab5..2fe7a20 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -94,8 +94,7 @@
 
     SkMatrix tmpM;
 
-    (void)this->getLocalMatrix(&tmpM);
-    tmpM.setConcat(matrix, tmpM);
+    tmpM.setConcat(matrix, this->getLocalMatrix());
 
     SkAutoAlphaRestore  restore(const_cast<SkPaint*>(&paint), 0xFF);
 
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 885a810..2af86c0 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -2374,8 +2374,11 @@
     VertState::Proc vertProc = state.chooseProc(vmode);
 
     if (NULL != textures || NULL != colors) {
-        SkMatrix  localM, tempM;
-        bool      hasLocalM = shader && shader->getLocalMatrix(&localM);
+        SkMatrix  tempM;
+        SkMatrix  savedLocalM;
+        if (shader) {
+            savedLocalM = shader->getLocalMatrix();
+        }
 
         if (NULL != colors) {
             if (!triShader.setContext(*fBitmap, p, *fMatrix)) {
@@ -2386,9 +2389,7 @@
         while (vertProc(&state)) {
             if (NULL != textures) {
                 if (texture_to_matrix(state, vertices, textures, &tempM)) {
-                    if (hasLocalM) {
-                        tempM.postConcat(localM);
-                    }
+                    tempM.postConcat(savedLocalM);
                     shader->setLocalMatrix(tempM);
                     // need to recal setContext since we changed the local matrix
                     if (!shader->setContext(*fBitmap, p, *fMatrix)) {
@@ -2410,11 +2411,7 @@
         }
         // now restore the shader's original local matrix
         if (NULL != shader) {
-            if (hasLocalM) {
-                shader->setLocalMatrix(localM);
-            } else {
-                shader->resetLocalMatrix();
-            }
+            shader->setLocalMatrix(savedLocalM);
         }
     } else {
         // no colors[] and no texture
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 9c9366b..2b20e3d 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -15,23 +15,24 @@
 
 SK_DEFINE_INST_COUNT(SkShader)
 
-SkShader::SkShader() : fLocalMatrix(NULL) {
+SkShader::SkShader() {
+    fLocalMatrix.reset();
     SkDEBUGCODE(fInSession = false;)
 }
 
 SkShader::SkShader(SkFlattenableReadBuffer& buffer)
-        : INHERITED(buffer), fLocalMatrix(NULL) {
+        : INHERITED(buffer) {
     if (buffer.readBool()) {
-        SkMatrix matrix;
-        buffer.readMatrix(&matrix);
-        setLocalMatrix(matrix);
+        buffer.readMatrix(&fLocalMatrix);
+    } else {
+        fLocalMatrix.reset();
     }
+
     SkDEBUGCODE(fInSession = false;)
 }
 
 SkShader::~SkShader() {
     SkASSERT(!fInSession);
-    sk_free(fLocalMatrix);
 }
 
 void SkShader::beginSession() {
@@ -46,41 +47,10 @@
 
 void SkShader::flatten(SkFlattenableWriteBuffer& buffer) const {
     this->INHERITED::flatten(buffer);
-    buffer.writeBool(fLocalMatrix != NULL);
-    if (fLocalMatrix) {
-        buffer.writeMatrix(*fLocalMatrix);
-    }
-}
-
-bool SkShader::getLocalMatrix(SkMatrix* localM) const {
-    if (fLocalMatrix) {
-        if (localM) {
-            *localM = *fLocalMatrix;
-        }
-        return true;
-    } else {
-        if (localM) {
-            localM->reset();
-        }
-        return false;
-    }
-}
-
-void SkShader::setLocalMatrix(const SkMatrix& localM) {
-    if (localM.isIdentity()) {
-        this->resetLocalMatrix();
-    } else {
-        if (fLocalMatrix == NULL) {
-            fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix));
-        }
-        *fLocalMatrix = localM;
-    }
-}
-
-void SkShader::resetLocalMatrix() {
-    if (fLocalMatrix) {
-        sk_free(fLocalMatrix);
-        fLocalMatrix = NULL;
+    bool hasLocalM = this->hasLocalMatrix();
+    buffer.writeBool(hasLocalM);
+    if (hasLocalM) {
+        buffer.writeMatrix(fLocalMatrix);
     }
 }
 
@@ -92,8 +62,8 @@
 
     fDeviceConfig = SkToU8(device.getConfig());
     fPaintAlpha = paint.getAlpha();
-    if (fLocalMatrix) {
-        total.setConcat(matrix, *fLocalMatrix);
+    if (this->hasLocalMatrix()) {
+        total.setConcat(matrix, this->getLocalMatrix());
         m = &total;
     }
     if (m->invert(&fTotalInverse)) {
diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
index 8e62d49..e1d5eed 100644
--- a/src/device/xps/SkXPSDevice.cpp
+++ b/src/device/xps/SkXPSDevice.cpp
@@ -975,8 +975,7 @@
             return S_OK;
         }
 
-        SkMatrix localMatrix;
-        shader->getLocalMatrix(&localMatrix);
+        SkMatrix localMatrix = shader->getLocalMatrix();
         if (NULL != parentTransform) {
             localMatrix.preConcat(*parentTransform);
         }
@@ -1022,8 +1021,7 @@
             break;
         case SkShader::kDefault_BitmapType: {
             //TODO: outMatrix??
-            SkMatrix localMatrix;
-            shader->getLocalMatrix(&localMatrix);
+            SkMatrix localMatrix = shader->getLocalMatrix();
             if (NULL != parentTransform) {
                 localMatrix.preConcat(*parentTransform);
             }
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 524db76..d957656 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -569,20 +569,12 @@
 
 bool SkLinearGradient::asNewEffect(GrContext* context, GrEffectStage* stage) const {
     SkASSERT(NULL != context && NULL != stage);
-
-    SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode)));
-
     SkMatrix matrix;
-    if (this->getLocalMatrix(&matrix)) {
-        if (!matrix.invert(&matrix)) {
-            return false;
-        }
-        matrix.postConcat(fPtsToUnit);
-        stage->setEffect(effect, matrix);
-    } else {
-        stage->setEffect(effect, fPtsToUnit);
+    if (!this->getLocalMatrix().invert(&matrix)) {
+        return false;
     }
-
+    matrix.postConcat(fPtsToUnit);
+    stage->setEffect(SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode)), matrix)->unref();
     return true;
 }
 
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index 4766af6..a20ea35 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -567,19 +567,13 @@
 
 bool SkRadialGradient::asNewEffect(GrContext* context, GrEffectStage* stage) const {
     SkASSERT(NULL != context && NULL != stage);
-    SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode)));
 
     SkMatrix matrix;
-    if (this->getLocalMatrix(&matrix)) {
-        if (!matrix.invert(&matrix)) {
-            return false;
-        }
-        matrix.postConcat(fPtsToUnit);
-        stage->setEffect(effect, matrix);
-    } else {
-        stage->setEffect(effect, fPtsToUnit);
+    if (!this->getLocalMatrix().invert(&matrix)) {
+        return false;
     }
-
+    matrix.postConcat(fPtsToUnit);
+    stage->setEffect(SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode)), matrix)->unref();
     return true;
 }
 
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index b64e15d..a783e37 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -473,19 +473,12 @@
 /////////////////////////////////////////////////////////////////////
 
 bool SkSweepGradient::asNewEffect(GrContext* context, GrEffectStage* stage) const {
-    SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSweepGradient, (context, *this)));
-
     SkMatrix matrix;
-    if (this->getLocalMatrix(&matrix)) {
-        if (!matrix.invert(&matrix)) {
-            return false;
-        }
-        matrix.postConcat(fPtsToUnit);
-        stage->setEffect(effect, matrix);
-    } else {
-        stage->setEffect(effect, fPtsToUnit);
+    if (!this->getLocalMatrix().invert(&matrix)) {
+        return false;
     }
-
+    matrix.postConcat(fPtsToUnit);
+    stage->setEffect(SkNEW_ARGS(GrSweepGradient, (context, *this)), matrix)->unref();
     return true;
 }
 
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index acd0eee..f93f660 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -677,25 +677,22 @@
 bool SkTwoPointConicalGradient::asNewEffect(GrContext* context,
                                             GrEffectStage* stage) const {
     SkASSERT(NULL != context && NULL != stage);
-
+    SkASSERT(fPtsToUnit.isIdentity());
+    // invert the localM, translate to center1, rotate so center2 is on x axis.
     SkMatrix matrix;
+    if (!this->getLocalMatrix().invert(&matrix)) {
+        return false;
+    }
+    matrix.postTranslate(-fCenter1.fX, -fCenter1.fY);
+
     SkPoint diff = fCenter2 - fCenter1;
     SkScalar diffLen = diff.length();
     if (0 != diffLen) {
         SkScalar invDiffLen = SkScalarInvert(diffLen);
-        matrix.setSinCos(-SkScalarMul(invDiffLen, diff.fY),
-                         SkScalarMul(invDiffLen, diff.fX));
-    } else {
-        matrix.reset();
-    }
-    matrix.preTranslate(-fCenter1.fX, -fCenter1.fY);
-
-    SkMatrix localM;
-    if (this->getLocalMatrix(&localM)) {
-        if (!localM.invert(&localM)) {
-            return false;
-        }
-        matrix.preConcat(localM);
+        SkMatrix rot;
+        rot.setSinCos(-SkScalarMul(invDiffLen, diff.fY),
+                       SkScalarMul(invDiffLen, diff.fX));
+        matrix.postConcat(rot);
     }
 
     stage->setEffect(SkNEW_ARGS(GrConical2Gradient, (context, *this, fTileMode)), matrix)->unref();
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 9357b11..659bce0 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -651,24 +651,20 @@
 bool SkTwoPointRadialGradient::asNewEffect(GrContext* context,
                                            GrEffectStage* stage) const {
     SkASSERT(NULL != context && NULL != stage);
-    SkScalar diffLen = fDiff.length();
+    // invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis.
     SkMatrix matrix;
+    if (!this->getLocalMatrix().invert(&matrix)) {
+        return false;
+    }
+    matrix.postConcat(fPtsToUnit);
+
+    SkScalar diffLen = fDiff.length();
     if (0 != diffLen) {
         SkScalar invDiffLen = SkScalarInvert(diffLen);
-        matrix.setSinCos(-SkScalarMul(invDiffLen, fDiff.fY),
-                         SkScalarMul(invDiffLen, fDiff.fX));
-    } else {
-        matrix.reset();
-    }
-
-    matrix.preConcat(fPtsToUnit);
-
-    SkMatrix localM;
-    if (this->getLocalMatrix(&localM)) {
-        if (!localM.invert(&localM)) {
-            return false;
-        }
-        matrix.preConcat(localM);
+        SkMatrix rot;
+        rot.setSinCos(-SkScalarMul(invDiffLen, fDiff.fY),
+                       SkScalarMul(invDiffLen, fDiff.fX));
+        matrix.postConcat(rot);
     }
 
     stage->setEffect(SkNEW_ARGS(GrRadial2Gradient, (context, *this, fTileMode)), matrix)->unref();
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b0f4ac1..cdccbcd 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -584,6 +584,16 @@
         return false;
     }
 
+    // since our texture coords will be in local space, we whack the texture
+    // matrix to map them back into 0...1 before we load it
+    if (shader->hasLocalMatrix()) {
+        SkMatrix inverse;
+        if (!shader->getLocalMatrix().invert(&inverse)) {
+            return false;
+        }
+        matrix.preConcat(inverse);
+    }
+
     // Must set wrap and filter on the sampler before requesting a texture.
     GrTextureParams params(tileModes, skPaint.isFilterBitmap());
     GrTexture* texture = textures[kShaderTextureIdx].set(dev, bitmap, &params);
@@ -593,15 +603,6 @@
         return false;
     }
 
-    // since our texture coords will be in local space, we whack the texture
-    // matrix to map them back into 0...1 before we load it
-    SkMatrix localM;
-    if (shader->getLocalMatrix(&localM)) {
-        SkMatrix inverse;
-        if (localM.invert(&inverse)) {
-            matrix.preConcat(inverse);
-        }
-    }
     if (SkShader::kDefault_BitmapType == bmptype) {
         GrScalar sx = SkFloatToScalar(1.f / bitmap.width());
         GrScalar sy = SkFloatToScalar(1.f / bitmap.height());
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index ace93ea..db5beb8 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -937,7 +937,7 @@
     fInfo.fColorCount = 0;
     fInfo.fColors = NULL;
     fInfo.fColorOffsets = NULL;
-    shader.getLocalMatrix(&fShaderTransform);
+    fShaderTransform = shader.getLocalMatrix();
     fImageTileModes[0] = fImageTileModes[1] = SkShader::kClamp_TileMode;
 
     fType = shader.asAGradient(&fInfo);