Move SkShader::fLocalMatrix into SkShader constructor.

As a first step towards removing SkShader::setLocalMatrix, which will make
SkShader thread-safe, remove calls to setLocalMatrix that happen immediately
after the shader is being created. Instead, pass the matrix into the constructor
or factory method.

BUG=skia:1976
R=scroggo@google.com, reed@google.com, skyostil@google.com, mtklein@google.com

Author: dominikg@chromium.org

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

git-svn-id: http://skia.googlecode.com/svn/trunk@14401 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gradients_2pt_conical.cpp b/gm/gradients_2pt_conical.cpp
index 93bddb2..7f0467e 100644
--- a/gm/gradients_2pt_conical.cpp
+++ b/gm/gradients_2pt_conical.cpp
@@ -38,7 +38,8 @@
 };
 
 static SkShader* Make2ConicalOutside(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = SkScalarDiv(pts[1].fX - pts[0].fX, 10);
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -47,11 +48,13 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalOutsideFlip(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = SkScalarDiv(pts[1].fX - pts[0].fX, 10);
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -60,89 +63,97 @@
     return SkGradientShader::CreateTwoPointConical(center1, radius1,
                                                    center0, radius0,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalInside(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
-    return SkGradientShader::CreateTwoPointConical(
-                                                  center1, (pts[1].fX - pts[0].fX) / 7,
-                                                  center0, (pts[1].fX - pts[0].fX) / 2,
-                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
+    return SkGradientShader::CreateTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
+                                                   center0, (pts[1].fX - pts[0].fX) / 2,
+                                                   data.fColors, data.fPos, data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalInsideFlip(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
-    return SkGradientShader::CreateTwoPointConical(
-                                                  center0, (pts[1].fX - pts[0].fX) / 2,
-                                                  center1, (pts[1].fX - pts[0].fX) / 7,
-                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
+    return SkGradientShader::CreateTwoPointConical(center0, (pts[1].fX - pts[0].fX) / 2,
+                                                   center1, (pts[1].fX - pts[0].fX) / 7,
+                                                   data.fColors, data.fPos, data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalInsideCenter(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
-    return SkGradientShader::CreateTwoPointConical(
-                                                  center0, (pts[1].fX - pts[0].fX) / 7,
-                                                  center0, (pts[1].fX - pts[0].fX) / 2,
-                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
+    return SkGradientShader::CreateTwoPointConical(center0, (pts[1].fX - pts[0].fX) / 7,
+                                                   center0, (pts[1].fX - pts[0].fX) / 2,
+                                                   data.fColors, data.fPos, data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalZeroRad(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
-    return SkGradientShader::CreateTwoPointConical(
-                                                  center1, 0.f,
-                                                  center0, (pts[1].fX - pts[0].fX) / 2,
-                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
+    return SkGradientShader::CreateTwoPointConical(center1, 0.f,
+                                                   center0, (pts[1].fX - pts[0].fX) / 2,
+                                                   data.fColors, data.fPos, data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalZeroRadFlip(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
-    return SkGradientShader::CreateTwoPointConical(
-                                                  center1, (pts[1].fX - pts[0].fX) / 2,
-                                                  center0, 0.f,
-                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
+    return SkGradientShader::CreateTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 2,
+                                                   center0, 0.f,
+                                                   data.fColors, data.fPos, data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalZeroRadCenter(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
-    return SkGradientShader::CreateTwoPointConical(
-                                                  center0, 0.f,
-                                                  center0, (pts[1].fX - pts[0].fX) / 2,
-                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
+    return SkGradientShader::CreateTwoPointConical(center0, 0.f,
+                                                   center0, (pts[1].fX - pts[0].fX) / 2,
+                                                   data.fColors, data.fPos, data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalZeroRadOutside(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = 0.f;
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -151,11 +162,13 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalZeroRadFlipOutside(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = 0.f;
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -164,11 +177,13 @@
     return SkGradientShader::CreateTwoPointConical(center1, radius1,
                                                    center0, radius0,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalEdgeX(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = SkScalarDiv(pts[1].fX - pts[0].fX, 7);
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -178,11 +193,13 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalEdgeY(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = SkScalarDiv(pts[1].fX - pts[0].fX, 7);
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -192,10 +209,12 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 static SkShader* Make2ConicalZeroRadEdgeX(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = 0.f;
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -205,11 +224,13 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalZeroRadEdgeY(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = 0.f;
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -219,11 +240,13 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalTouchX(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = SkScalarDiv(pts[1].fX - pts[0].fX, 7);
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -233,11 +256,13 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalTouchY(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     SkScalar radius0 = SkScalarDiv(pts[1].fX - pts[0].fX, 7);
     SkScalar radius1 = SkScalarDiv(pts[1].fX - pts[0].fX, 3);
@@ -247,24 +272,27 @@
     return SkGradientShader::CreateTwoPointConical(center0, radius0,
                                                    center1, radius1,
                                                    data.fColors, data.fPos,
-                                                   data.fCount, tm, mapper);
+                                                   data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 static SkShader* Make2ConicalInsideSmallRad(const SkPoint pts[2], const GradData& data,
-                             SkShader::TileMode tm, SkUnitMapper* mapper) {
+                             SkShader::TileMode tm, SkUnitMapper* mapper,
+                             const SkMatrix& localMatrix) {
     SkPoint center0, center1;
     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
                 SkScalarAve(pts[0].fY, pts[1].fY));
     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
-    return SkGradientShader::CreateTwoPointConical(
-                                                  center0, 0.0000000000000000001f,
-                                                  center0, (pts[1].fX - pts[0].fX) / 2,
-                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
+    return SkGradientShader::CreateTwoPointConical(center0, 0.0000000000000000001f,
+                                                   center0, (pts[1].fX - pts[0].fX) / 2,
+                                                   data.fColors, data.fPos, data.fCount, tm, mapper,
+                                                   0, &localMatrix);
 }
 
 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
-                               SkShader::TileMode tm, SkUnitMapper* mapper);
+                               SkShader::TileMode tm, SkUnitMapper* mapper,
+                               const SkMatrix& localMatrix);
 
 static const GradMaker gGradMakersOutside[] = {
     Make2ConicalOutside, Make2ConicalOutsideFlip,
@@ -336,15 +364,14 @@
         for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) {
             canvas->save();
             for (int j = 0; j < count; j++) {
-                SkShader* shader = gradMaker[j](pts, gGradData[i], tm, NULL);
+                SkMatrix scale = SkMatrix::I();
 
                 if (i == 3) { // if the clamp case
-                    SkMatrix scale;
                     scale.setScale(0.5f, 0.5f);
                     scale.postTranslate(25.f, 25.f);
-                    shader->setLocalMatrix(scale);
                 }
 
+                SkShader* shader = gradMaker[j](pts, gGradData[i], tm, NULL, scale);
                 paint.setShader(shader);
                 canvas->drawRect(r, paint);
                 shader->unref();