SkShader::asNewEffect Refactoring
The new signature is:
	bool asNewEffect(GrContext* context, const SkPaint& paint, GrColor* grColor, GrEffectRef** grEffect, const SkMatrix* localMatrixOrNull) const;
It will fix the hack for skcolorshader by modifying the GrColor parameter in SkGr::SkPaint2GrPaintShader.
BUG=skia:2646
R=jvanverth@google.com, bsalomon@google.com
Author: dandov@google.com
Review URL: https://codereview.chromium.org/318923005
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index 9e1f39b..0997c0e 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -66,3 +66,7 @@
 # Added by robertphillips for https://codereview.chromium.org/316143003/
 # This CL actually fixes this GM's image
 distantclip
+
+# dandov: Fix for bitmap shader by taking into account if the bitmap is alpha only
+# https://codereview.chromium.org/318923005/
+bitmapshaders
diff --git a/include/core/SkColorShader.h b/include/core/SkColorShader.h
index be59627..8603577 100644
--- a/include/core/SkColorShader.h
+++ b/include/core/SkColorShader.h
@@ -56,6 +56,10 @@
 
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
 
+    virtual bool asNewEffect(GrContext* context, const SkPaint& paint,
+                             const SkMatrix* localMatrix, GrColor* grColor,
+                             GrEffectRef** grEffect) const SK_OVERRIDE;
+
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
 
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 82efab2..31f57cc 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -14,6 +14,7 @@
 #include "SkMask.h"
 #include "SkMatrix.h"
 #include "SkPaint.h"
+#include "../gpu/GrColor.h"
 
 class SkPath;
 class SkPicture;
@@ -373,14 +374,17 @@
 
 
     /**
-     *  If the shader subclass has a GrEffect implementation, this resturns the effect to install.
+     *  Returns true if the shader subclass succeeds in setting the grEffect and the grColor output 
+     *  parameters to a value, returns false if it fails or if there is not an implementation of
+     *  this method in the shader subclass.
      *  The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha.
      *  The output color should be the computed SkShader premul color modulated by the incoming
      *  color. The GrContext may be used by the effect to create textures. The GPU device does not
      *  call createContext. Instead we pass the SkPaint here in case the shader needs paint info.
      */
