aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/gl/GrGLProgram.cpp1
-rw-r--r--src/gpu/gl/GrGLProgram.h3
-rw-r--r--src/gpu/gl/GrGpuGL.cpp165
-rw-r--r--src/gpu/gl/GrGpuGL.h4
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp38
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(&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()) {
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;
}