aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-10 14:51:57 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-10 14:51:57 +0000
commit1da0746fa155cdca982ae8deb68cc64f540c92df (patch)
tree26516a2f983e8179c9ffd539c7989e917ce3412e
parenta7f84e150cb9e821267a8ca9e59c1ae9a3cfa300 (diff)
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
-rw-r--r--gpu/include/GrGLTexture.h37
-rw-r--r--gpu/include/GrGpu.h7
-rw-r--r--gpu/include/GrInOrderDrawBuffer.h7
-rw-r--r--gpu/include/GrTexture.h21
-rw-r--r--gpu/src/GrContext.cpp4
-rw-r--r--gpu/src/GrGLTexture.cpp44
-rw-r--r--gpu/src/GrGpuGL.cpp18
-rw-r--r--gpu/src/GrGpuGL.h3
-rw-r--r--gpu/src/GrInOrderDrawBuffer.cpp10
-rw-r--r--src/gpu/SkGpuDevice.cpp4
10 files changed, 75 insertions, 80 deletions
diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h
index 14370abb80..7b7480ca87 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 16fbb93a25..75fb1f4eaa 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 d59eb96b08..79ec458dbb 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<Draw> 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<SavedDrawState> fStates;
GrTAllocator<GrClip> fClips;
diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h
index 2d3928cb25..666aa570f8 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 c6fa618920..cf51cc9e6f 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 ae991e8362..1acb871c79 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 b0d5e73bc9..1c3de1acb9 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 ab504adbb2..f9a6987772 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 b2fe581eed..8225425b41 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 86082c5e50..91a6319a17 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 = {