move texture flush and param update to separate function

Review URL: http://codereview.appspot.com/6266044/



git-svn-id: http://skia.googlecode.com/svn/trunk@4142 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-06-04 19:05:11 +00:00
parent 8b0d0f6a9c
commit 4c8837867a
5 changed files with 110 additions and 103 deletions

View 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;
}

View 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)

View 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()) {

View 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);

View 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 GrMatrix& vm = this->getDrawState().getViewMatrix();
if (!fProgramData->fViewMatrix.cheapEqualTo(vm)) {
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) ||
fProgramData->fViewportSize != viewportSize) {
const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
GrAssert(NULL != rt);
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;
}