-    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint,
-                                     const SkMatrix* localMatrixOrNull) const;
+    virtual bool asNewEffect(GrContext* context, const SkPaint& paint,
+                             const SkMatrix* localMatrixOrNull, GrColor* grColor,
+                             GrEffectRef** grEffect) const;
 
 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
     /**
@@ -463,7 +467,7 @@
 
 private:
     SkMatrix fLocalMatrix;
-
+    
     typedef SkFlattenable INHERITED;
 };
 
diff --git a/include/effects/SkPerlinNoiseShader.h b/include/effects/SkPerlinNoiseShader.h
index 63e7415..96cad46 100644
--- a/include/effects/SkPerlinNoiseShader.h
+++ b/include/effects/SkPerlinNoiseShader.h
@@ -95,8 +95,8 @@
         typedef SkShader::Context INHERITED;
     };
 
-    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&,
-                                     const SkMatrix*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrContext* context, const SkPaint&, const SkMatrix*, GrColor*,
+                             GrEffectRef**) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader)
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 7016b1e..835d353 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -67,6 +67,11 @@
     return GrColorPackRGBA(r, g, b, a);
 }
 
+static inline GrColor SkColor2GrColorJustAlpha(SkColor c) {
+    U8CPU a = SkColorGetA(c);
+    return GrColorPackRGBA(a, a, a, a);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 bool GrIsBitmapInCache(const GrContext*, const SkBitmap&, const GrTextureParams*);
@@ -78,12 +83,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 // Converts a SkPaint to a GrPaint, ignoring the SkPaint's shader.
-// justAlpha indicates that the SkPaint's alpha should be used rather than the color.
+// Sets the color of GrPaint to the value of the parameter grColor
 // Callers may subsequently modify the GrPaint. Setting constantColor indicates
 // that the final paint will draw the same color at every pixel. This allows
 // an optimization where the the color filter can be applied to the SkPaint's
 // color once while converting to GrPaint and then ignored.
-void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, bool justAlpha,
+void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor grColor,
                              bool constantColor, GrPaint* grPaint);
 
 // This function is similar to skPaint2GrPaintNoShader but also converts
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 8e25530..8e03a80 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -382,19 +382,20 @@
 #include "effects/GrSimpleTextureEffect.h"
 #include "SkGr.h"
 
-GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                             const SkMatrix* localMatrix) const {
+bool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                     const SkMatrix* localMatrix, GrColor* grColor,
+                                     GrEffectRef** grEffect) const {
     SkMatrix matrix;
     matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height());
 
     SkMatrix lmInverse;
     if (!this->getLocalMatrix().invert(&lmInverse)) {
-        return NULL;
+        return false;
     }
     if (localMatrix) {
         SkMatrix inv;
         if (!localMatrix->invert(&inv)) {
-            return NULL;
+            return false;
         }
         lmInverse.postConcat(inv);
     }
@@ -450,16 +451,29 @@
     if (NULL == texture) {
         SkErrorInternals::SetError( kInternalError_SkError,
                                     "Couldn't convert bitmap to texture.");
-        return NULL;
+        return false;
     }
+    
+    *grColor = (kAlpha_8_SkColorType == fRawBitmap.colorType()) ? SkColor2GrColor(paint.getColor())
+                                        : SkColor2GrColorJustAlpha(paint.getColor());
 
-    GrEffectRef* effect = NULL;
     if (useBicubic) {
-        effect = GrBicubicEffect::Create(texture, matrix, tm);
+        *grEffect = GrBicubicEffect::Create(texture, matrix, tm);
     } else {
-        effect = GrSimpleTextureEffect::Create(texture, matrix, params);
+        *grEffect = GrSimpleTextureEffect::Create(texture, matrix, params);
     }
     GrUnlockAndUnrefCachedBitmapTexture(texture);
-    return effect;
+
+    return true;
 }
+
+#else 
+
+bool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                     const SkMatrix* localMatrix, GrColor* grColor,
+                                     GrEffectRef** grEffect) const {
+    SkDEBUGFAIL("Should not call in GPU-less build");
+    return false;
+}
+
 #endif
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 80e4550..08e8397 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -30,9 +30,9 @@
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader)
 
-#if SK_SUPPORT_GPU
-    GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE;
-#endif
+
+    bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**)
+            const SK_OVERRIDE;
 
     class BitmapProcShaderContext : public SkShader::Context {
     public:
diff --git a/src/core/SkLocalMatrixShader.h b/src/core/SkLocalMatrixShader.h
index 1adfb0a..1143f06 100644
--- a/src/core/SkLocalMatrixShader.h
+++ b/src/core/SkLocalMatrixShader.h
@@ -32,15 +32,27 @@
         return fProxyShader->asAGradient(info);
     }
 
-    virtual GrEffectRef* asNewEffect(GrContext* ctx, const SkPaint& paint,
-                                     const SkMatrix* localMatrix) const SK_OVERRIDE {
+#if SK_SUPPORT_GPU
+    
+    virtual bool asNewEffect(GrContext* context, const SkPaint& paint, const SkMatrix* localMatrix,
+                             GrColor* grColor, GrEffectRef** grEffect) const SK_OVERRIDE {
         SkMatrix tmp = fProxyLocalMatrix;
         if (localMatrix) {
             tmp.preConcat(*localMatrix);
         }
-        return fProxyShader->asNewEffect(ctx, paint, &tmp);
+        return fProxyShader->asNewEffect(context, paint, &tmp, grColor, grEffect);
     }
-
+    
+#else 
+    
+    virtual bool asNewEffect(GrContext* context, const SkPaint& paint, const SkMatrix* localMatrix,
+                             GrColor* grColor, GrEffectRef** grEffect) const SK_OVERRIDE {
+        SkDEBUGFAIL("Should not call in GPU-less build");
+        return false;
+    }
+    
+#endif
+    
     virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const SK_OVERRIDE {
         if (localMatrix) {
             *localMatrix = fProxyLocalMatrix;
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index 81e1375..2de8d4d 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -188,12 +188,20 @@
 #endif
 
 #if SK_SUPPORT_GPU
-GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                          const SkMatrix* localMatrix) const {
+bool SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                  const SkMatrix* localMatrix, GrColor* grColor,
+                                  GrEffectRef** grEffect) const {
     SkAutoTUnref<SkShader> bitmapShader(this->refBitmapShader(context->getMatrix(), localMatrix));
     if (!bitmapShader) {
-        return NULL;
+        return false;
     }
-    return bitmapShader->asNewEffect(context, paint, NULL);
+    return bitmapShader->asNewEffect(context, paint, NULL, grColor, grEffect);
+}
+#else
+bool SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                  const SkMatrix* localMatrix, GrColor* grColor,
+                                  GrEffectRef** grEffect) const {
+    SkDEBUGFAIL("Should not call in GPU-less build");
+    return false;
 }
 #endif
diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h
index 936a69e..294ffcd 100644
--- a/src/core/SkPictureShader.h
+++ b/src/core/SkPictureShader.h
@@ -29,9 +29,8 @@
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureShader)
 
-#if SK_SUPPORT_GPU
-    GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE;
-#endif
+    bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**)
+        const SK_OVERRIDE;
 
 protected:
     SkPictureShader(SkReadBuffer&);
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 9484db5..18fb0d2 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -208,8 +208,10 @@
     return kNone_GradientType;
 }
 
-GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const {
-    return NULL;
+bool SkShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                           const SkMatrix* localMatrixOrNull, GrColor* grColor,
+                           GrEffectRef** grEffect)  const {
+    return false;
 }
 
 SkShader* SkShader::refAsALocalMatrixShader(SkMatrix*) const {
@@ -341,6 +343,31 @@
     return kColor_GradientType;
 }
 
+#if SK_SUPPORT_GPU
+
+#include "SkGr.h"
+
+bool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                const SkMatrix* localMatrix, GrColor* grColor,
+                                GrEffectRef** grEffect) const {
+    *grEffect = NULL;
+    SkColor skColor = fColor;
+    U8CPU newA = SkMulDiv255Round(SkColorGetA(fColor), paint.getAlpha());
+    *grColor = SkColor2GrColor(SkColorSetA(skColor, newA));
+    return true;
+}
+
+#else
+
+bool SkColorShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                     const SkMatrix* localMatrix, GrColor* grColor,
+                                     GrEffectRef** grEffect) const {
+    SkDEBUGFAIL("Should not call in GPU-less build");
+    return false;
+}
+
+#endif
+
 #ifndef SK_IGNORE_TO_STRING
 void SkColorShader::toString(SkString* str) const {
     str->append("SkColorShader: (");
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index a37dff5..bc24061 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -726,7 +726,9 @@
                                              stitchTiles ? &tileSize : NULL);
 
     SkPaint paint;
-    GrEffectRef* effect = shader->asNewEffect(context, paint, NULL);
+    GrColor grColor;
+    GrEffectRef* effect;
+    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
 
     SkDELETE(shader);
 
@@ -1278,10 +1280,13 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint,
-                                              const SkMatrix* externalLocalMatrix) const {
+bool SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                      const SkMatrix* externalLocalMatrix, GrColor* grColor,
+                                      GrEffectRef** grEffect) const {
     SkASSERT(NULL != context);
-
+    
+    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    
     SkMatrix localMatrix = this->getLocalMatrix();
     if (externalLocalMatrix) {
         localMatrix.preConcat(*externalLocalMatrix);
@@ -1294,7 +1299,8 @@
         }
         SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(
                                                 clearColor, SkXfermode::kSrc_Mode));
-        return cf->asNewEffect(context);
+        *grEffect = cf->asNewEffect(context);
+        return true;
     }
 
     // Either we don't stitch tiles, either we have a valid tile size
@@ -1303,7 +1309,7 @@
 #ifdef SK_USE_SIMPLEX_NOISE
     // Simplex noise is currently disabled but can be enabled by defining SK_USE_SIMPLEX_NOISE
     sk_ignore_unused_variable(context);
-    GrEffectRef* effect =
+    *grEffect =
         GrSimplexNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
                                      fNumOctaves, fStitchTiles, fSeed,
                                      this->getLocalMatrix(), paint.getAlpha());
@@ -1313,7 +1319,7 @@
     GrTexture* noiseTexture = GrLockAndRefCachedBitmapTexture(
         context, fPaintingData->getNoiseBitmap(), NULL);
 
-    GrEffectRef* effect = (NULL != permutationsTexture) && (NULL != noiseTexture) ?
+    *grEffect = (NULL != permutationsTexture) && (NULL != noiseTexture) ?
         GrPerlinNoiseEffect::Create(fType, fPaintingData->fBaseFrequency,
                                     fNumOctaves, fStitchTiles,
                                     fPaintingData->fStitchDataInit,
@@ -1332,14 +1338,16 @@
     }
 #endif
 
-    return effect;
+    return true;
 }
 
 #else
 
-GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const {
+bool SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint,
+                                      const SkMatrix* externalLocalMatrix, GrColor* grColor,
+                                      GrEffectRef** grEffect) const {
     SkDEBUGFAIL("Should not call in GPU-less build");
-    return NULL;
+    return false;
 }
 
 #endif
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 4766364..72b9d47 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -446,6 +446,7 @@
 #if SK_SUPPORT_GPU
 
 #include "GrTBackendEffectFactory.h"
+#include "SkGr.h"
 
 /////////////////////////////////////////////////////////////////////
 
@@ -527,7 +528,10 @@
                                                                  colors, stops, colorCount,
                                                                  tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrColor grColor;
+    GrEffectRef* effect;
+    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    return effect;
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -547,29 +551,37 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffectRef* SkLinearGradient::asNewEffect(GrContext* context, const SkPaint&,
-                                           const SkMatrix* localMatrix) const {
+bool SkLinearGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                   const SkMatrix* localMatrix, GrColor* grColor,
+                                   GrEffectRef** grEffect)  const {
     SkASSERT(NULL != context);
+    
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
-        return NULL;
+        return false;
     }
     if (localMatrix) {
         SkMatrix inv;
         if (!localMatrix->invert(&inv)) {
-            return NULL;
+            return false;
         }
         matrix.postConcat(inv);
     }
     matrix.postConcat(fPtsToUnit);
-    return GrLinearGradient::Create(context, *this, matrix, fTileMode);
+    
+    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *grEffect = GrLinearGradient::Create(context, *this, matrix, fTileMode);
+    
+    return true;
 }
 
 #else
 
-GrEffectRef* SkLinearGradient::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const {
+bool SkLinearGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                   const SkMatrix* localMatrix, GrColor* grColor,
+                                   GrEffectRef** grEffect)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
-    return NULL;
+    return false;
 }
 
 #endif
diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h
index 432dac0..f412a68 100644
--- a/src/effects/gradients/SkLinearGradient.h
+++ b/src/effects/gradients/SkLinearGradient.h
@@ -30,7 +30,8 @@
 
     virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrContext* context, const SkPaint& paint, const SkMatrix* localMatrix,
+                             GrColor* grColor, GrEffectRef** grEffect) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient)
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index 3b9d175..f0cb161 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -458,6 +458,7 @@
 #if SK_SUPPORT_GPU
 
 #include "GrTBackendEffectFactory.h"
+#include "SkGr.h"
 
 class GrGLRadialGradient : public GrGLGradientEffect {
 public:
@@ -538,7 +539,10 @@
                                                                  colors, stops, colorCount,
                                                                  tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrColor grColor;
+    GrEffectRef* effect;
+    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    return effect;
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -559,30 +563,37 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffectRef* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&,
-                                           const SkMatrix* localMatrix) const {
+bool SkRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                   const SkMatrix* localMatrix, GrColor* grColor,
+                                   GrEffectRef** grEffect) const {
     SkASSERT(NULL != context);
-
+    
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
-        return NULL;
+        return false;
     }
     if (localMatrix) {
         SkMatrix inv;
         if (!localMatrix->invert(&inv)) {
-            return NULL;
+            return false;
         }
         matrix.postConcat(inv);
     }
     matrix.postConcat(fPtsToUnit);
-    return GrRadialGradient::Create(context, *this, matrix, fTileMode);
+    
+    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *grEffect = GrRadialGradient::Create(context, *this, matrix, fTileMode);
+    
+    return true;
 }
 
 #else
 
-GrEffectRef* SkRadialGradient::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const {
+bool SkRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                   const SkMatrix* localMatrix, GrColor* grColor,
+                                   GrEffectRef** grEffect) const {
     SkDEBUGFAIL("Should not call in GPU-less build");
-    return NULL;
+    return false;
 }
 
 #endif
diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h
index aade31e..197c967 100644
--- a/src/effects/gradients/SkRadialGradient.h
+++ b/src/effects/gradients/SkRadialGradient.h
@@ -33,7 +33,7 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**) const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialGradient)
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index 3dddbba..154e3a2 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -174,6 +174,7 @@
 #if SK_SUPPORT_GPU
 
 #include "GrTBackendEffectFactory.h"
+#include "SkGr.h"
 
 class GrGLSweepGradient : public GrGLGradientEffect {
 public:
@@ -247,7 +248,10 @@
     SkAutoTUnref<SkShader> shader(SkGradientShader::CreateSweep(center.fX, center.fY,
                                                                 colors, stops, colorCount));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrEffectRef* effect;
+    GrColor grColor;
+    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    return effect;
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -279,28 +283,36 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffectRef* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&,
-                                          const SkMatrix* localMatrix) const {
+bool SkSweepGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                  const SkMatrix* localMatrix, GrColor* grColor,
+                                  GrEffectRef** grEffect)  const {
+    
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
-        return NULL;
+        return false;
     }
     if (localMatrix) {
         SkMatrix inv;
         if (!localMatrix->invert(&inv)) {
-            return NULL;
+            return false;
         }
         matrix.postConcat(inv);
     }
     matrix.postConcat(fPtsToUnit);
-    return GrSweepGradient::Create(context, *this, matrix);
+    
+    *grEffect = GrSweepGradient::Create(context, *this, matrix);
+    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    
+    return true;
 }
 
 #else
 
-GrEffectRef* SkSweepGradient::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const {
+bool SkSweepGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                  const SkMatrix* localMatrix, GrColor* grColor,
+                                  GrEffectRef** grEffect)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
-    return NULL;
+    return false;
 }
 
 #endif
diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h
index 2f798e8..0b12e71 100644
--- a/src/effects/gradients/SkSweepGradient.h
+++ b/src/effects/gradients/SkSweepGradient.h
@@ -35,7 +35,8 @@
 
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
 
-    virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor*, GrEffectRef**)
+        const SK_OVERRIDE;
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient)
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index e26e36b..4421b90 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -6,7 +6,6 @@
  */
 
 #include "SkTwoPointConicalGradient.h"
