Make 0-texture GrCustomStages work.
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 15:33:25 +0000 (15:33 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 15:33:25 +0000 (15:33 +0000)
Review URL: http://codereview.appspot.com/6448080/

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

src/gpu/GrContext.cpp
src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGLProgramStage.h
src/gpu/gl/GrGLUniformManager.cpp
src/gpu/gl/GrGpuGL.cpp

index 0815562..f801b26 100644 (file)
@@ -1035,24 +1035,25 @@ inline bool isSimilarityTransformation(const SkMatrix& matrix,
 void GrContext::drawOval(const GrPaint& paint,
                          const GrRect& rect,
                          SkScalar strokeWidth) {
-    DrawCategory category = (DEFER_PATHS) ? kBuffered_DrawCategory :
-                                            kUnbuffered_DrawCategory;
-    GrDrawTarget* target = this->prepareToDraw(paint, category);
-    GrDrawState::AutoStageDisable atr(fDrawState);
-    GrDrawState* drawState = target->drawState();
-    GrMatrix vm = drawState->getViewMatrix();
-
-    if (!isSimilarityTransformation(vm) ||
+    GrAssert(strokeWidth <= 0);
+    if (!isSimilarityTransformation(this->getMatrix()) ||
         !paint.fAntiAlias ||
         rect.height() != rect.width()) {
         SkPath path;
         path.addOval(rect);
         GrPathFill fill = (strokeWidth == 0) ?
-                            kHairLine_GrPathFill : kWinding_GrPathFill;
+                           kHairLine_GrPathFill : kWinding_GrPathFill;
         this->internalDrawPath(paint, path, fill, NULL);
         return;
     }
 
+    DrawCategory category = (DEFER_PATHS) ? kBuffered_DrawCategory :
+                                            kUnbuffered_DrawCategory;
+    GrDrawTarget* target = this->prepareToDraw(paint, category);
+    GrDrawState* drawState = target->drawState();
+    GrDrawState::AutoStageDisable atr(fDrawState);
+    const GrMatrix vm = drawState->getViewMatrix();
+
     const GrRenderTarget* rt = drawState->getRenderTarget();
     if (NULL == rt) {
         return;
index ec68eae..3590428 100644 (file)
@@ -977,10 +977,17 @@ bool GrGLProgram::bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[],
 
 void GrGLProgram::initSamplerUniforms() {
     GL_CALL(UseProgram(fProgramID));
-    // init sampler unis and set bogus values for state tracking
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        if (GrGLUniformManager::kInvalidUniformHandle != fUniforms.fStages[s].fSamplerUni) {
-            fUniformManager.setSampler(fUniforms.fStages[s].fSamplerUni, s);
+        int count = fUniforms.fStages[s].fSamplerUniforms.count();
+        // FIXME: We're still always reserving one texture per stage. After GrTextureParams are
+        // expressed by the custom stage rather than the GrSamplerState we can move texture binding
+        // into GrGLProgram and it should be easier to fix this.
+        GrAssert(count <= 1);
+        for (int t = 0; t < count; ++t) {
+            UniformHandle uh = fUniforms.fStages[s].fSamplerUniforms[t];
+            if (GrGLUniformManager::kInvalidUniformHandle != uh) {
+                fUniformManager.setSampler(uh, s);
+            }
         }
     }
 }
@@ -1029,8 +1036,10 @@ void GrGLProgram::genStageCode(int stageNum,
     }
 
     const char* samplerName;
-    uniforms.fSamplerUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
-                                               kSampler2D_GrSLType, "Sampler", &samplerName);
+    uniforms.fSamplerUniforms.push_back(builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
+                                                            kSampler2D_GrSLType,
+                                                            "Sampler",
+                                                            &samplerName));
 
     const char *varyingVSName, *varyingFSName;
     builder->addVarying(GrSLFloatVectorType(builder->fVaryingDims),
index b6c224c..18d97d5 100644 (file)
@@ -276,10 +276,9 @@ private:
 
     struct StageUniforms {
         UniformHandle fTextureMatrixUni;
-        UniformHandle fSamplerUni;
+        SkTArray<UniformHandle, true> fSamplerUniforms;
         StageUniforms() {
             fTextureMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
-            fSamplerUni = GrGLUniformManager::kInvalidUniformHandle;
         }
     };
 
index 09012ea..12163f8 100644 (file)
@@ -37,12 +37,6 @@ public:
         kProgramStageKeyBits = GrProgramStageFactory::kProgramStageKeyBits,
     };
 
-    // TODO: redundant with GrGLProgram.cpp
-    enum {
-        kUnusedUniform = -1,
-        kUseUniform = 2000
-    };
-
     GrGLProgramStage(const GrProgramStageFactory&);
 
     virtual ~GrGLProgramStage();
index 180286b..06ce2db 100644 (file)
@@ -28,7 +28,10 @@ void GrGLUniformManager::setSampler(UniformHandle u, GrGLint texUnit) const {
     const Uniform& uni = fUniforms[handle_to_index(u)];
     GrAssert(uni.fType == kSampler2D_GrSLType);
     GrAssert(GrGLShaderVar::kNonArray == uni.fArrayCount);
-    GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
+    // FIXME: We still insert a single sampler uniform for every stage. If the shader does not
+    // reference the sampler then the compiler may have optimized it out. Uncomment this assert
+    // once stages insert their own samplers.
+    // GrAssert(kUnusedUniform != uni.fFSLocation || kUnusedUniform != uni.fVSLocation);
     if (kUnusedUniform != uni.fFSLocation) {
         GR_GL_CALL(fContext.interface(), Uniform1i(uni.fFSLocation, texUnit));
     }
index 68f7a9a..26018bf 100644 (file)
@@ -2135,13 +2135,15 @@ const GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) {
 
 void GrGpuGL::flushBoundTextureAndParams(int stage) {
     GrDrawState* drawState = this->drawState();
-    // FIXME: Assuming one texture maximum per custom stage
+    // FIXME: Assuming at most one texture per custom stage
     const GrCustomStage* customStage = drawState->sampler(stage)->getCustomStage();
     GrGLTexture* nextTexture =  static_cast<GrGLTexture*>(customStage->texture(0));
-    // Currently we always use the texture params from the GrSamplerState. Soon custom stages
-    // will provide their own params.
-    const GrTextureParams& texParams = drawState->getSampler(stage).getTextureParams();
-    this->flushBoundTextureAndParams(stage, texParams, nextTexture);
+    if (NULL != nextTexture) {
+        // Currently we always use the texture params from the GrSamplerState. Soon custom stages
+        // will provide their own params.
+        const GrTextureParams& texParams = drawState->getSampler(stage).getTextureParams();
+        this->flushBoundTextureAndParams(stage, texParams, nextTexture);
+    }
 }
 
 void GrGpuGL::flushBoundTextureAndParams(int stage,