Use the GrCacheable ID to eliminate the need for notifications to GrGpuGL when textures and RTs are deleted. Also, rename GrCacheable::getGenerationID() to getInstanceID() since it doesn't behave like other "generation" IDs. R=jvanverth@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/376703009
diff --git a/include/gpu/GrCacheable.h b/include/gpu/GrCacheable.h index 344ae6b..5cd9b0d 100644 --- a/include/gpu/GrCacheable.h +++ b/include/gpu/GrCacheable.h
@@ -46,12 +46,12 @@ * not change when the content of the GrCacheable object changes. This will never return * 0. */ - uint32_t getGenerationID() const; + uint64_t getInstanceID() const { return fInstanceID; } protected: GrCacheable() : fCacheEntry(NULL) - , fGenID(0) {} + , fInstanceID(CreateInstanceID()) {} bool isInCache() const { return NULL != fCacheEntry; } @@ -64,8 +64,10 @@ void didChangeGpuMemorySize() const; private: + static uint64_t CreateInstanceID(); + GrResourceCacheEntry* fCacheEntry; // NULL if not in cache - mutable uint32_t fGenID; + mutable uint64_t fInstanceID; typedef SkRefCnt INHERITED; };
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index 25c13ec..78b6174 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp
@@ -56,7 +56,7 @@ fCurrTexture = NULL; fCurrVertex = 0; - fEffectTextureGenID = 0; + fEffectTextureInstanceID = 0; fVertices = NULL; fMaxVertices = 0; @@ -94,11 +94,11 @@ SkASSERT(fCurrTexture); GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode); - uint32_t textureGenID = fCurrTexture->getGenerationID(); + uint64_t textureInstanceID = fCurrTexture->getInstanceID(); - if (textureGenID != fEffectTextureGenID) { + if (textureInstanceID != fEffectTextureInstanceID) { fCachedEffect.reset(GrCustomCoordsTextureEffect::Create(fCurrTexture, params)); - fEffectTextureGenID = textureGenID; + fEffectTextureInstanceID = textureInstanceID; } // This effect could be stored with one of the cache objects (atlas?)
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h index b9d5ce7..c9bb9fd 100644 --- a/src/gpu/GrBitmapTextContext.h +++ b/src/gpu/GrBitmapTextContext.h
@@ -48,7 +48,7 @@ int32_t fMaxVertices; GrTexture* fCurrTexture; SkAutoTUnref<GrEffect> fCachedEffect; - uint32_t fEffectTextureGenID; + uint64_t fEffectTextureInstanceID; int fCurrVertex; SkRect fVertexBounds; };
diff --git a/src/gpu/GrCacheable.cpp b/src/gpu/GrCacheable.cpp index 120be78..6047f39 100644 --- a/src/gpu/GrCacheable.cpp +++ b/src/gpu/GrCacheable.cpp
@@ -8,10 +8,11 @@ #include "GrCacheable.h" -uint32_t GrCacheable::getGenerationID() const { - static int32_t gPathRefGenerationID; - while (!fGenID) { - fGenID = static_cast<uint32_t>(sk_atomic_inc(&gPathRefGenerationID) + 1); - } - return fGenID; +uint64_t GrCacheable::CreateInstanceID() { + static int64_t gCacheableID; + uint64_t id; + do { + id = static_cast<uint64_t>(sk_atomic_inc(&gCacheableID) + 1); + } while (!id); + return id; }
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp index f2a0cdc..2486396 100644 --- a/src/gpu/gl/GrGLRenderTarget.cpp +++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -79,7 +79,6 @@ } void GrGLRenderTarget::onRelease() { - GPUGL->notifyRenderTargetDelete(this); if (!this->isWrapped()) { if (fTexFBOID) { GL_CALL(DeleteFramebuffers(1, &fTexFBOID));
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp index 856cfb1..255cdd9 100644 --- a/src/gpu/gl/GrGLTexture.cpp +++ b/src/gpu/gl/GrGLTexture.cpp
@@ -49,7 +49,6 @@ } void GrGLTexture::onRelease() { - GPUGL->notifyTextureDelete(this); fTexIDObj.reset(NULL); INHERITED::onRelease(); }
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 3a2be13..52e3c33 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp
@@ -120,7 +120,7 @@ SkASSERT(ctx.isInitialized()); fCaps.reset(SkRef(ctx.caps())); - fHWBoundTextures.reset(this->glCaps().maxFragmentTextureUnits()); + fHWBoundTextureInstanceIDs.reset(this->glCaps().maxFragmentTextureUnits()); fHWPathTexGenSettings.reset(this->glCaps().maxFixedFunctionTextureCoords()); GrGLClearErr(fGLContext.interface()); @@ -273,8 +273,8 @@ fHWActiveTextureUnitIdx = -1; // invalid if (resetBits & kTextureBinding_GrGLBackendState) { - for (int s = 0; s < fHWBoundTextures.count(); ++s) { - fHWBoundTextures[s] = NULL; + for (int s = 0; s < fHWBoundTextureInstanceIDs.count(); ++s) { + fHWBoundTextureInstanceIDs[s] = 0; } } @@ -298,7 +298,7 @@ } if (resetBits & kRenderTarget_GrGLBackendState) { - fHWBoundRenderTarget = NULL; + fHWBoundRenderTargetInstanceID = 0; } if (resetBits & kPathRendering_GrGLBackendState) { @@ -867,7 +867,7 @@ } // below here we may bind the FBO - fHWBoundRenderTarget = NULL; + fHWBoundRenderTargetInstanceID = 0; if (desc->fRTFBOID != desc->fTexFBOID) { SkASSERT(desc->fSampleCnt > 0); GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, @@ -1252,7 +1252,7 @@ GrGLStencilBuffer* glsb = static_cast<GrGLStencilBuffer*>(sb); GrGLuint rb = glsb->renderbufferID(); - fHWBoundRenderTarget = NULL; + fHWBoundRenderTargetInstanceID = 0; GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo)); GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER, GR_GL_STENCIL_ATTACHMENT, @@ -1458,8 +1458,8 @@ } GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget); - if (renderTarget != fHWBoundRenderTarget) { - fHWBoundRenderTarget = NULL; + if (renderTarget->getInstanceID() != fHWBoundRenderTargetInstanceID) { + fHWBoundRenderTargetInstanceID = 0; GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID())); } switch (this->glCaps().invalidateFBType()) { @@ -1722,7 +1722,8 @@ static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget()); SkASSERT(NULL != rt); - if (fHWBoundRenderTarget != rt) { + uint64_t rtID = rt->getInstanceID(); + if (fHWBoundRenderTargetInstanceID != rtID) { GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID())); #ifdef SK_DEBUG // don't do this check in Chromium -- this is causing @@ -1737,7 +1738,7 @@ } } #endif - fHWBoundRenderTarget = rt; + fHWBoundRenderTargetInstanceID = rtID; const GrGLIRect& vp = rt->getViewport(); if (fHWViewport != vp) { vp.pushToGLViewport(this->glInterface()); @@ -2004,7 +2005,7 @@ GL_CALL(BindFramebuffer(GR_GL_DRAW_FRAMEBUFFER, rt->textureFBOID())); // make sure we go through flushRenderTarget() since we've modified // the bound DRAW FBO ID. - fHWBoundRenderTarget = NULL; + fHWBoundRenderTargetInstanceID = 0; const GrGLIRect& vp = rt->getViewport(); const SkIRect dirtyRect = rt->getResolveRect(); GrGLIRect r; @@ -2298,10 +2299,11 @@ this->onResolveRenderTarget(texRT); } - if (fHWBoundTextures[unitIdx] != texture) { + uint64_t textureID = texture->getInstanceID(); + if (fHWBoundTextureInstanceIDs[unitIdx] != textureID) { this->setTextureUnit(unitIdx); GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID())); - fHWBoundTextures[unitIdx] = texture; + fHWBoundTextureInstanceIDs[unitIdx] = textureID; } ResetTimestamp timestamp; @@ -2529,23 +2531,6 @@ } } -void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { - SkASSERT(NULL != renderTarget); - if (fHWBoundRenderTarget == renderTarget) { - fHWBoundRenderTarget = NULL; - } -} - -void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { - for (int s = 0; s < fHWBoundTextures.count(); ++s) { - if (fHWBoundTextures[s] == texture) { - // deleting bound texture does implied bind to 0 - fHWBoundTextures[s] = NULL; - } - } -} - - GrGLuint GrGpuGL::createGLPathObject() { if (NULL == fPathNameAllocator.get()) { static const int range = 65536; @@ -2716,7 +2701,7 @@ } void GrGpuGL::setTextureUnit(int unit) { - SkASSERT(unit >= 0 && unit < fHWBoundTextures.count()); + SkASSERT(unit >= 0 && unit < fHWBoundTextureInstanceIDs.count()); if (unit != fHWActiveTextureUnitIdx) { GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit)); fHWActiveTextureUnitIdx = unit; @@ -2725,14 +2710,14 @@ void GrGpuGL::setScratchTextureUnit() { // Bind the last texture unit since it is the least likely to be used by GrGLProgram. - int lastUnitIdx = fHWBoundTextures.count() - 1; + int lastUnitIdx = fHWBoundTextureInstanceIDs.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; + fHWBoundTextureInstanceIDs[lastUnitIdx] = 0; } namespace { @@ -2869,7 +2854,7 @@ GrGLTexture* dstTex = static_cast<GrGLTexture*>(dst->asTexture()); SkASSERT(NULL != dstTex); // We modified the bound FBO - fHWBoundRenderTarget = NULL; + fHWBoundRenderTargetInstanceID = 0; GrGLIRect srcGLRect; srcGLRect.setRelativeTo(srcVP, srcRect.fLeft, @@ -2911,7 +2896,7 @@ dstFBO = bind_surface_as_fbo(this->glInterface(), dst, GR_GL_DRAW_FRAMEBUFFER, &dstVP); srcFBO = bind_surface_as_fbo(this->glInterface(), src, GR_GL_READ_FRAMEBUFFER, &srcVP); // We modified the bound FBO - fHWBoundRenderTarget = NULL; + fHWBoundRenderTargetInstanceID = 0; GrGLIRect srcGLRect; GrGLIRect dstGLRect; srcGLRect.setRelativeTo(srcVP,
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index a2c636d..509c4c1 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h
@@ -105,8 +105,6 @@ void notifyIndexBufferDelete(GrGLuint id) { fHWGeometryState.notifyIndexBufferDelete(id); } - void notifyTextureDelete(GrGLTexture* texture); - void notifyRenderTargetDelete(GrRenderTarget* renderTarget); // These functions should be used to generate and delete GL path names. They have their own // allocator that runs on the client side, so they are much faster than going through GenPaths. @@ -464,8 +462,8 @@ GrDrawState::DrawFace fHWDrawFace; TriState fHWWriteToColor; TriState fHWDitherEnabled; - GrRenderTarget* fHWBoundRenderTarget; - SkTArray<GrTexture*, true> fHWBoundTextures; + uint64_t fHWBoundRenderTargetInstanceID; + SkTArray<uint64_t, true> fHWBoundTextureInstanceIDs; struct PathTexGenData { GrGLenum fMode;