-
 #include "SkTwoPointConicalGradient_gpu.h"
 
 struct TwoPtRadialContext {
@@ -380,20 +379,26 @@
 
 #if SK_SUPPORT_GPU
 
-GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint&,
-                                                    const SkMatrix* localMatrix) const {
+#include "SkGr.h"
+
+bool SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                             const SkMatrix* localMatrix, GrColor* grColor,
+                                             GrEffectRef** grEffect)  const {
     SkASSERT(NULL != context);
     SkASSERT(fPtsToUnit.isIdentity());
 
-    return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode, localMatrix);
+    *grEffect = Gr2PtConicalGradientEffect::Create(context, *this, fTileMode, localMatrix);
+    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    return true;
 }
 
 #else
 
-GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext*, const SkPaint&,
-                                                    const SkMatrix*) const {
+bool SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                            const SkMatrix* localMatrix, GrColor* grColor,
+                                            GrEffectRef** grEffect)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
-    return NULL;
+    return false;
 }
 
 #endif
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h
index 78998a8..f345d08 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.h
+++ b/src/effects/gradients/SkTwoPointConicalGradient.h
@@ -65,7 +65,8 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const;
     virtual SkShader::GradientType asAGradient(GradientInfo* info) const  SK_OVERRIDE;
-    virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrContext*, const SkPaint&, const SkMatrix*, GrColor* grColor,
+                             GrEffectRef**) const SK_OVERRIDE;
     virtual bool isOpaque() const SK_OVERRIDE;
 
     SkScalar getCenterX1() const { return SkPoint::Distance(fCenter1, fCenter2); }
diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
index 37c524d..4f9f758 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
@@ -203,7 +203,10 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrEffectRef* effect;
+    GrColor grColor;
+    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    return effect;
 }
 
 GLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrBackendEffectFactory& factory,
@@ -474,7 +477,10 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrEffectRef* effect;
+    GrColor grColor;
+    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    return effect;
 }
 
 GLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrBackendEffectFactory& factory,
@@ -683,7 +689,10 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrColor grColor;
+    GrEffectRef* grEffect;
+    shader->asNewEffect(context, paint, NULL, &grColor, &grEffect);
+    return grEffect;
 }
 
 GLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrBackendEffectFactory& factory,
@@ -925,7 +934,10 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrColor grColor;
+    GrEffectRef* grEffect;
+    shader->asNewEffect(context, paint, NULL, &grColor, &grEffect);
+    return grEffect;
 }
 
 GLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrBackendEffectFactory& factory,
@@ -1153,7 +1165,10 @@
                                                                           colors, stops, colorCount,
                                                                           tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrColor grColor;
+    GrEffectRef* grEffect;
+    shader->asNewEffect(context, paint, NULL, &grColor, &grEffect);
+    return grEffect;
 }
 
 GLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrBackendEffectFactory& factory,
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 8243cda..e3d8996 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -6,7 +6,7 @@
  * found in the LICENSE file.
  */
 
