two loops for setting stage descs
Review URL: http://codereview.appspot.com/5486054/


git-svn-id: http://skia.googlecode.com/svn/trunk@2872 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrGLProgram.h b/src/gpu/GrGLProgram.h
index 450da05..d02294a 100644
--- a/src/gpu/GrGLProgram.h
+++ b/src/gpu/GrGLProgram.h
@@ -173,6 +173,9 @@
                     fOptFlags &= ~kIsEnabled_OptFlagBit;
                 }
             }
+            void reset() {
+                memset(this, 0, sizeof(*this));
+            }
         };
 
         // Specifies where the intitial color comes from before the stages are
diff --git a/src/gpu/GrGpuGL.h b/src/gpu/GrGpuGL.h
index 5f9180f..323d5f6 100644
--- a/src/gpu/GrGpuGL.h
+++ b/src/gpu/GrGpuGL.h
@@ -41,8 +41,6 @@
                                     GrPixelConfig config,
                                     size_t rowBytes) const SK_OVERRIDE;
     virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE;
-protected:
-    GrGpuGL(const GrGLInterface* glInterface, GrGLBinding glBinding);
 
     struct GLCaps {
         GLCaps()
@@ -118,8 +116,19 @@
         bool fTextureUsageSupport;
 
         void print() const;
-    } fGLCaps;
- 
+    };
+
+    const GLCaps& glCaps() const { return fGLCaps; }
+
+    // subclass may try to take advantage of identity tex matrices.
+    // This helper determines if matrix will be identity after all
+    // adjustments are applied.
+    static bool TextureMatrixIsIdentity(const GrGLTexture* texture,
+                                        const GrSamplerState& sampler);
+
+protected:
+    GrGpuGL(const GrGLInterface* glInterface, GrGLBinding glBinding);
+
     struct {
         size_t                  fVertexOffset;
         GrVertexLayout          fVertexLayout;
@@ -157,8 +166,6 @@
         GrGLIRect   fViewportRect;
     } fHWBounds;
 
-    const GLCaps& glCaps() const { return fGLCaps; }
-
     // GrGpu overrides
     virtual void onResetContext() SK_OVERRIDE;
 
@@ -241,13 +248,6 @@
     static void AdjustTextureMatrix(const GrGLTexture* texture,
                                     GrSamplerState::SampleMode mode,
                                     GrMatrix* matrix);
-
-    // subclass may try to take advantage of identity tex matrices.
-    // This helper determines if matrix will be identity after all
-    // adjustments are applied.
-    static bool TextureMatrixIsIdentity(const GrGLTexture* texture,
-                                        const GrSamplerState& sampler);
-
     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
 
 private:
@@ -321,6 +321,7 @@
 
     const GrGLInterface* fGL;
     GrGLBinding fGLBinding;
+    GLCaps fGLCaps;
 
     bool fPrintedCaps;
 
diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp
index 98ac1bf..87bdb05 100644
--- a/src/gpu/GrGpuGLShaders.cpp
+++ b/src/gpu/GrGpuGLShaders.cpp
@@ -875,6 +875,97 @@
     fHWGeometryState.fArrayPtrsDirty = false;
 }
 
