Index: src/gpu/gl/GrGpuGL.cpp |
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp |
index 0c47060e4f5033454caf5b1748762a57a4c6eb47..2f218a0c86e543f42f5393cc629709fb7fa3aa24 100644 |
--- a/src/gpu/gl/GrGpuGL.cpp |
+++ b/src/gpu/gl/GrGpuGL.cpp |
@@ -20,9 +20,6 @@ static const GrGLint GR_INVAL_GLINT = ~0; |
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) |
#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) |
-// we use a spare texture unit to avoid |
-// mucking with the state of any of the stages. |
-static const int SPARE_TEX_UNIT = GrDrawState::kNumStages; |
#define SKIP_CACHE_CHECK true |
@@ -118,35 +115,6 @@ bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { |
static bool gPrintStartupSpew; |
-static bool fbo_test(const GrGLInterface* gl, int w, int h) { |
- |
- GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); |
- |
- GrGLuint testFBO; |
- GR_GL_CALL(gl, GenFramebuffers(1, &testFBO)); |
- GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, testFBO)); |
- GrGLuint testRTTex; |
- GR_GL_CALL(gl, GenTextures(1, &testRTTex)); |
- GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, testRTTex)); |
- // some implementations require texture to be mip-map complete before |
- // FBO with level 0 bound as color attachment will be framebuffer complete. |
- GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, |
- GR_GL_TEXTURE_MIN_FILTER, |
- GR_GL_NEAREST)); |
- GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D, 0, GR_GL_RGBA, w, h, |
- 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, NULL)); |
- GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0)); |
- GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER, |
- GR_GL_COLOR_ATTACHMENT0, |
- GR_GL_TEXTURE_2D, testRTTex, 0)); |
- GrGLenum status; |
- GR_GL_CALL_RET(gl, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
- GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO)); |
- GR_GL_CALL(gl, DeleteTextures(1, &testRTTex)); |
- |
- return status == GR_GL_FRAMEBUFFER_COMPLETE; |
-} |
- |
GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) |
: GrGpu(context) |
, fGLContext(ctx) { |
@@ -155,6 +123,8 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) |
fCaps.reset(SkRef(ctx.info().caps())); |
+ fHWBoundTextures.reset(ctx.info().caps()->maxFragmentTextureUnits()); |
+ |
fillInConfigRenderableTable(); |
@@ -183,9 +153,6 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) |
GrAssert(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt); |
fLastSuccessfulStencilFmtIdx = 0; |
- if (false) { // avoid bit rot, suppress warning |
- fbo_test(this->glInterface(), 0, 0); |
- } |
} |
GrGpuGL::~GrGpuGL() { |
@@ -361,7 +328,7 @@ void GrGpuGL::onResetContext() { |
fHWBlendState.invalidate(); |
- for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
+ for (int s = 0; s < fHWBoundTextures.count(); ++s) { |
fHWBoundTextures[s] = NULL; |
} |
@@ -473,7 +440,6 @@ GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) { |
return NULL; |
} |
- this->setSpareTextureUnit(); |
return texture; |
} |
@@ -527,7 +493,7 @@ bool GrGpuGL::onWriteTexturePixels(GrTexture* texture, |
} |
GrGLTexture* glTex = static_cast<GrGLTexture*>(texture); |
- this->setSpareTextureUnit(); |
+ this->setScratchTextureUnit(); |
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); |
GrGLTexture::Desc desc; |
desc.fFlags = glTex->desc().fFlags; |
@@ -952,7 +918,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc, |
return return_null_texture(); |
} |
- this->setSpareTextureUnit(); |
+ this->setScratchTextureUnit(); |
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID)); |
// Some drivers like to know filter/wrap before seeing glTexImage2D. Some |
@@ -2102,7 +2068,7 @@ void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { |
} |
void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { |
- for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
+ for (int s = 0; s < fHWBoundTextures.count(); ++s) { |
if (fHWBoundTextures[s] == texture) { |
// deleting bound texture does implied bind to 0 |
fHWBoundTextures[s] = NULL; |
@@ -2222,18 +2188,23 @@ bool GrGpuGL::configToGLFormats(GrPixelConfig config, |
} |
void GrGpuGL::setTextureUnit(int unit) { |
- GrAssert(unit >= 0 && unit < GrDrawState::kNumStages); |
- if (fHWActiveTextureUnitIdx != unit) { |
+ GrAssert(unit >= 0 && unit < fHWBoundTextures.count()); |
+ if (unit != fHWActiveTextureUnitIdx) { |
GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit)); |
fHWActiveTextureUnitIdx = unit; |
} |
} |
-void GrGpuGL::setSpareTextureUnit() { |
- if (fHWActiveTextureUnitIdx != (GR_GL_TEXTURE0 + SPARE_TEX_UNIT)) { |
- GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); |
- fHWActiveTextureUnitIdx = SPARE_TEX_UNIT; |
+void GrGpuGL::setScratchTextureUnit() { |
+ // Bind the last texture unit since it is the least likely to be used by GrGLProgram. |
+ int lastUnitIdx = fHWBoundTextures.count() - 1; |
+ if (lastUnitIdx != fHWActiveTextureUnitIdx) { |
+ GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx)); |
+ fHWActiveTextureUnitIdx = lastUnitIdx; |
} |
+ // clear out the this field so that if a program does use this unit it will rebind the correct |
+ // texture. |
+ fHWBoundTextures[lastUnitIdx] = NULL; |
} |
namespace { |
@@ -2370,7 +2341,7 @@ bool GrGpuGL::onCopySurface(GrSurface* dst, |
srcRect.height(), |
src->origin()); |
- this->setSpareTextureUnit(); |
+ this->setScratchTextureUnit(); |
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); |
GrGLint dstY; |
if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { |