Get gradient information for gpu effect directly from SkGradientShader instead of...
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 18 Apr 2014 14:42:11 +0000 (14:42 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 18 Apr 2014 14:42:11 +0000 (14:42 +0000)
BUG=skia:
R=bsalomon@google.com

Author: egdaniel@google.com

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

git-svn-id: http://skia.googlecode.com/svn/trunk@14254 2bbb7eff-a529-9590-31e7-b0007b416f81

src/effects/gradients/SkGradientShader.cpp
src/effects/gradients/SkGradientShaderPriv.h

index 2ebb9c7..504855a 100644 (file)
@@ -220,6 +220,23 @@ void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
     buffer.writeMatrix(fPtsToUnit);
 }
 
+SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const {
+    if (fColorCount <= 3) {
+        memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor));
+    }
+
+    if (SkShader::kClamp_TileMode == fTileMode) {
+        if (2 == fColorCount) {
+            return kTwo_GpuColorType;
+        } else if (3 == fColorCount &&
+                   (SkScalarAbs(
+                    SkFixedToScalar(fRecs[1].fPos) - SK_ScalarHalf) < SK_Scalar1 / 1000)) {
+            return kThree_GpuColorType;
+        }
+    }
+    return kTexture_GpuColorType;
+}
+
 bool SkGradientShaderBase::isOpaque() const {
     return fColorsAreOpaque;
 }
@@ -832,13 +849,13 @@ GrGLGradientEffect::~GrGLGradientEffect() { }
 
 void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, EffectKey key) {
 
-    if (GrGradientEffect::kTwo_ColorType == ColorTypeFromKey(key)) { // 2 Color case
+    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)) { // 2 Color case
         fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                              kVec4f_GrSLType, "GradientStartColor");
         fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                            kVec4f_GrSLType, "GradientEndColor");
 
-    } else if (GrGradientEffect::kThree_ColorType == ColorTypeFromKey(key)){ // 3 Color Case
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){ // 3 Color Case
         fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                              kVec4f_GrSLType, "GradientStartColor");
         fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
@@ -880,7 +897,7 @@ void GrGLGradientEffect::setData(const GrGLUniformManager& uman,
     const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
 
 
-    if (GrGradientEffect::kTwo_ColorType == e.getColorType()){
+    if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()){
 
         if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
             set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
@@ -890,7 +907,7 @@ void GrGLGradientEffect::setData(const GrGLUniformManager& uman,
             set_color_uni(uman, fColorEndUni,   e.getColors(1));
         }
 
-    } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){
+    } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()){
 
         if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
             set_mul_color_uni(uman, fColorStartUni, e.getColors(0));
@@ -917,9 +934,9 @@ GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect&
 
     EffectKey key = 0;
 
-    if (GrGradientEffect::kTwo_ColorType == e.getColorType()) {
+    if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) {
         key |= kTwoColorKey;
-    } else if (GrGradientEffect::kThree_ColorType == e.getColorType()){
+    } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()){
         key |= kThreeColorKey;
     }
 