+namespace {
+void copy_stage_to_desc(GrGLProgram::StageDesc* stage,
+                        const GrGLTexture* texture,
+                        const GrSamplerState& sampler,
+                        const GrGpuGL::GLCaps& caps) {
+    typedef GrGLProgram::StageDesc StageDesc;
+    GrAssert(NULL != texture);
+    stage->fOptFlags = 0;
+    stage->setEnabled(true);
+
+    // we matrix to invert when orientation is TopDown, so make sure
+    // we aren't in that case before flagging as identity.
+    if (GrGpuGL::TextureMatrixIsIdentity(texture, sampler)) {
+        stage->fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
+    } else if (!sampler.getMatrix().hasPerspective()) {
+        stage->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
+    }
+    switch (sampler.getSampleMode()) {
+        case GrSamplerState::kNormal_SampleMode:
+            stage->fCoordMapping = StageDesc::kIdentity_CoordMapping;
+            break;
+        case GrSamplerState::kRadial_SampleMode:
+            stage->fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
+            break;
+        case GrSamplerState::kRadial2_SampleMode:
+            if (sampler.radial2IsDegenerate()) {
+                stage->fCoordMapping =
+                    StageDesc::kRadial2GradientDegenerate_CoordMapping;
+            } else {
+                stage->fCoordMapping =
+                    StageDesc::kRadial2Gradient_CoordMapping;
+            }
+            break;
+        case GrSamplerState::kSweep_SampleMode:
+            stage->fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
+            break;
+        default:
+            GrCrash("Unexpected sample mode!");
+            break;
+    }
+
+    switch (sampler.getFilter()) {
+        // these both can use a regular texture2D()
+        case GrSamplerState::kNearest_Filter:
+        case GrSamplerState::kBilinear_Filter:
+            stage->fFetchMode = StageDesc::kSingle_FetchMode;
+            break;
+        // performs 4 texture2D()s
+        case GrSamplerState::k4x4Downsample_Filter:
+            stage->fFetchMode = StageDesc::k2x2_FetchMode;
+            break;
+        // performs fKernelWidth texture2D()s
+        case GrSamplerState::kConvolution_Filter:
+            stage->fFetchMode = StageDesc::kConvolution_FetchMode;
+            break;
+        default:
+            GrCrash("Unexpected filter!");
+            break;
+    }
+
+    if (sampler.hasTextureDomain()) {
+        GrAssert(GrSamplerState::kClamp_WrapMode ==
+                    sampler.getWrapX() &&
+                    GrSamplerState::kClamp_WrapMode ==
+                    sampler.getWrapY());
+        stage->fOptFlags |= StageDesc::kCustomTextureDomain_OptFlagBit;
+    }
+
+    stage->fInConfigFlags = 0;
+    if (!caps.fTextureSwizzleSupport) {
+        if (GrPixelConfigIsAlphaOnly(texture->config())) {
+            // if we don't have texture swizzle support then
+            // the shader must do an alpha smear after reading
+            // the texture
+            stage->fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
+        } else if (sampler.swapsRAndB()) {
+            stage->fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag;
+        }
+    }
+    if (GrPixelConfigIsUnpremultiplied(texture->config())) {
+        stage->fInConfigFlags |= StageDesc::kMulRGBByAlpha_InConfigFlag;
+    }
+
+    if (sampler.getFilter() == GrSamplerState::kConvolution_Filter) {
+        stage->fKernelWidth = sampler.getKernelWidth();
+    } else {
+        stage->fKernelWidth = 0;
+    }
+}
+}
+
 void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
                                   BlendOptFlags blendOpts,
                                   GrBlendCoeff dstCoeff) {
@@ -944,106 +1035,37 @@
         // use canonical value when not set to avoid cache misses
         desc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
     }
