From: bsalomon@google.com Date: Thu, 10 Mar 2011 14:51:57 +0000 (+0000) Subject: Delete GL tex ID when last of GrGLTexture or GrGLRenderTarget that reference it is... X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~18862 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1da0746fa155cdca982ae8deb68cc64f540c92df;p=platform%2Fupstream%2FlibSkiaSharp.git Delete GL tex ID when last of GrGLTexture or GrGLRenderTarget that reference it is destroyed git-svn-id: http://skia.googlecode.com/svn/trunk@915 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h index 14370ab..7b7480c 100644 --- a/gpu/include/GrGLTexture.h +++ b/gpu/include/GrGLTexture.h @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,6 +25,26 @@ class GrGpuGL; class GrGLTexture; +/** + * A ref counted tex id that deletes the texture in its destructor. + */ +class GrGLTexID : public GrRefCnt { +public: + GrGLTexID(GLuint texID) : fTexID(texID) {} + + virtual ~GrGLTexID() { + if (0 != fTexID) { + GR_GL(DeleteTextures(1, &fTexID)); + } + } + + void abandon() { fTexID = 0; } + GLuint id() const { return fTexID; } + +private: + GLuint fTexID; +}; + class GrGLRenderTarget : public GrRenderTarget { public: virtual ~GrGLRenderTarget(); @@ -49,6 +69,7 @@ protected: }; GrGLRenderTarget(const GLRenderTargetIDs& ids, + GrGLTexID* texID, GLuint stencilBits, const GrGLIRect& fViewport, GrGLTexture* texture, @@ -59,7 +80,7 @@ protected: private: GrGpuGL* fGL; GLuint fRTFBOID; - GLuint fTexFBOID; + GLuint fTexFBOID; GLuint fStencilRenderbufferID; GLuint fMSColorRenderbufferID; @@ -75,7 +96,10 @@ private: // only render to to content area (as opposed to the whole allocation) and // we want the rendering to be at top left (GL has origin in bottom left) GrGLIRect fViewport; - + + // non-NULL if this RT was created by Gr with an associated GrGLTexture. + GrGLTexID* fTexIDObj; + friend class GrGpuGL; friend class GrGLTexture; @@ -120,9 +144,8 @@ public: // overloads of GrTexture virtual void abandon(); - virtual bool isRenderTarget() const; virtual GrRenderTarget* asRenderTarget(); - virtual void removeRenderTarget(); + virtual void releaseRenderTarget(); virtual void uploadTextureData(uint32_t x, uint32_t y, uint32_t width, @@ -132,7 +155,7 @@ public: const TexParams& getTexParams() const { return fTexParams; } void setTexParams(const TexParams& texParams) { fTexParams = texParams; } - GLuint textureID() const { return fTextureID; } + GLuint textureID() const { return fTexIDObj->id(); } GLenum uploadFormat() const { return fUploadFormat; } GLenum uploadByteCount() const { return fUploadByteCount; } @@ -174,7 +197,7 @@ public: private: TexParams fTexParams; - GLuint fTextureID; + GrGLTexID* fTexIDObj; GLenum fUploadFormat; GLenum fUploadByteCount; GLenum fUploadType; diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h index 16fbb93..75fb1f4 100644 --- a/gpu/include/GrGpu.h +++ b/gpu/include/GrGpu.h @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -156,6 +156,11 @@ public: * will be embedded in a power of two texture. The extra width and height * is filled as though srcData were rendered clamped into the texture. * + * If kRenderTarget_TextureFlag is specified the GrRenderTarget is + * accessible via GrTexture::asRenderTarget(). The texture will hold a ref + * on the render target until its releaseRenderTarget() is called or it is + * destroyed. + * * @param desc describes the texture to be created. * @param srcData texel data to load texture. Begins with full-size * palette data for paletted textures. Contains width* diff --git a/gpu/include/GrInOrderDrawBuffer.h b/gpu/include/GrInOrderDrawBuffer.h index d59eb96..79ec458 100644 --- a/gpu/include/GrInOrderDrawBuffer.h +++ b/gpu/include/GrInOrderDrawBuffer.h @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -134,11 +134,6 @@ private: void pushClip(); GrTAllocator fDraws; - // HACK: We currently do not hold refs on RTs in the saved draw states. - // The reason is that in the GL implementation when a GrTexture is destroyed - // that has an associated RT the RT is destroyed regardless of its ref count. - // We need a third object that holds the shared GL ids and persists until - // both reach ref count 0. (skia issue 122) GrTAllocator fStates; GrTAllocator fClips; diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h index 2d3928c..666aa57 100644 --- a/gpu/include/GrTexture.h +++ b/gpu/include/GrTexture.h @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -161,31 +161,20 @@ public: virtual void abandon() = 0; /** - * Queries whether the texture was created as a render target. - * - * Use asRenderTarget() to use the texture as a render target if this - * returns true. - * - * @return true if the texture was created as a render target. - */ - virtual bool isRenderTarget() const = 0; - - /** * Retrieves the render target underlying this texture that can be passed to * GrGpu::setRenderTarget(). * - * If isRenderTarget() is false then the returned handle is undefined. - * * @return handle to render target or undefined if the texture is not a * render target */ virtual GrRenderTarget* asRenderTarget() = 0; /** - * Removes the "rendertargetness" from a texture. This may or may not - * actually do anything with the underlying 3D API. + * Removes the reference on the associated GrRenderTarget held by this + * texture. Afterwards asRenderTarget() will return NULL. The + * GrRenderTarget survives the release if another ref is held on it. */ - virtual void removeRenderTarget() = 0; + virtual void releaseRenderTarget() = 0; /** * Return the native ID or handle to the texture, depending on the diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp index c6fa618..cf51cc9 100644 --- a/gpu/src/GrContext.cpp +++ b/gpu/src/GrContext.cpp @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -172,7 +172,7 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key, 0, 4); entry = fTextureCache->createAndLock(*key, texture); } - texture->removeRenderTarget(); + texture->releaseRenderTarget(); } else { // TODO: Our CPU stretch doesn't filter. But we create separate // stretched textures when the sampler state is either filtered or diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp index ae991e8..1acb871 100644 --- a/gpu/src/GrGLTexture.cpp +++ b/gpu/src/GrGLTexture.cpp @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ #include "GrGpuGL.h" GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids, + GrGLTexID* texID, GLuint stencilBits, const GrGLIRect& viewport, GrGLTexture* texture, @@ -34,6 +35,8 @@ GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids, fNeedsResolve = false; fViewport = viewport; fOwnIDs = ids.fOwnIDs; + fTexIDObj = texID; + GrSafeRef(fTexIDObj); } GrGLRenderTarget::~GrGLRenderTarget() { @@ -52,6 +55,7 @@ GrGLRenderTarget::~GrGLRenderTarget() { GR_GLEXT(fGL->extensions(), DeleteRenderbuffers(1, &fMSColorRenderbufferID)); } } + GrSafeUnref(fTexIDObj); } void GrGLRenderTarget::abandon() { @@ -59,6 +63,9 @@ void GrGLRenderTarget::abandon() { fTexFBOID = 0; fStencilRenderbufferID = 0; fMSColorRenderbufferID = 0; + if (NULL != fTexIDObj) { + fTexIDObj->abandon(); + } } @@ -84,7 +91,7 @@ GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc, textureDesc.fFormat) { fTexParams = initialTexParams; - fTextureID = textureDesc.fTextureID; + fTexIDObj = new GrGLTexID(textureDesc.fTextureID); fUploadFormat = textureDesc.fUploadFormat; fUploadByteCount = textureDesc.fUploadByteCount; fUploadType = textureDesc.fUploadType; @@ -108,43 +115,32 @@ GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc, vp.fHeight = textureDesc.fContentHeight; vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight; - fRenderTarget = new GrGLRenderTarget(rtIDs, textureDesc.fStencilBits, + fRenderTarget = new GrGLRenderTarget(rtIDs, fTexIDObj, + textureDesc.fStencilBits, vp, this, gl); } } GrGLTexture::~GrGLTexture() { - // make sure we haven't been abandoned - if (fTextureID) { - fGpuGL->notifyTextureDelete(this); - GR_GL(DeleteTextures(1, &fTextureID)); - } - delete fRenderTarget; + fGpuGL->notifyTextureDelete(this); + fTexIDObj->unref(); + GrSafeUnref(fRenderTarget); } void GrGLTexture::abandon() { - fTextureID = 0; + fTexIDObj->abandon(); if (NULL != fRenderTarget) { fRenderTarget->abandon(); } } -bool GrGLTexture::isRenderTarget() const { - return NULL != fRenderTarget; -} - GrRenderTarget* GrGLTexture::asRenderTarget() { return (GrRenderTarget*)fRenderTarget; } -void GrGLTexture::removeRenderTarget() { - GrAssert(NULL != fRenderTarget); - if (NULL != fRenderTarget) { - // must do this notify before the delete - fGpuGL->notifyTextureRemoveRenderTarget(this); - delete fRenderTarget; - fRenderTarget = NULL; - } +void GrGLTexture::releaseRenderTarget() { + GrSafeUnref(fRenderTarget); + fRenderTarget = NULL; } void GrGLTexture::uploadTextureData(uint32_t x, @@ -162,7 +158,7 @@ void GrGLTexture::uploadTextureData(uint32_t x, // If we need to update textures that are created upside down // then we have to modify this code to flip the srcData GrAssert(kTopDown_Orientation == fOrientation); - GR_GL(BindTexture(GL_TEXTURE_2D, fTextureID)); + GR_GL(BindTexture(GL_TEXTURE_2D, fTexIDObj->id())); GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, fUploadByteCount)); GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, fUploadFormat, fUploadType, srcData)); @@ -170,7 +166,7 @@ void GrGLTexture::uploadTextureData(uint32_t x, } intptr_t GrGLTexture::getTextureHandle() { - return fTextureID; + return fTexIDObj->id(); } diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp index b0d5e73..1c3de1a 100644 --- a/gpu/src/GrGpuGL.cpp +++ b/gpu/src/GrGpuGL.cpp @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -510,7 +510,7 @@ GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper( rtIDs.fRTFBOID = (GLuint)platformRenderTarget; rtIDs.fTexFBOID = (GLuint)platformRenderTarget; - return new GrGLRenderTarget(rtIDs, stencilBits, viewport, NULL, this); + return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this); } GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() { @@ -529,7 +529,7 @@ GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() { rtIDs.fOwnIDs = false; - return new GrGLRenderTarget(rtIDs, stencilBits, viewport, NULL, this); + return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this); } /////////////////////////////////////////////////////////////////////////////// @@ -1694,11 +1694,6 @@ void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) { void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { GrAssert(NULL != renderTarget); - - // if the bound FBO is destroyed we can't rely on the implicit bind to 0 - // a) we want the default RT which may not be FBO 0 - // b) we set more state than just FBO based on the RT - // So trash the HW state to force an RT flush next time if (fCurrDrawState.fRenderTarget == renderTarget) { fCurrDrawState.fRenderTarget = NULL; } @@ -1719,13 +1714,6 @@ void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { } } -void GrGpuGL::notifyTextureRemoveRenderTarget(GrGLTexture* texture) { - GrAssert(NULL != texture->asRenderTarget()); - - // if there is a pending resolve, perform it. - resolveTextureRenderTarget(texture); -} - bool GrGpuGL::canBeTexture(GrTexture::PixelConfig config, GLenum* internalFormat, GLenum* format, diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h index ab504ad..f9a6987 100644 --- a/gpu/src/GrGpuGL.h +++ b/gpu/src/GrGpuGL.h @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -151,7 +151,6 @@ private: void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer); void notifyTextureDelete(GrGLTexture* texture); void notifyRenderTargetDelete(GrRenderTarget* renderTarget); - void notifyTextureRemoveRenderTarget(GrGLTexture* texture); void setSpareTextureUnit(); diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp index b2fe581..8225425 100644 --- a/gpu/src/GrInOrderDrawBuffer.cpp +++ b/gpu/src/GrInOrderDrawBuffer.cpp @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -291,12 +291,11 @@ void GrInOrderDrawBuffer::reset() { GrAssert(!fReservedGeometry.fLocked); uint32_t numStates = fStates.count(); for (uint32_t i = 0; i < numStates; ++i) { + const DrState& dstate = this->accessSavedDrawState(fStates[i]); for (int s = 0; s < kNumStages; ++s) { - GrTexture* tex = this->accessSavedDrawState(fStates[i]).fTextures[s]; - if (NULL != tex) { - tex->unref(); - } + GrSafeUnref(dstate.fTextures[s]); } + GrSafeUnref(dstate.fRenderTarget); } int numDraws = fDraws.count(); for (int d = 0; d < numDraws; ++d) { @@ -499,6 +498,7 @@ void GrInOrderDrawBuffer::pushState() { for (int s = 0; s < kNumStages; ++s) { GrSafeRef(fCurrDrawState.fTextures[s]); } + GrSafeRef(fCurrDrawState.fRenderTarget); this->saveCurrentDrawState(&fStates.push_back()); } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 86082c5..91a6319 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1,5 +1,5 @@ /* - Copyright 2010 Google Inc. + Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -142,7 +142,7 @@ SkGpuDevice::SkGpuDevice(GrContext* context, &fTexture, true); if (fCache) { SkASSERT(NULL != fTexture); - SkASSERT(fTexture->isRenderTarget()); + SkASSERT(NULL != fTexture->asRenderTarget()); } #else const GrGpu::TextureDesc desc = {