- #include "SkTwoPointRadialGradient.h"
+#include "SkTwoPointRadialGradient.h"
 
 /* Two-point radial gradients are specified by two circles, each with a center
    point and radius.  The gradient can be considered to be a series of
@@ -383,6 +383,7 @@
 #if SK_SUPPORT_GPU
 
 #include "GrTBackendEffectFactory.h"
+#include "SkGr.h"
 
 // For brevity
 typedef GrGLUniformManager::UniformHandle UniformHandle;
@@ -530,7 +531,10 @@
                                                                          colors, stops, colorCount,
                                                                          tm));
     SkPaint paint;
-    return shader->asNewEffect(context, paint, NULL);
+    GrEffectRef* effect;
+    GrColor grColor;
+    shader->asNewEffect(context, paint, NULL, &grColor, &effect);
+    return effect;
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -670,18 +674,20 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint&,
-                                                   const SkMatrix* localMatrix) const {
+bool SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                           const SkMatrix* localMatrix, GrColor* grColor,
+                                           GrEffectRef** grEffect)  const {
     SkASSERT(NULL != context);
+    
     // invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis.
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
-        return NULL;
+        return false;
     }
     if (localMatrix) {
         SkMatrix inv;
         if (!localMatrix->invert(&inv)) {
-            return NULL;
+            return false;
         }
         matrix.postConcat(inv);
     }
@@ -696,15 +702,19 @@
         matrix.postConcat(rot);
     }
 
-    return GrRadial2Gradient::Create(context, *this, matrix, fTileMode);
+    *grColor = SkColor2GrColorJustAlpha(paint.getColor());
+    *grEffect = GrRadial2Gradient::Create(context, *this, matrix, fTileMode);
+    
+    return true;
 }
 
 #else
 
-GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext*, const SkPaint&,
-                                                   const SkMatrix*) const {
+bool SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint& paint,
+                                           const SkMatrix* localMatrix, GrColor* grColor,
+                                           GrEffectRef** grEffect)  const {
     SkDEBUGFAIL("Should not call in GPU-less build");
-    return NULL;
+    return false;
 }
 
 #endif
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h
index 90052eb..8916754 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.h
+++ b/src/effects/gradients/SkTwoPointRadialGradient.h
@@ -21,8 +21,8 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&,
-                                     const SkMatrix*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrContext* context, const SkPaint&, const SkMatrix*, GrColor*,
+                             GrEffectRef**)  const SK_OVERRIDE;
 
     virtual size_t contextSize() const SK_OVERRIDE;
 
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 44120a2..15539a9 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1356,7 +1356,9 @@
     GrPaint grPaint;
     grPaint.addColorEffect(effect);
     bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config());
-    SkPaint2GrPaintNoShader(this->context(), paint, alphaOnly, false, &grPaint);
+    GrColor grColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
+                                    SkColor2GrColor(paint.getColor());
+    SkPaint2GrPaintNoShader(this->context(), paint, grColor, false, &grPaint);
 
     fContext->drawRectToRect(grPaint, dstRect, paintRect, NULL);
 }
@@ -1422,7 +1424,8 @@
     GrPaint grPaint;
     grPaint.addColorTextureEffect(texture, SkMatrix::I());
 
-    SkPaint2GrPaintNoShader(this->context(), paint, true, false, &grPaint);
+    SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
+                            false, &grPaint);
 
     fContext->drawRectToRect(grPaint,
                              SkRect::MakeXYWH(SkIntToScalar(left),
@@ -1530,7 +1533,8 @@
     GrPaint grPaint;
     grPaint.addColorTextureEffect(devTex, SkMatrix::I());
 
-    SkPaint2GrPaintNoShader(this->context(), paint, true, false, &grPaint);
+    SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(paint.getColor()),
+                            false, &grPaint);
 
     SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x),
                                       SkIntToScalar(y),
@@ -1616,7 +1620,8 @@
     GrPaint grPaint;
     // we ignore the shader if texs is null.
     if (NULL == texs) {
-        SkPaint2GrPaintNoShader(this->context(), paint, false, NULL == colors, &grPaint);
+        SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(paint.getColor()),
+                                NULL == colors, &grPaint);
     } else {
         SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPaint);
     }
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index fb2ebdd..c4720b5 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -416,7 +416,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, bool justAlpha,
+void SkPaint2GrPaintNoShader(GrContext* context, const SkPaint& skPaint, GrColor grColor,
                              bool constantColor, GrPaint* grPaint) {
 
     grPaint->setDither(skPaint.isDither());
@@ -440,16 +440,9 @@
         dm = SkXfermode::kISA_Coeff;
     }
     grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
-
-    if (justAlpha) {
-        uint8_t alpha = skPaint.getAlpha();
-        grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha));
-        // justAlpha is currently set to true only if there is a texture,
-        // so constantColor should not also be true.
-        SkASSERT(!constantColor);
-    } else {
-        grPaint->setColor(SkColor2GrColor(skPaint.getColor()));
-    }
+    
+    //set the color of the paint to the one of the parameter
+    grPaint->setColor(grColor);
 
     SkColorFilter* colorFilter = skPaint.getColorFilter();
     if (NULL != colorFilter) {
@@ -491,7 +484,8 @@
                            bool constantColor, GrPaint* grPaint) {
     SkShader* shader = skPaint.getShader();
     if (NULL == shader) {
-        SkPaint2GrPaintNoShader(context, skPaint, false, constantColor, grPaint);
+        SkPaint2GrPaintNoShader(context, skPaint, SkColor2GrColor(skPaint.getColor()),
+                                constantColor, grPaint);
         return;
     }
 
@@ -503,28 +497,15 @@
     AutoMatrix am(context);
 
     // setup the shader as the first color effect on the paint
-    SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(context, skPaint, NULL));
-    if (NULL != effect.get()) {
+    // the default grColor is the paint's color
+    GrColor grColor = SkColor2GrColor(skPaint.getColor());
+    GrEffectRef* grEffect = NULL;
+    if (shader->asNewEffect(context, skPaint, NULL, &grColor, &grEffect) && NULL != grEffect) {
+        SkAutoTUnref<GrEffectRef> effect(grEffect);
         grPaint->addColorEffect(effect);
-        // Now setup the rest of the paint.
-        SkPaint2GrPaintNoShader(context, skPaint, true, false, grPaint);
-    } else {
-        // We still don't have SkColorShader::asNewEffect() implemented.
-        SkShader::GradientInfo info;
-        SkColor                color;
-
-        info.fColors = &color;
-        info.fColorOffsets = NULL;
-        info.fColorCount = 1;
-        if (SkShader::kColor_GradientType == shader->asAGradient(&info)) {
-            SkPaint copy(skPaint);
-            copy.setShader(NULL);
-            // modulate the paint alpha by the shader's solid color alpha
-            U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha());
-            copy.setColor(SkColorSetA(color, newA));
-            SkPaint2GrPaintNoShader(context, copy, false, constantColor, grPaint);
-        } else {
-            SkPaint2GrPaintNoShader(context, skPaint, false, constantColor, grPaint);
-        }
+        constantColor = false;
     }
+    // The grcolor is automatically set when calling asneweffect.
+    // If the shader can be seen as an effect it returns true and adds its effect to the grpaint.
+    SkPaint2GrPaintNoShader(context, skPaint, grColor, constantColor, grPaint);
 }