Fix crash in GrStencilBuffer when it tries to unlock itself but has lost its GrGpu ptr.
Review URL: http://codereview.appspot.com/4810088/
git-svn-id: http://skia.googlecode.com/svn/trunk@2084 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGLStencilBuffer.h b/gpu/src/GrGLStencilBuffer.h
index c2f6aea..caaca47 100644
--- a/gpu/src/GrGLStencilBuffer.h
+++ b/gpu/src/GrGLStencilBuffer.h
@@ -58,10 +58,12 @@
GR_GL(DeleteRenderbuffers(1, &fRenderbufferID));
fRenderbufferID = 0;
}
+ INHERITED::onRelease();
}
virtual void onAbandon() {
fRenderbufferID = 0;
+ INHERITED::onAbandon();
}
private:
diff --git a/gpu/src/GrStencilBuffer.cpp b/gpu/src/GrStencilBuffer.cpp
index d004612..4b08e23 100644
--- a/gpu/src/GrStencilBuffer.cpp
+++ b/gpu/src/GrStencilBuffer.cpp
@@ -13,8 +13,8 @@
void GrStencilBuffer::wasDetachedFromRenderTarget(const GrRenderTarget* rt) {
GrAssert(fRTAttachmentCnt > 0);
- if (0 == --fRTAttachmentCnt && NULL != fCacheEntry) {
- this->getGpu()->getContext()->unlockStencilBuffer(fCacheEntry);
+ if (0 == --fRTAttachmentCnt) {
+ this->unlockInCache();
// At this point we could be deleted!
}
}
@@ -24,3 +24,32 @@
fCacheEntry =
this->getGpu()->getContext()->addAndLockStencilBuffer(this);
}
+
+void GrStencilBuffer::onRelease() {
+ // When the GrGpu rips through its list of resources and releases
+ // them it may release an SB before it releases its attached RTs.
+ // In that case when GrStencilBuffer sees its last detach it no
+ // long has a gpu ptr (gets nulled in GrResource::release()) and can't
+ // access the cache to unlock itself. So if we're being released and still
+ // have attachments go ahead and unlock now.
+ if (fRTAttachmentCnt) {
+ this->unlockInCache();
+ // we shouldn't be deleted here because some RT still has a ref on us.
+ }
+ fCacheEntry = NULL;
+}
+
+void GrStencilBuffer::onAbandon() {
+ // we can use the same behavior as release.
+ this->onRelease();
+}
+
+void GrStencilBuffer::unlockInCache() {
+ if (NULL != fCacheEntry) {
+ GrGpu* gpu = this->getGpu();
+ if (NULL != gpu) {
+ GrAssert(NULL != gpu->getContext());
+ gpu->getContext()->unlockStencilBuffer(fCacheEntry);
+ }
+ }
+}
diff --git a/gpu/src/GrStencilBuffer.h b/gpu/src/GrStencilBuffer.h
index b24ebba..5249ce8 100644
--- a/gpu/src/GrStencilBuffer.h
+++ b/gpu/src/GrStencilBuffer.h
@@ -77,7 +77,17 @@
, fRTAttachmentCnt(0) {
}
+ // GrResource overrides
+
+ // subclass override must call INHERITED::onRelease
+ virtual void onRelease();
+ // subclass override must call INHERITED::onAbandon
+ virtual void onAbandon();
+
private:
+
+ void unlockInCache();
+
int fWidth;
int fHeight;
int fBits;