aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2014-11-14 13:33:09 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-11-14 13:33:09 -0800
commit12299ab7a1be5f4b99284ecf289d46107ef0a946 (patch)
tree975b65e8d15cb7c7a6ffc3f1b2b820b4b0da978d
parent85588344c3ef43768e27881f71079edb372119b5 (diff)
Make GrResourceCache2 responsible for calling release, abandon, and ~.
BUG=skia:2889 TBR=robertphillips@google.com NOTRY=true Review URL: https://codereview.chromium.org/729683002
-rw-r--r--bench/GrResourceCacheBench.cpp4
-rw-r--r--include/gpu/GrGpuResource.h50
-rw-r--r--src/gpu/GrGpuResource.cpp34
-rw-r--r--src/gpu/GrGpuResourceCacheAccess.h20
-rw-r--r--src/gpu/GrResourceCache2.cpp38
-rw-r--r--src/gpu/GrResourceCache2.h4
-rw-r--r--src/gpu/gl/GrGLIndexBuffer.h1
-rw-r--r--src/gpu/gl/GrGLPath.cpp4
-rw-r--r--src/gpu/gl/GrGLPath.h1
-rw-r--r--src/gpu/gl/GrGLPathRange.cpp4
-rw-r--r--src/gpu/gl/GrGLPathRange.h2
-rw-r--r--src/gpu/gl/GrGLRenderTarget.h2
-rw-r--r--src/gpu/gl/GrGLStencilBuffer.cpp4
-rw-r--r--src/gpu/gl/GrGLStencilBuffer.h2
-rw-r--r--src/gpu/gl/GrGLTexture.h2
-rw-r--r--src/gpu/gl/GrGLTextureRenderTarget.h2
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.h1
-rw-r--r--src/gpu/gl/GrGpuGL.cpp31
-rw-r--r--tests/ResourceCacheTest.cpp1
19 files changed, 91 insertions, 116 deletions
diff --git a/bench/GrResourceCacheBench.cpp b/bench/GrResourceCacheBench.cpp
index ef97ed8971..e1ec90d511 100644
--- a/bench/GrResourceCacheBench.cpp
+++ b/bench/GrResourceCacheBench.cpp
@@ -33,8 +33,6 @@ public:
this->registerWithCache();
}
- virtual ~StencilResource() { this->release(); }
-
static GrResourceKey ComputeKey(int width, int height, int sampleCnt) {
return GrStencilBuffer::ComputeKey(width, height, sampleCnt);
}
@@ -58,8 +56,6 @@ public:
this->registerWithCache();
}
- virtual ~TextureResource() { this->release(); }
-
static GrResourceKey ComputeKey(const GrSurfaceDesc& desc) {
GrCacheID::Key key;
memset(&key, 0, sizeof(key));
diff --git a/include/gpu/GrGpuResource.h b/include/gpu/GrGpuResource.h
index 3c87117124..c5b8ca5fbb 100644
--- a/include/gpu/GrGpuResource.h
+++ b/include/gpu/GrGpuResource.h
@@ -56,21 +56,20 @@ public:
this->didUnref();
}
- bool isPurgable() const { return this->reffedOnlyByCache() && !this->internalHasPendingIO(); }
- bool reffedOnlyByCache() const { return 1 == fRefCnt; }
-
void validate() const {
#ifdef SK_DEBUG
SkASSERT(fRefCnt >= 0);
SkASSERT(fPendingReads >= 0);
SkASSERT(fPendingWrites >= 0);
- SkASSERT(fRefCnt + fPendingReads + fPendingWrites > 0);
+ SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0);
#endif
}
protected:
GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { }
+ bool isPurgable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); }
+
bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
@@ -102,14 +101,8 @@ private:
private:
void didUnref() const {
- if (0 == fPendingReads && 0 == fPendingWrites) {
- if (0 == fRefCnt) {
- // Must call derived destructor since this is not a virtual class.
- SkDELETE(static_cast<const DERIVED*>(this));
- } else if (1 == fRefCnt) {
- // The one ref is the cache's
- static_cast<const DERIVED*>(this)->notifyIsPurgable();
- }
+ if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) {
+ static_cast<const DERIVED*>(this)->notifyIsPurgable();
}
}
@@ -132,18 +125,6 @@ public:
SK_DECLARE_INST_COUNT(GrGpuResource)
/**
- * Frees the object in the underlying 3D API. It must be safe to call this
- * when the object has been previously abandoned.
- */
- void release();
-
- /**
- * Removes references to objects in the underlying 3D API without freeing
- * them. Used when the API context has been torn down before the GrContext.
- */
- void abandon();
-
- /**
* Tests whether a object has been abandoned or released. All objects will
* be in this state after their creating GrContext is destroyed or has
* contextLost called. It's up to the client to test wasDestroyed() before
@@ -203,10 +184,12 @@ protected:
GrGpu* getGpu() const { return fGpu; }
- // Derived classes should always call their parent class' onRelease
- // and onAbandon methods in their overrides.
- virtual void onRelease() {};
- virtual void onAbandon() {};
+ /** Overridden to free GPU resources in the backend API. */
+ virtual void onRelease() { }
+ /** Overridden to abandon any internal handles, ptrs, etc to backend API resources.
+ This may be called when the underlying 3D context is no longer valid and so no
+ backend API calls should be made. */
+ virtual void onAbandon() { }
bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
@@ -223,6 +206,17 @@ protected:
void setScratchKey(const GrResourceKey& scratchKey);
private:
+ /**
+ * Frees the object in the underlying 3D API. Called by CacheAccess.
+ */
+ void release();
+
+ /**
+ * Removes references to objects in the underlying 3D API without freeing them.
+ * Called by CacheAccess.
+ */
+ void abandon();
+
virtual size_t onGpuMemorySize() const = 0;
// See comments in CacheAccess.
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp
index be8ea0daf0..fcc5f4de50 100644
--- a/src/gpu/GrGpuResource.cpp
+++ b/src/gpu/GrGpuResource.cpp
@@ -36,26 +36,24 @@ void GrGpuResource::registerWithCache() {
}
GrGpuResource::~GrGpuResource() {
- // subclass should have released this.
+ // The cache should have released or destroyed this resource.
SkASSERT(this->wasDestroyed());
}
void GrGpuResource::release() {
- if (fGpu) {
- this->onRelease();
- get_resource_cache2(fGpu)->resourceAccess().removeResource(this);
- fGpu = NULL;
- fGpuMemorySize = 0;
- }
+ SkASSERT(fGpu);
+ this->onRelease();
+ get_resource_cache2(fGpu)->resourceAccess().removeResource(this);
+ fGpu = NULL;
+ fGpuMemorySize = 0;
}
void GrGpuResource::abandon() {
- if (fGpu) {
- this->onAbandon();
- get_resource_cache2(fGpu)->resourceAccess().removeResource(this);
- fGpu = NULL;
- fGpuMemorySize = 0;
- }
+ SkASSERT(fGpu);
+ this->onAbandon();
+ get_resource_cache2(fGpu)->resourceAccess().removeResource(this);
+ fGpu = NULL;
+ fGpuMemorySize = 0;
}
const GrContext* GrGpuResource::getContext() const {
@@ -90,7 +88,7 @@ bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) {
SkASSERT(!contentKey.isScratch());
SkASSERT(this->internalHasRef());
- if (fContentKeySet) {
+ if (fContentKeySet || this->wasDestroyed()) {
return false;
}
@@ -105,8 +103,12 @@ bool GrGpuResource::setContentKey(const GrResourceKey& contentKey) {
}
void GrGpuResource::notifyIsPurgable() const {
- if (!this->wasDestroyed()) {
- get_resource_cache2(fGpu)->resourceAccess().notifyPurgable(this);
+ if (this->wasDestroyed()) {
+ // We've already been removed from the cache. Goodbye cruel world!
+ SkDELETE(this);
+ } else {
+ GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this);
+ get_resource_cache2(fGpu)->resourceAccess().notifyPurgable(mutableThis);
}
}
diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h
index 7417a55a71..3c3786d053 100644
--- a/src/gpu/GrGpuResourceCacheAccess.h
+++ b/src/gpu/GrGpuResourceCacheAccess.h
@@ -54,6 +54,26 @@ public:
return NULL;
}
+ /**
+ * Called by the cache to delete the resource under normal circumstances.
+ */
+ void release() {
+ fResource->release();
+ if (fResource->isPurgable()) {
+ SkDELETE(fResource);
+ }
+ }
+
+ /**
+ * Called by the cache to delete the resource when the backend 3D context is no longer valid.
+ */
+ void abandon() {
+ fResource->abandon();
+ if (fResource->isPurgable()) {
+ SkDELETE(fResource);
+ }
+ }
+
private:
CacheAccess(GrGpuResource* resource) : fResource(resource) { }
CacheAccess(const CacheAccess& that) : fResource(that.fResource) { }
diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp
index 53e7f88112..3f7498c325 100644
--- a/src/gpu/GrResourceCache2.cpp
+++ b/src/gpu/GrResourceCache2.cpp
@@ -93,7 +93,6 @@ void GrResourceCache2::insertResource(GrGpuResource* resource) {
SkASSERT(!this->isInCache(resource));
SkASSERT(!fPurging);
fResources.addToHead(resource);
- resource->ref();
++fCount;
SkDEBUGCODE(fHighWaterCount = SkTMax(fCount, fHighWaterCount));
@@ -129,8 +128,7 @@ void GrResourceCache2::abandonAll() {
SkASSERT(!fPurging);
while (GrGpuResource* head = fResources.head()) {
SkASSERT(!head->wasDestroyed());
- head->abandon();
- head->unref();
+ head->cacheAccess().abandon();
// abandon should have already removed this from the list.
SkASSERT(head != fResources.head());
}
@@ -145,8 +143,7 @@ void GrResourceCache2::releaseAll() {
SkASSERT(!fPurging);
while (GrGpuResource* head = fResources.head()) {
SkASSERT(!head->wasDestroyed());
- head->release();
- head->unref();
+ head->cacheAccess().release();
// release should have already removed this from the list.
SkASSERT(head != fResources.head());
}
@@ -159,7 +156,7 @@ public:
AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { }
bool operator()(const GrGpuResource* resource) const {
- if (!resource->reffedOnlyByCache() || !resource->cacheAccess().isScratch()) {
+ if (resource->internalHasRef() || !resource->cacheAccess().isScratch()) {
return false;
}
@@ -224,7 +221,7 @@ void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) {
fResources.addToHead(resource);
}
-void GrResourceCache2::notifyPurgable(const GrGpuResource* resource) {
+void GrResourceCache2::notifyPurgable(GrGpuResource* resource) {
SkASSERT(resource);
SkASSERT(this->isInCache(resource));
SkASSERT(resource->isPurgable());
@@ -239,25 +236,14 @@ void GrResourceCache2::notifyPurgable(const GrGpuResource* resource) {
// Purge the resource if we're over budget
bool overBudget = fCount > fMaxCount || fBytes > fMaxBytes;
- // We should not be over budget here unless all resources are unpuragble.
-#ifdef SK_DEBUG
- if (overBudget) {
- ResourceList::Iter iter;
- GrGpuResource* r = iter.init(fResources, ResourceList::Iter::kHead_IterStart);
- for ( ; r; r = iter.next()) {
- SkASSERT(r == resource || !r->isPurgable());
- }
- }
-#endif
-
// Also purge if the resource has neither a valid scratch key nor a content key.
bool noKey = !resource->cacheAccess().isScratch() &&
(NULL == resource->cacheAccess().getContentKey());
if (overBudget || noKey) {
SkDEBUGCODE(int beforeCount = fCount;)
- resource->unref();
- // We should at least have freed resource. It may have in turn freed other resources.
+ resource->cacheAccess().release();
+ // We should at least free this resource, perhaps dependent resources as well.
SkASSERT(fCount < beforeCount);
}
@@ -295,7 +281,7 @@ void GrResourceCache2::internalPurgeAsNeeded() {
while (resource) {
GrGpuResource* prev = resourceIter.prev();
if (resource->isPurgable()) {
- resource->unref();
+ resource->cacheAccess().release();
}
resource = prev;
if (fCount <= fMaxCount && fBytes <= fMaxBytes) {
@@ -331,8 +317,8 @@ void GrResourceCache2::purgeAllUnlocked() {
while (resource) {
GrGpuResource* prev = resourceIter.prev();
if (resource->isPurgable()) {
- resource->unref();
- }
+ resource->cacheAccess().release();
+ }
resource = prev;
}
@@ -387,8 +373,10 @@ void GrResourceCache2::validate() const {
SkASSERT(content == fContentHash.count());
SkASSERT(scratch + couldBeScratch == fScratchMap.count());
- bool overBudget = bytes > fMaxBytes || count > fMaxCount;
- SkASSERT(!overBudget || locked == count || fPurging);
+ // This assertion is not currently valid because we can be in recursive notifyIsPurgable()
+ // calls. This will be fixed when subresource registration is explicit.
+ // bool overBudget = bytes > fMaxBytes || count > fMaxCount;
+ // SkASSERT(!overBudget || locked == count || fPurging);
}
#endif
diff --git a/src/gpu/GrResourceCache2.h b/src/gpu/GrResourceCache2.h
index 8b4d1d0e67..805d359eb4 100644
--- a/src/gpu/GrResourceCache2.h
+++ b/src/gpu/GrResourceCache2.h
@@ -148,7 +148,7 @@ private:
////
void insertResource(GrGpuResource*);
void removeResource(GrGpuResource*);
- void notifyPurgable(const GrGpuResource*);
+ void notifyPurgable(GrGpuResource*);
void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize);
bool didSetContentKey(GrGpuResource*);
void makeResourceMRU(GrGpuResource*);
@@ -241,7 +241,7 @@ private:
/**
* Called by GrGpuResources when they detects that they are newly purgable.
*/
- void notifyPurgable(const GrGpuResource* resource) { fCache->notifyPurgable(resource); }
+ void notifyPurgable(GrGpuResource* resource) { fCache->notifyPurgable(resource); }
/**
* Called by GrGpuResources when their sizes change.
diff --git a/src/gpu/gl/GrGLIndexBuffer.h b/src/gpu/gl/GrGLIndexBuffer.h
index 5d5de43eee..a62bba1d51 100644
--- a/src/gpu/gl/GrGLIndexBuffer.h
+++ b/src/gpu/gl/GrGLIndexBuffer.h
@@ -20,7 +20,6 @@ public:
typedef GrGLBufferImpl::Desc Desc;
GrGLIndexBuffer(GrGpuGL* gpu, const Desc& desc);
- virtual ~GrGLIndexBuffer() { this->release(); }
GrGLuint bufferID() const { return fImpl.bufferID(); }
size_t baseOffset() const { return fImpl.baseOffset(); }
diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp
index 6097f469db..fc5688114d 100644
--- a/src/gpu/gl/GrGLPath.cpp
+++ b/src/gpu/gl/GrGLPath.cpp
@@ -143,10 +143,6 @@ GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke)
this->registerWithCache();
}
-GrGLPath::~GrGLPath() {
- this->release();
-}
-
void GrGLPath::onRelease() {
if (0 != fPathID && !this->isWrapped()) {
static_cast<GrGpuGL*>(this->getGpu())->glPathRendering()->deletePaths(fPathID, 1);
diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h
index b8bd8ad1a4..a7640d526a 100644
--- a/src/gpu/gl/GrGLPath.h
+++ b/src/gpu/gl/GrGLPath.h
@@ -28,7 +28,6 @@ public:
const SkStrokeRec&);
GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke);
- virtual ~GrGLPath();
GrGLuint pathID() const { return fPathID; }
protected:
diff --git a/src/gpu/gl/GrGLPathRange.cpp b/src/gpu/gl/GrGLPathRange.cpp
index 12c96c6a3f..5ff64f85af 100644
--- a/src/gpu/gl/GrGLPathRange.cpp
+++ b/src/gpu/gl/GrGLPathRange.cpp
@@ -29,10 +29,6 @@ GrGLPathRange::GrGLPathRange(GrGpuGL* gpu,
this->registerWithCache();
}
-GrGLPathRange::~GrGLPathRange() {
- this->release();
-}
-
void GrGLPathRange::onInitPath(int index, const SkPath& skPath) const {
GrGpuGL* gpu = static_cast<GrGpuGL*>(this->getGpu());
if (NULL == gpu) {
diff --git a/src/gpu/gl/GrGLPathRange.h b/src/gpu/gl/GrGLPathRange.h
index 440ffbc0c9..8fde666e7e 100644
--- a/src/gpu/gl/GrGLPathRange.h
+++ b/src/gpu/gl/GrGLPathRange.h
@@ -39,8 +39,6 @@ public:
size_t gpuMemorySize,
const SkStrokeRec&);
- virtual ~GrGLPathRange();
-
GrGLuint basePathID() const { return fBasePathID; }
protected:
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index b81bbed4b2..fd149b1185 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -30,8 +30,6 @@ public:
GrGLRenderTarget(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&);
- virtual ~GrGLRenderTarget() { this->release(); }
-
void setViewport(const GrGLIRect& rect) { fViewport = rect; }
const GrGLIRect& getViewport() const { return fViewport; }
diff --git a/src/gpu/gl/GrGLStencilBuffer.cpp b/src/gpu/gl/GrGLStencilBuffer.cpp
index fd14ea01f2..2ec06d438c 100644
--- a/src/gpu/gl/GrGLStencilBuffer.cpp
+++ b/src/gpu/gl/GrGLStencilBuffer.cpp
@@ -9,10 +9,6 @@
#include "GrGLStencilBuffer.h"
#include "GrGpuGL.h"
-GrGLStencilBuffer::~GrGLStencilBuffer() {
- this->release();
-}
-
size_t GrGLStencilBuffer::onGpuMemorySize() const {
uint64_t size = this->width();
size *= this->height();
diff --git a/src/gpu/gl/GrGLStencilBuffer.h b/src/gpu/gl/GrGLStencilBuffer.h
index 53777e40c7..ff0d5cb4d0 100644
--- a/src/gpu/gl/GrGLStencilBuffer.h
+++ b/src/gpu/gl/GrGLStencilBuffer.h
@@ -35,8 +35,6 @@ public:
this->registerWithCache();
}
- virtual ~GrGLStencilBuffer();
-
GrGLuint renderbufferID() const {
return fRenderbufferID;
}
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index f23adae0d2..268fe9239e 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -33,8 +33,6 @@ public:
GrGLTexture(GrGpuGL*, const GrSurfaceDesc&, const IDDesc&);
- virtual ~GrGLTexture() { this->release(); }
-
virtual GrBackendObject getTextureHandle() const SK_OVERRIDE;
virtual void textureParamsModified() SK_OVERRIDE { fTexParams.invalidate(); }
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h
index 06080a8a36..11577b8dcf 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.h
+++ b/src/gpu/gl/GrGLTextureRenderTarget.h
@@ -34,8 +34,6 @@ public:
this->registerWithCache();
}
- virtual ~GrGLTextureRenderTarget() { this->release(); }
-
protected:
virtual void onAbandon() SK_OVERRIDE {
GrGLRenderTarget::onAbandon();
diff --git a/src/gpu/gl/GrGLVertexBuffer.h b/src/gpu/gl/GrGLVertexBuffer.h
index db413ac990..40f4af9091 100644
--- a/src/gpu/gl/GrGLVertexBuffer.h
+++ b/src/gpu/gl/GrGLVertexBuffer.h
@@ -20,7 +20,6 @@ public:
typedef GrGLBufferImpl::Desc Desc;
GrGLVertexBuffer(GrGpuGL* gpu, const Desc& desc);
- virtual ~GrGLVertexBuffer() { this->release(); }
GrGLuint bufferID() const { return fImpl.bufferID(); }
size_t baseOffset() const { return fImpl.baseOffset(); }
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 877c21fc7e..89f26efe22 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1131,21 +1131,22 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
SkASSERT(height >= rt->height());
int samples = rt->numSamples();
- GrGLuint sbID;
- GL_CALL(GenRenderbuffers(1, &sbID));
- if (!sbID) {
- return false;
- }
+ GrGLuint sbID = 0;
int stencilFmtCnt = this->glCaps().stencilFormats().count();
for (int i = 0; i < stencilFmtCnt; ++i) {
+ if (!sbID) {
+ GL_CALL(GenRenderbuffers(1, &sbID));
+ }
+ if (!sbID) {
+ return false;
+ }
GL_CALL(BindRenderbuffer(GR_GL_RENDERBUFFER, sbID));
// we start with the last stencil format that succeeded in hopes
// that we won't go through this loop more than once after the
// first (painful) stencil creation.
int sIdx = (i + fLastSuccessfulStencilFmtIdx) % stencilFmtCnt;
- const GrGLCaps::StencilFormat& sFmt =
- this->glCaps().stencilFormats()[sIdx];
+ const GrGLCaps::StencilFormat& sFmt = this->glCaps().stencilFormats()[sIdx];
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
// we do this "if" so that we don't call the multisample
// version on a GL that doesn't have an MSAA extension.
@@ -1156,12 +1157,10 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
sFmt.fInternalFormat,
width, height);
} else {
- GL_ALLOC_CALL(this->glInterface(),
- RenderbufferStorage(GR_GL_RENDERBUFFER,
- sFmt.fInternalFormat,
- width, height));
- created =
- (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface()));
+ GL_ALLOC_CALL(this->glInterface(), RenderbufferStorage(GR_GL_RENDERBUFFER,
+ sFmt.fInternalFormat,
+ width, height));
+ created = (GR_GL_NO_ERROR == check_alloc_error(rt->desc(), this->glInterface()));
}
if (created) {
// After sized formats we attempt an unsized format and take
@@ -1172,13 +1171,15 @@ bool GrGpuGL::createStencilBufferForRenderTarget(GrRenderTarget* rt,
SkAutoTUnref<GrStencilBuffer> sb(SkNEW_ARGS(GrGLStencilBuffer,
(this, kIsWrapped, sbID, width, height,
samples, format)));
+ // If we fail we have to create a new render buffer ID since we gave this one to the
+ // GrGLStencilBuffer object.
+ sbID = 0;
if (this->attachStencilBufferToRenderTarget(sb, rt)) {
fLastSuccessfulStencilFmtIdx = sIdx;
sb->transferToCache();
rt->setStencilBuffer(sb);
return true;
- }
- sb->abandon(); // otherwise we lose sbID
+ }
}
}
GL_CALL(DeleteRenderbuffers(1, &sbID));
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 6f51d30766..c760f0e47d 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -86,7 +86,6 @@ public:
~TestResource() {
--fNumAlive;
SkSafeUnref(fToDelete);
- this->release();
}
void setSize(size_t size) {