+    int firstCoverageStage = drawState.getFirstCoverageStage();
 
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
+    for (int s = 0; s < firstCoverageStage; ++s) {
         StageDesc& stage = desc.fStages[s];
-
-        stage.fOptFlags = 0;
-        stage.setEnabled(this->isStageEnabled(s));
-
-        bool skip = s < drawState.getFirstCoverageStage() ? skipColor :
-                                                             skipCoverage;
-
-        if (!skip && stage.isEnabled()) {
-            lastEnabledStage = s;
+        bool enabled = !skipColor && this->isStageEnabled(s);
+        if (enabled) {
             const GrGLTexture* texture =
                 static_cast<const GrGLTexture*>(drawState.getTexture(s));
-            GrAssert(NULL != texture);
-            const GrSamplerState& sampler = drawState.getSampler(s);
-            // we matrix to invert when orientation is TopDown, so make sure
-            // we aren't in that case before flagging as identity.
-            if (TextureMatrixIsIdentity(texture, sampler)) {
-                stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
-            } else if (!sampler.getMatrix().hasPerspective()) {
-                stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
-            }
-            switch (sampler.getSampleMode()) {
-                case GrSamplerState::kNormal_SampleMode:
-                    stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
-                    break;
-                case GrSamplerState::kRadial_SampleMode:
-                    stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
-                    break;
-                case GrSamplerState::kRadial2_SampleMode:
-                    if (sampler.radial2IsDegenerate()) {
-                        stage.fCoordMapping =
-                            StageDesc::kRadial2GradientDegenerate_CoordMapping;
-                    } else {
-                        stage.fCoordMapping =
-                            StageDesc::kRadial2Gradient_CoordMapping;
-                    }
-                    break;
-                case GrSamplerState::kSweep_SampleMode:
-                    stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
-                    break;
-                default:
-                    GrCrash("Unexpected sample mode!");
-                    break;
-            }
-
-            switch (sampler.getFilter()) {
-                // these both can use a regular texture2D()
-                case GrSamplerState::kNearest_Filter:
-                case GrSamplerState::kBilinear_Filter:
-                    stage.fFetchMode = StageDesc::kSingle_FetchMode;
-                    break;
-                // performs 4 texture2D()s
-                case GrSamplerState::k4x4Downsample_Filter:
-                    stage.fFetchMode = StageDesc::k2x2_FetchMode;
-                    break;
-                // performs fKernelWidth texture2D()s
-                case GrSamplerState::kConvolution_Filter:
-                    stage.fFetchMode = StageDesc::kConvolution_FetchMode;
-                    break;
-                default:
-                    GrCrash("Unexpected filter!");
-                    break;
-            }
-
-            if (sampler.hasTextureDomain()) {
-                GrAssert(GrSamplerState::kClamp_WrapMode ==
-                            sampler.getWrapX() &&
-                         GrSamplerState::kClamp_WrapMode ==
-                            sampler.getWrapY());
-                stage.fOptFlags |= StageDesc::kCustomTextureDomain_OptFlagBit;
-            }
-
-            stage.fInConfigFlags = 0;
-            if (!this->glCaps().fTextureSwizzleSupport) {
-                if (GrPixelConfigIsAlphaOnly(texture->config())) {
-                    // if we don't have texture swizzle support then
-                    // the shader must do an alpha smear after reading
-                    // the texture
-                    stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
-                } else if (sampler.swapsRAndB()) {
-                    stage.fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag;
-                }
-            }
-            if (GrPixelConfigIsUnpremultiplied(texture->config())) {
-                stage.fInConfigFlags |= StageDesc::kMulRGBByAlpha_InConfigFlag;
-            }
-
-            if (sampler.getFilter() == GrSamplerState::kConvolution_Filter) {
-                stage.fKernelWidth = sampler.getKernelWidth();
-            } else {
-                stage.fKernelWidth = 0;
-            }
+            copy_stage_to_desc(&stage,
+                               texture,
+                               drawState.getSampler(s),
+                               this->glCaps());
+            lastEnabledStage = s;
         } else {
-            stage.fOptFlags         = 0;
-            stage.fCoordMapping     = (StageDesc::CoordMapping) 0;
-            stage.fInConfigFlags    = 0;
-            stage.fFetchMode        = (StageDesc::FetchMode) 0;
-            stage.fKernelWidth      = 0;
+            stage.reset();
+        }
+    }
+    for (int s = firstCoverageStage; s < GrDrawState::kNumStages; ++s) {
+        StageDesc& stage = desc.fStages[s];
+        bool enabled = !skipCoverage && this->isStageEnabled(s);
+        if (enabled) {
+            stage.setEnabled(enabled);
+            const GrGLTexture* texture =
+                static_cast<const GrGLTexture*>(drawState.getTexture(s));
+            copy_stage_to_desc(&stage,
+                               texture,
+                               drawState.getSampler(s),
+                               this->glCaps());
+            lastEnabledStage = s;
+        } else {
+            stage.reset();
         }
     }
 
@@ -1067,7 +1089,7 @@
     // We set field in the desc to kNumStages when either there are no 
     // coverage stages or the distinction between coverage and color is
     // immaterial.
-    int firstCoverageStage = GrDrawState::kNumStages;
+    firstCoverageStage = GrDrawState::kNumStages;
     desc.fFirstCoverageStage = GrDrawState::kNumStages;
     bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage;
     if (hasCoverage) {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b80d3a6..9fa76be 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -413,21 +413,21 @@
     grPaint->fDither    = skPaint.isDither();
     grPaint->fAntiAlias = skPaint.isAntiAlias();
 
-    SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
-    SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
+    grPaint->fSrcBlendCoeff = kOne_BlendCoeff;
+    grPaint->fDstBlendCoeff = kISA_BlendCoeff;
 
     SkXfermode* mode = skPaint.getXfermode();
     if (mode) {
+        SkXfermode::Coeff sm, dm;
         if (!mode->asCoeff(&sm, &dm)) {
             //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");)
 #if 0
             return false;
 #endif
+            grPaint->fSrcBlendCoeff = sk_blend_to_grblend(sm);
+            grPaint->fDstBlendCoeff = sk_blend_to_grblend(dm);
         }
     }
-    grPaint->fSrcBlendCoeff = sk_blend_to_grblend(sm);
-    grPaint->fDstBlendCoeff = sk_blend_to_grblend(dm);
-
     if (justAlpha) {
         uint8_t alpha = skPaint.getAlpha();
         grPaint->fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);