move texture flush and param update to separate function
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 4 Jun 2012 19:05:11 +0000 (19:05 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 4 Jun 2012 19:05:11 +0000 (19:05 +0000)
Review URL: http://codereview.appspot.com/6266044/

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

src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL.h
src/gpu/gl/GrGpuGL_program.cpp

index 6c22f46..2512ba0 100644 (file)
@@ -1189,6 +1189,7 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
         // Must not reset fStageOverride[] here.
     }
     programData->fViewMatrix = GrMatrix::InvalidMatrix();
+    programData->fViewportSize.set(-1, -1);
     programData->fColor = GrColor_ILLEGAL;
     programData->fColorFilterColor = GrColor_ILLEGAL;
 }
index f638eab..be154b0 100644 (file)
@@ -309,7 +309,10 @@ public:
         // shader uniform locations (-1 if shader doesn't use them)
         UniLocations fUniLocations;
 
+        // The matrix sent to GL is determined by both the client's matrix and
+        // the size of the viewport.
         GrMatrix  fViewMatrix;
+        SkISize   fViewportSize;
 
         // these reflect the current values of uniforms
         // (GL uniform values travel with program)
index 90fb2a6..42043f9 100644 (file)
@@ -1625,9 +1625,6 @@ void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
         if (fHWBounds.fViewportRect != vp) {
             vp.pushToGLViewport(this->glInterface());
             fHWBounds.fViewportRect = vp;
-            // View matrices pushed to GL depend upon the viewport. So they
-            // are now invalid.
-            fProgramCache->invalidateViewMatrices();
         }
     }
     if (NULL == bound || !bound->isEmpty()) {
@@ -2109,6 +2106,82 @@ void set_tex_swizzle(GrGLenum swizzle[4], const GrGLInterface* gl) {
 }
 }
 
+void GrGpuGL::flushBoundTextureAndParams(int stage) {
+    GrDrawState* drawState = this->drawState();
+
+    GrGLTexture* nextTexture = 
+        static_cast<GrGLTexture*>(drawState->getTexture(stage));
+
+    // true for now, but maybe not with GrEffect.
+    GrAssert(NULL != nextTexture);
+    // if we created a rt/tex and rendered to it without using a
+    // texture and now we're texturing from the rt it will still be
+    // the last bound texture, but it needs resolving. So keep this
+    // out of the "last != next" check.
+    GrGLRenderTarget* texRT = 
+        static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
+    if (NULL != texRT) {
+        this->onResolveRenderTarget(texRT);
+    }
+
+    if (fHWBoundTextures[stage] != nextTexture) {
+        this->setTextureUnit(stage);
+        GL_CALL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID()));
+    #if GR_COLLECT_STATS
+        ++fStats.fTextureChngCnt;
+    #endif
+        //GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
+        fHWBoundTextures[stage] = nextTexture;
+    }
+
+    const GrSamplerState& sampler = drawState->getSampler(stage);
+    ResetTimestamp timestamp;
+    const GrGLTexture::TexParams& oldTexParams =
+                            nextTexture->getCachedTexParams(&timestamp);
+    bool setAll = timestamp < this->getResetTimestamp();
+    GrGLTexture::TexParams newTexParams;
+
+    newTexParams.fFilter = gr_to_gl_filter(sampler.getFilter());
+
+    const GrGLenum* wraps =  GrGLTexture::WrapMode2GLWrap();
+    newTexParams.fWrapS = wraps[sampler.getWrapX()];
+    newTexParams.fWrapT = wraps[sampler.getWrapY()];
+    memcpy(newTexParams.fSwizzleRGBA,
+           get_swizzle(nextTexture->config(), sampler, this->glCaps()),
+           sizeof(newTexParams.fSwizzleRGBA));
+    if (setAll || newTexParams.fFilter != oldTexParams.fFilter) {
+        this->setTextureUnit(stage);
+        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                              GR_GL_TEXTURE_MAG_FILTER,
+                              newTexParams.fFilter));
+        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                              GR_GL_TEXTURE_MIN_FILTER,
+                              newTexParams.fFilter));
+    }
+    if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
+        this->setTextureUnit(stage);
+        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                              GR_GL_TEXTURE_WRAP_S,
+                              newTexParams.fWrapS));
+    }
+    if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
+        this->setTextureUnit(stage);
+        GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                              GR_GL_TEXTURE_WRAP_T,
+                              newTexParams.fWrapT));
+    }
+    if (this->glCaps().textureSwizzleSupport() &&
+        (setAll || memcmp(newTexParams.fSwizzleRGBA,
+                          oldTexParams.fSwizzleRGBA,
+                          sizeof(newTexParams.fSwizzleRGBA)))) {
+        this->setTextureUnit(stage);
+        set_tex_swizzle(newTexParams.fSwizzleRGBA,
+                        this->glInterface());
+    }
+    nextTexture->setCachedTexParams(newTexParams,
+                                    this->getResetTimestamp());
+}
+
 bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
 
     GrDrawState* drawState = this->drawState();