@@ -936,7 +953,7 @@ void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TextureSamplerArray& samplers) {
-    if (GrGradientEffect::kTwo_ColorType == ColorTypeFromKey(key)){
+    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)){
         builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
                                builder->getUniformVariable(fColorStartUni).c_str(),
                                builder->getUniformVariable(fColorEndUni).c_str(),
@@ -952,7 +969,7 @@ void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
 
         builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
                                (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-    } else if (GrGradientEffect::kThree_ColorType == ColorTypeFromKey(key)){
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){
         builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
                                gradientTValue);
         builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
@@ -997,30 +1014,14 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
 
     fIsOpaque = shader.isOpaque();
 
-    SkShader::GradientInfo info;
-    SkScalar pos[3] = {0};
-
-    info.fColorCount = 3;
-    info.fColors = &fColors[0];
-    info.fColorOffsets = &pos[0];
-    shader.asAGradient(&info);
+    fColorType = shader.getGpuColorType(&fColors[0]);
 
     // The two and three color specializations do not currently support tiling.
-    bool foundSpecialCase = false;
-    if (SkShader::kClamp_TileMode == info.fTileMode) {
-        if (2 == info.fColorCount) {
-            fRow = -1; // flag for no atlas
-            fColorType = kTwo_ColorType;
-            foundSpecialCase = true;
-        } else if (3 == info.fColorCount &&
-                   (SkScalarAbs(pos[1] - SK_ScalarHalf) < SK_Scalar1 / 1000)) { // 3 color symmetric
-            fRow = -1; // flag for no atlas
-            fColorType = kThree_ColorType;
-            foundSpecialCase = true;
-        }
-    }
-    if (foundSpecialCase) {
-        if (SkGradientShader::kInterpolateColorsInPremul_Flag & info.fGradientFlags) {
+    if (SkGradientShaderBase::kTwo_GpuColorType == fColorType ||
+        SkGradientShaderBase::kThree_GpuColorType == fColorType) {
+        fRow = -1;
+        
+        if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getFlags()) {
             fPremulType = kBeforeInterp_PremulType;
         } else {
             fPremulType = kAfterInterp_PremulType;
@@ -1031,7 +1032,6 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
         fPremulType = kBeforeInterp_PremulType;
         SkBitmap bitmap;
         shader.getGradientTableBitmap(&bitmap);
-        fColorType = kTexture_ColorType;
 
         GrTextureStripAtlas::Desc desc;
         desc.fWidth  = bitmap.width();
@@ -1080,12 +1080,12 @@ bool GrGradientEffect::onIsEqual(const GrEffect& effect) const {
 
     if (this->fColorType == s.getColorType()){
 
-        if (kTwo_ColorType == fColorType) {
+        if (SkGradientShaderBase::kTwo_GpuColorType == fColorType) {
             if (*this->getColors(0) != *s.getColors(0) ||
                 *this->getColors(1) != *s.getColors(1)) {
                 return false;
             }
-        } else if (kThree_ColorType == fColorType) {
+        } else if (SkGradientShaderBase::kThree_GpuColorType == fColorType) {
             if (*this->getColors(0) != *s.getColors(0) ||
                 *this->getColors(1) != *s.getColors(1) ||
                 *this->getColors(2) != *s.getColors(2)) {
index 83e0789..1ccd049 100644 (file)
@@ -128,6 +128,18 @@ public:
         kDitherStride16 = kCache16Count,
     };
 
+    enum GpuColorType {
+        kTwo_GpuColorType,
+        kThree_GpuColorType, // Symmetric three color
+        kTexture_GpuColorType
+    };
+
+    // Determines and returns the gradient is a two color gradient, symmetric three color gradient
+    // or other (texture gradient). If it is two or symmetric three color, the colors array will
+    // also be filled with the gradient colors
+    GpuColorType getGpuColorType(SkColor colors[3]) const;
+
+    uint32_t getFlags() const { return fGradFlags; } 
 
 protected:
     SkGradientShaderBase(SkReadBuffer& );
@@ -251,13 +263,7 @@ public:
 
     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
-    enum ColorType {
-        kTwo_ColorType,
-        kThree_ColorType,
-        kTexture_ColorType
-    };
-
-    ColorType getColorType() const { return fColorType; }
+    SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
 
     enum PremulType {
         kBeforeInterp_PremulType,
@@ -267,7 +273,7 @@ public:
     PremulType getPremulType() const { return fPremulType; }
 
     const SkColor* getColors(int pos) const {
-        SkASSERT(fColorType != kTexture_ColorType);
+        SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType);
         SkASSERT((pos-1) <= fColorType);
         return &fColors[pos];
     }
@@ -294,18 +300,14 @@ protected:
 private:
     static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
 
-    enum {
-        kMaxAnalyticColors = 3 // if more colors use texture
-    };
-
     GrCoordTransform fCoordTransform;
     GrTextureAccess fTextureAccess;
     SkScalar fYCoord;
     GrTextureStripAtlas* fAtlas;
     int fRow;
     bool fIsOpaque;
-    ColorType fColorType;
-    SkColor fColors[kMaxAnalyticColors];
+    SkGradientShaderBase::GpuColorType fColorType;
+    SkColor fColors[3]; // More than 3 colors we use texture
     PremulType fPremulType; // This only changes behavior for two and three color special cases.
                             // It is already baked into to the table for texture gradients.
     typedef GrEffect INHERITED;
@@ -338,12 +340,12 @@ protected:
         kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
     };
 
-    static GrGradientEffect::ColorType ColorTypeFromKey(EffectKey key){
+    static SkGradientShaderBase::GpuColorType ColorTypeFromKey(EffectKey key){
         if (kTwoColorKey == (key & kColorKeyMask)) {
-            return GrGradientEffect::kTwo_ColorType;
+            return SkGradientShaderBase::kTwo_GpuColorType;
         } else if (kThreeColorKey == (key & kColorKeyMask)) {
-            return GrGradientEffect::kThree_ColorType;
-        } else {return GrGradientEffect::kTexture_ColorType;}
+            return SkGradientShaderBase::kThree_GpuColorType;
+        } else {return SkGradientShaderBase::kTexture_GpuColorType;}
     }
 
     static GrGradientEffect::PremulType PremulTypeFromKey(EffectKey key){