diff options
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 165 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 38 |
5 files changed, 109 insertions, 102 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 6c22f46e02..2512ba0408 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -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; } diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index f638eabf64..be154b0160 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -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) diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 90fb2a69b3..42043f9f6e 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -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(×tamp); + 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(×tamp); - 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()) { diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index b0a7bdc653..b5dd09ab51 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -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); diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index e79afe15e2..1f3216f3ef 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -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; } |