@@ -2116,92 +2189,6 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
     // and bailed if not true.
     GrAssert(NULL != drawState->getRenderTarget());
 
-    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
-        // bind texture and set sampler state
-        if (this->isStageEnabled(s)) {
-            GrGLTexture* nextTexture = 
-                static_cast<GrGLTexture*>(drawState->getTexture(s));
-
-            // true for now, but maybe not with GrEffect.
-            GrAssert(NULL != nextTexture);
-            // if we created a rt/tex and rendered to it without using a
-            // texture and now we're texturing from the rt it will still be
-            // the last bound texture, but it needs resolving. So keep this
-            // out of the "last != next" check.
-            GrGLRenderTarget* texRT = 
-                static_cast<GrGLRenderTarget*>(nextTexture->asRenderTarget());
-            if (NULL != texRT) {
-                this->onResolveRenderTarget(texRT);
-            }
-
-            if (fHWBoundTextures[s] != nextTexture) {
-                this->setTextureUnit(s);
-                GL_CALL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID()));
-            #if GR_COLLECT_STATS
-                ++fStats.fTextureChngCnt;
-            #endif
-                //GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
-                fHWBoundTextures[s] = nextTexture;
-            }
-
-            const GrSamplerState& sampler = drawState->getSampler(s);
-            ResetTimestamp timestamp;
-            const GrGLTexture::TexParams& oldTexParams =
-                                    nextTexture->getCachedTexParams(&timestamp);
-            bool setAll = timestamp < this->getResetTimestamp();
-            GrGLTexture::TexParams newTexParams;
-
-            newTexParams.fFilter = gr_to_gl_filter(sampler.getFilter());
-
-            const GrGLenum* wraps =  GrGLTexture::WrapMode2GLWrap();
-            newTexParams.fWrapS = wraps[sampler.getWrapX()];
-            newTexParams.fWrapT = wraps[sampler.getWrapY()];
-            memcpy(newTexParams.fSwizzleRGBA,
-                   get_swizzle(nextTexture->config(), sampler, this->glCaps()),
-                   sizeof(newTexParams.fSwizzleRGBA));
-            if (setAll || newTexParams.fFilter != oldTexParams.fFilter) {
-                this->setTextureUnit(s);
-                GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
-                                        GR_GL_TEXTURE_MAG_FILTER,
-                                        newTexParams.fFilter));
-                GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
-                                        GR_GL_TEXTURE_MIN_FILTER,
-                                        newTexParams.fFilter));
-            }
-            if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
-                this->setTextureUnit(s);
-                GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
-                                        GR_GL_TEXTURE_WRAP_S,
-                                        newTexParams.fWrapS));
-            }
-            if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
-                this->setTextureUnit(s);
-                GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
-                                        GR_GL_TEXTURE_WRAP_T,
-                                        newTexParams.fWrapT));
-            }
-            if (this->glCaps().textureSwizzleSupport() &&
-                (setAll ||
-                 memcmp(newTexParams.fSwizzleRGBA,
-                        oldTexParams.fSwizzleRGBA,
-                        sizeof(newTexParams.fSwizzleRGBA)))) {
-                this->setTextureUnit(s);
-                set_tex_swizzle(newTexParams.fSwizzleRGBA,
-                                this->glInterface());
-            }
-            nextTexture->setCachedTexParams(newTexParams,
-                                            this->getResetTimestamp());
-        }
-    }
-
-    GrIRect* rect = NULL;
-    GrIRect clipBounds;
-    if (drawState->isClipState() &&
-        fClip.hasConservativeBounds()) {
-        fClip.getConservativeBounds().roundOut(&clipBounds);
-        rect = &clipBounds;
-    }
-    this->flushRenderTarget(rect);
     this->flushAAState(type);
 
     if (drawState->isDitherState()) {
index b0a7bdc..b5dd09a 100644 (file)
@@ -203,7 +203,6 @@ private:
         ~ProgramCache();
 
         void abandon();
-        void invalidateViewMatrices();
         CachedData* getProgramData(const GrGLProgram& desc,
                                    GrCustomStage** stages);
     private:
@@ -239,6 +238,9 @@ private:
         const GrGLContextInfo&      fGL;
     };
 
+    // binds the texture and sets its texture params
+    void flushBoundTextureAndParams(int stage);
+
     // sets the texture matrix and domain for the currently bound program
     void flushTextureMatrixAndDomain(int stage);
 
index e79afe1..1f3216f 100644 (file)
@@ -39,13 +39,6 @@ void GrGpuGL::ProgramCache::abandon() {
     fCount = 0;
 }
 
-void GrGpuGL::ProgramCache::invalidateViewMatrices() {
-    for (int i = 0; i < fCount; ++i) {
-        // set to illegal matrix
-        fEntries[i].fProgramData.fViewMatrix = GrMatrix::InvalidMatrix();
-    }
-}
-
 GrGLProgram::CachedData* GrGpuGL::ProgramCache::getProgramData(
                                         const GrGLProgram& desc,
                                         GrCustomStage** stages) {
@@ -111,15 +104,20 @@ void GrGpuGL::abandonResources(){
 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
 
 void GrGpuGL::flushViewMatrix() {
+    const GrGLRenderTarget* rt = static_cast<const GrGLRenderTarget*>(this->getDrawState().getRenderTarget());
+    SkISize viewportSize;
+    const GrGLIRect& viewport = rt->getViewport();
+    viewportSize.set(viewport.fWidth, viewport.fHeight);
+
     const GrMatrix& vm = this->getDrawState().getViewMatrix();
-    if (!fProgramData->fViewMatrix.cheapEqualTo(vm)) {
 
-        const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
-        GrAssert(NULL != rt);
+    if (!fProgramData->fViewMatrix.cheapEqualTo(vm) ||
+        fProgramData->fViewportSize != viewportSize) {
+
         GrMatrix m;
         m.setAll(
-            GrIntToScalar(2) / rt->width(), 0, -GR_Scalar1,
-            0,-GrIntToScalar(2) / rt->height(), GR_Scalar1,
+            GrIntToScalar(2) / viewportSize.fWidth, 0, -GR_Scalar1,
+            0,-GrIntToScalar(2) / viewportSize.fHeight, GR_Scalar1,
             0, 0, GrMatrix::I()[8]);
         m.setConcat(m, vm);
 
@@ -142,6 +140,7 @@ void GrGpuGL::flushViewMatrix() {
         GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
                                  1, false, mt));
         fProgramData->fViewMatrix = vm;
+        fProgramData->fViewportSize = viewportSize;
     }
 }
 
@@ -438,6 +437,9 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
 
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         if (this->isStageEnabled(s)) {
+
+            this->flushBoundTextureAndParams(s);
+
             this->flushTextureMatrixAndDomain(s);
 
             this->flushTexelSize(s);
@@ -455,6 +457,18 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) {
         }
     }
     this->flushColorMatrix();
+
+    GrIRect* rect = NULL;
+    GrIRect clipBounds;
+    if (drawState.isClipState() &&
+        fClip.hasConservativeBounds()) {
+        fClip.getConservativeBounds().roundOut(&clipBounds);
+        rect = &clipBounds;
+    }
+    // This must come after textures are flushed because a texture may need
+    // to be msaa-resolved (which will modify bound FBO state).
+    this->flushRenderTarget(rect);
+
     return true;
 }