Add GrResource base class for ibs, texs, vbs, etc.
Add lostContext() to GrContext.

Review URL: http://codereview.appspot.com/4328044/



git-svn-id: http://skia.googlecode.com/svn/trunk@1026 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
index ab99d9a..a37df9c 100644
--- a/gpu/src/GrAtlas.cpp
+++ b/gpu/src/GrAtlas.cpp
@@ -203,16 +203,4 @@
     fPlotMgr->freePlot(x, y);
 }
 
-void GrAtlasMgr::abandonAll() {
-#if 0
-    GrAtlas** curr = fList.begin();
-    GrAtlas** stop = fList.end();
-    for (; curr < stop; curr++) {
-        (*curr)->texture()->abandon();
-        delete *curr;
-    }
-    fList.reset();
-#endif
-}
-
 
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index f6009f5..d093d7c 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -57,6 +57,7 @@
 }
 
 GrContext::~GrContext() {
+    this->flush();
     fGpu->unref();
     delete fTextureCache;
     delete fFontCache;
@@ -66,9 +67,31 @@
     GrSafeUnref(fCustomPathRenderer);
 }
 
-void GrContext::abandonAllTextures() {
-    fTextureCache->deleteAll(GrTextureCache::kAbandonTexture_DeleteMode);
-    fFontCache->abandonAll();
+void GrContext::contextLost() {
+    delete fDrawBuffer;
+    fDrawBuffer = NULL;
+    delete fDrawBufferVBAllocPool;
+    fDrawBufferVBAllocPool = NULL;
+    delete fDrawBufferIBAllocPool;
+    fDrawBufferIBAllocPool = NULL;
+
+    fTextureCache->removeAll();
+    fFontCache->freeAll();
+    fGpu->markContextDirty();
+
+    fGpu->abandonResources();
+
+    this->setupDrawBuffer();
+}
+
+void GrContext::resetContext() {
+    fGpu->markContextDirty();
+}
+
+void GrContext::freeGpuResources() {
+    this->flush();
+    fTextureCache->removeAll();
+    fFontCache->freeAll();
 }
 
 GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key,
@@ -688,12 +711,8 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrContext::resetContext() {
-    fGpu->markContextDirty();
-}
-
 void GrContext::setRenderTarget(GrRenderTarget* target) {
-    flush(false);
+    this->flush(false);
     fGpu->setRenderTarget(target);
 }
 
@@ -745,7 +764,7 @@
 
     fGpu = gpu;
     fGpu->ref();
-    
+
     fCustomPathRenderer = GrPathRenderer::CreatePathRenderer();
     fGpu->setClipPathRenderer(fCustomPathRenderer);
 
@@ -755,22 +774,31 @@
 
     fLastDrawCategory = kUnbuffered_DrawCategory;
 
+    fDrawBuffer = NULL;
+    fDrawBufferVBAllocPool = NULL;
+    fDrawBufferIBAllocPool = NULL;
+
+    this->setupDrawBuffer();
+}
+
+void GrContext::setupDrawBuffer() {
+
+    GrAssert(NULL == fDrawBuffer);
+    GrAssert(NULL == fDrawBufferVBAllocPool);
+    GrAssert(NULL == fDrawBufferIBAllocPool);
+
 #if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
     fDrawBufferVBAllocPool =
-        new GrVertexBufferAllocPool(gpu, false,
+        new GrVertexBufferAllocPool(fGpu, false,
                                     DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
                                     DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
     fDrawBufferIBAllocPool =
-        new GrIndexBufferAllocPool(gpu, false,
+        new GrIndexBufferAllocPool(fGpu, false,
                                    DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
                                    DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
 
     fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
                                           fDrawBufferIBAllocPool);
-#else
-    fDrawBuffer = NULL;
-    fDrawBufferVBAllocPool = NULL;
-    fDrawBufferIBAllocPool = NULL;
 #endif
 
 #if BATCH_RECT_TO_RECT
@@ -818,7 +846,7 @@
 GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
                                            GrPathIter* path,
                                            GrPathFill fill) {
-    if (NULL != fCustomPathRenderer && 
+    if (NULL != fCustomPathRenderer &&
         fCustomPathRenderer->canDrawPath(target, path, fill)) {
         return fCustomPathRenderer;
     } else {
diff --git a/gpu/src/GrGLIndexBuffer.cpp b/gpu/src/GrGLIndexBuffer.cpp
index 9d73419..4fb1e99 100644
--- a/gpu/src/GrGLIndexBuffer.cpp
+++ b/gpu/src/GrGLIndexBuffer.cpp
@@ -18,42 +18,46 @@
 #include "GrGLIndexBuffer.h"
 #include "GrGpuGL.h"
 
-GrGLIndexBuffer::GrGLIndexBuffer(GrGLuint id, GrGpuGL* gl, size_t sizeInBytes,
-                                   bool dynamic) :
-                                INHERITED(sizeInBytes, dynamic),
-                                fGL(gl),
-                                fBufferID(id),
-                                fLockPtr(NULL) {
+#define GPUGL static_cast<GrGpuGL*>(getGpu())
+
+GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu,
+                                 GrGLuint id,
+                                 size_t sizeInBytes,
+                                 bool dynamic)
+    : INHERITED(gpu, sizeInBytes, dynamic)
+    , fBufferID(id)
+    , fLockPtr(NULL) {
+
 }
 
-GrGLIndexBuffer::~GrGLIndexBuffer() {
+void GrGLIndexBuffer::onRelease() {
     // make sure we've not been abandoned
     if (fBufferID) {
-        fGL->notifyIndexBufferDelete(this);
+        GPUGL->notifyIndexBufferDelete(this);
         GR_GL(DeleteBuffers(1, &fBufferID));
+        fBufferID = 0;
     }
 }
 
+void GrGLIndexBuffer::onAbandon() {
+    fBufferID = 0;
+    fLockPtr = NULL;
+}
+
 void GrGLIndexBuffer::bind() const {
     GR_GL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, fBufferID));
-    fGL->notifyIndexBufferBind(this);
+    GPUGL->notifyIndexBufferBind(this);
 }
 
 GrGLuint GrGLIndexBuffer::bufferID() const {
     return fBufferID;
 }
 
-void GrGLIndexBuffer::abandon() {
-    fBufferID = 0;
-    fGL = NULL;
-    fLockPtr = NULL;
-}
-
 void* GrGLIndexBuffer::lock() {
     GrAssert(fBufferID);
     GrAssert(!isLocked());
-    if (fGL->supportsBufferLocking()) {
-        bind();
+    if (GPUGL->supportsBufferLocking()) {
+        this->bind();
         // Let driver know it can discard the old data
         GR_GL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, size(), NULL,
                          dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
@@ -71,18 +75,17 @@
 void GrGLIndexBuffer::unlock() {
     GrAssert(fBufferID);
     GrAssert(isLocked());
-    GrAssert(fGL->supportsBufferLocking());
+    GrAssert(GPUGL->supportsBufferLocking());
 
-    bind();
+    this->bind();
     GR_GL(UnmapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER));
     fLockPtr = NULL;
 }
 
 bool GrGLIndexBuffer::isLocked() const {
-    GrAssert(fBufferID);
 #if GR_DEBUG
-    if (fGL->supportsBufferLocking()) {
-        bind();
+    if (this->isValid() && GPUGL->supportsBufferLocking()) {
+        this->bind();
         GrGLint mapped;
         GR_GL(GetBufferParameteriv(GR_GL_ELEMENT_ARRAY_BUFFER,
                                    GR_GL_BUFFER_MAPPED, &mapped));
@@ -98,7 +101,7 @@
     if (srcSizeInBytes > size()) {
         return false;
     }
-    bind();
+    this->bind();
     GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
     if (size() == srcSizeInBytes) {
         GR_GL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, srcSizeInBytes, src, usage));
@@ -117,7 +120,7 @@
     if (srcSizeInBytes + offset > size()) {
         return false;
     }
-    bind();
+    this->bind();
     GR_GL(BufferSubData(GR_GL_ELEMENT_ARRAY_BUFFER, offset, srcSizeInBytes, src));
     return true;
 }
diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp
index ae36e4c..bd157d2 100644
--- a/gpu/src/GrGLTexture.cpp
+++ b/gpu/src/GrGLTexture.cpp
@@ -18,16 +18,15 @@
 #include "GrGLTexture.h"
 #include "GrGpuGL.h"
 
-GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids,
+#define GPUGL static_cast<GrGpuGL*>(getGpu())
+
+GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
+                                   const GLRenderTargetIDs& ids,
                                    GrGLTexID* texID,
                                    GrGLuint stencilBits,
                                    const GrGLIRect& viewport,
-                                   GrGLTexture* texture,
-                                   GrGpuGL* gl) : INHERITED(texture,
-                                                            viewport.fWidth,
-                                                            viewport.fHeight,
-                                                            stencilBits) {
-    fGL                     = gl;
+                                   GrGLTexture* texture)
+    : INHERITED(gpu, texture, viewport.fWidth, viewport.fHeight, stencilBits) {
     fRTFBOID                = ids.fRTFBOID;
     fTexFBOID               = ids.fTexFBOID;
     fStencilRenderbufferID  = ids.fStencilRenderbufferID;
@@ -39,10 +38,10 @@
     GrSafeRef(fTexIDObj);
 }
 
-GrGLRenderTarget::~GrGLRenderTarget() {
-    fGL->notifyRenderTargetDelete(this);
+void GrGLRenderTarget::onRelease() {
     if (fOwnIDs) {
         if (fTexFBOID) {
+            GPUGL->notifyRenderTargetDelete(this);
             GR_GL(DeleteFramebuffers(1, &fTexFBOID));
         }
         if (fRTFBOID && fRTFBOID != fTexFBOID) {
@@ -55,16 +54,22 @@
             GR_GL(DeleteRenderbuffers(1, &fMSColorRenderbufferID));
         }
     }
+    fRTFBOID                = 0;
+    fTexFBOID               = 0;
+    fStencilRenderbufferID  = 0;
+    fMSColorRenderbufferID  = 0;
     GrSafeUnref(fTexIDObj);
+    fTexIDObj = NULL;
 }
 
-void GrGLRenderTarget::abandon() {
+void GrGLRenderTarget::onAbandon() {
     fRTFBOID                = 0;
     fTexFBOID               = 0;
     fStencilRenderbufferID  = 0;
     fMSColorRenderbufferID  = 0;
     if (NULL != fTexIDObj) {
         fTexIDObj->abandon();
+        fTexIDObj = NULL;
     }
 }
 
@@ -92,13 +97,14 @@
 };
 
 
-GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
+GrGLTexture::GrGLTexture(GrGpuGL* gpu,
+                         const GLTextureDesc& textureDesc,
                          const GLRenderTargetIDs& rtIDs,
-                         const TexParams& initialTexParams,
-                         GrGpuGL* gl)
-        : INHERITED(textureDesc.fContentWidth, 
-                    textureDesc.fContentHeight, 
-                    textureDesc.fFormat) {
+                         const TexParams& initialTexParams)
+    : INHERITED(gpu,
+                textureDesc.fContentWidth,
+                textureDesc.fContentHeight,
+                textureDesc.fFormat) {
 
     fTexParams          = initialTexParams;
     fTexIDObj           = new GrGLTexID(textureDesc.fTextureID);
@@ -113,7 +119,6 @@
     fScaleY             = GrIntToScalar(textureDesc.fContentHeight) /
                             textureDesc.fAllocHeight;
     fRenderTarget       = NULL;
-    fGpuGL              = gl;
 
     GrAssert(0 != textureDesc.fTextureID);
 
@@ -125,27 +130,32 @@
         vp.fHeight = textureDesc.fContentHeight;
         vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
 
-        fRenderTarget = new GrGLRenderTarget(rtIDs, fTexIDObj,
+        fRenderTarget = new GrGLRenderTarget(gpu, rtIDs, fTexIDObj,
                                              textureDesc.fStencilBits,
-                                             vp, this, gl);
+                                             vp, this);
     }
 }
 
-GrGLTexture::~GrGLTexture() {
-    fGpuGL->notifyTextureDelete(this);
-    fTexIDObj->unref();
-    GrSafeUnref(fRenderTarget);
+void GrGLTexture::onRelease() {
+    if (NULL != fTexIDObj) {
+        GPUGL->notifyTextureDelete(this);
+        fTexIDObj->unref();
+        fTexIDObj = NULL;
+        GrSafeUnref(fRenderTarget);
+    }
 }
 
-void GrGLTexture::abandon() {
-    fTexIDObj->abandon();
+void GrGLTexture::onAbandon() {
+    if (NULL != fTexIDObj) {
+        fTexIDObj->abandon();
+    }
     if (NULL != fRenderTarget) {
         fRenderTarget->abandon();
     }
 }
 
 GrRenderTarget* GrGLTexture::asRenderTarget() {
-    return (GrRenderTarget*)fRenderTarget;
+    return fRenderTarget;
 }
 
 void GrGLTexture::releaseRenderTarget() {
@@ -158,8 +168,8 @@
                                     uint32_t width,
                                     uint32_t height,
                                     const void* srcData) {
-    
-    fGpuGL->setSpareTextureUnit();
+
+    GPUGL->setSpareTextureUnit();
 
     // glCompressedTexSubImage2D doesn't support any formats
     // (at least without extensions)
@@ -170,7 +180,7 @@
     GrAssert(kTopDown_Orientation == fOrientation);
     GR_GL(BindTexture(GR_GL_TEXTURE_2D, fTexIDObj->id()));
     GR_GL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, fUploadByteCount));
-    GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height, 
+    GR_GL(TexSubImage2D(GR_GL_TEXTURE_2D, 0, x, y, width, height,
                         fUploadFormat, fUploadType, srcData));
 
 }
diff --git a/gpu/src/GrGLVertexBuffer.cpp b/gpu/src/GrGLVertexBuffer.cpp
index f96f90e..3fa1425 100644
--- a/gpu/src/GrGLVertexBuffer.cpp
+++ b/gpu/src/GrGLVertexBuffer.cpp
@@ -18,42 +18,45 @@
 #include "GrGLVertexBuffer.h"
 #include "GrGpuGL.h"
 
-GrGLVertexBuffer::GrGLVertexBuffer(GrGLuint id, GrGpuGL* gl, size_t sizeInBytes,
-                                   bool dynamic) :
-                                   INHERITED(sizeInBytes, dynamic),
-                                   fGL(gl),
-                                   fBufferID(id),
-                                   fLockPtr(NULL) {
+#define GPUGL static_cast<GrGpuGL*>(getGpu())
+
+GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu,
+                                   GrGLuint id,
+                                   size_t sizeInBytes,
+                                   bool dynamic)
+    : INHERITED(gpu, sizeInBytes, dynamic)
+    , fBufferID(id)
+    , fLockPtr(NULL) {
 }
 
-GrGLVertexBuffer::~GrGLVertexBuffer() {
+void GrGLVertexBuffer::onRelease() {
     // make sure we've not been abandoned
     if (fBufferID) {
-        fGL->notifyVertexBufferDelete(this);
+        GPUGL->notifyVertexBufferDelete(this);
         GR_GL(DeleteBuffers(1, &fBufferID));
+        fBufferID = 0;
     }
 }
 
+void GrGLVertexBuffer::onAbandon() {
+    fBufferID = 0;
+    fLockPtr = NULL;
+}
+
 void GrGLVertexBuffer::bind() const {
     GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, fBufferID));
-    fGL->notifyVertexBufferBind(this);
+    GPUGL->notifyVertexBufferBind(this);
 }
 
 GrGLuint GrGLVertexBuffer::bufferID() const {
     return fBufferID;
 }
 
-void GrGLVertexBuffer::abandon() {
-    fBufferID = 0;
-    fGL = NULL;
-    fLockPtr = NULL;
-}
-
 void* GrGLVertexBuffer::lock() {
     GrAssert(fBufferID);
     GrAssert(!isLocked());
-    if (fGL->supportsBufferLocking()) {
-        bind();
+    if (GPUGL->supportsBufferLocking()) {
+        this->bind();
         // Let driver know it can discard the old data
         GR_GL(BufferData(GR_GL_ARRAY_BUFFER, size(), NULL,
                          dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
@@ -68,21 +71,22 @@
 }
 
 void GrGLVertexBuffer::unlock() {
+
     GrAssert(fBufferID);
     GrAssert(isLocked());
-    GrAssert(fGL->supportsBufferLocking());
+    GrAssert(GPUGL->supportsBufferLocking());
 
-    bind();
+    this->bind();
     GR_GL(UnmapBuffer(GR_GL_ARRAY_BUFFER));
     fLockPtr = NULL;
 }
 
 bool GrGLVertexBuffer::isLocked() const {
-    GrAssert(fBufferID);
+    GrAssert(!this->isValid() || fBufferID);
 #if GR_DEBUG
-    if (fGL->supportsBufferLocking()) {
+    if (this->isValid() && GPUGL->supportsBufferLocking()) {
         GrGLint mapped;
-        bind();
+        this->bind();
         GR_GL(GetBufferParameteriv(GR_GL_ARRAY_BUFFER, GR_GL_BUFFER_MAPPED, &mapped));
         GrAssert(!!mapped == !!fLockPtr);
     }
@@ -96,7 +100,7 @@
     if (srcSizeInBytes > size()) {
         return false;
     }
-    bind();
+    this->bind();
     GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
     if (size() == srcSizeInBytes) {
         GR_GL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
@@ -115,7 +119,7 @@
     if (srcSizeInBytes + offset > size()) {
         return false;
     }
-    bind();
+    this->bind();
     GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
     return true;
 }
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 378b881..31e4d99 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -69,20 +69,22 @@
 
 extern void gr_run_unittests();
 
-GrGpu::GrGpu() : f8bitPaletteSupport(false),
-                 fCurrPoolVertexBuffer(NULL),
-                 fCurrPoolStartVertex(0),
-                 fCurrPoolIndexBuffer(NULL),
-                 fCurrPoolStartIndex(0),
-                 fVertexPool(NULL),
-                 fIndexPool(NULL),
-                 fQuadIndexBuffer(NULL),
-                 fUnitSquareVertexBuffer(NULL),
-                 fDefaultPathRenderer(NULL),
-                 fClientPathRenderer(NULL),
-                 fContextIsDirty(true),
-                 fVertexPoolInUse(false),
-                 fIndexPoolInUse(false) {
+GrGpu::GrGpu()
+    : f8bitPaletteSupport(false)
+    , fCurrPoolVertexBuffer(NULL)
+    , fCurrPoolStartVertex(0)
+    , fCurrPoolIndexBuffer(NULL)
+    , fCurrPoolStartIndex(0)
+    , fVertexPool(NULL)
+    , fIndexPool(NULL)
+    , fQuadIndexBuffer(NULL)
+    , fUnitSquareVertexBuffer(NULL)
+    , fDefaultPathRenderer(NULL)
+    , fClientPathRenderer(NULL)
+    , fContextIsDirty(true)
+    , fVertexPoolInUse(false)
+    , fIndexPoolInUse(false)
+    , fResourceHead(NULL) {
 #if GR_DEBUG
     //gr_run_unittests();
 #endif
@@ -90,17 +92,76 @@
 }
 
 GrGpu::~GrGpu() {
-    GrSafeUnref(fQuadIndexBuffer);
-    GrSafeUnref(fUnitSquareVertexBuffer);
-    delete fVertexPool;
-    delete fIndexPool;
-    GrSafeUnref(fClientPathRenderer);
-    GrSafeUnref(fDefaultPathRenderer);
+    releaseResources();
 }
 
-void GrGpu::resetContext() {
+void GrGpu::abandonResources() {
+
+    while (NULL != fResourceHead) {
+        fResourceHead->abandon();
+    }
+
+    GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid());
+    GrAssert(NULL == fUnitSquareVertexBuffer ||
+             !fUnitSquareVertexBuffer->isValid());
+    GrSafeSetNull(fQuadIndexBuffer);
+    GrSafeSetNull(fUnitSquareVertexBuffer);
+    delete fVertexPool;
+    fVertexPool = NULL;
+    delete fIndexPool;
+    fIndexPool = NULL;
 }
 
+void GrGpu::releaseResources() {
+
+    while (NULL != fResourceHead) {
+        fResourceHead->release();
+    }
+
+    GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid());
+    GrAssert(NULL == fUnitSquareVertexBuffer ||
+             !fUnitSquareVertexBuffer->isValid());
+    GrSafeSetNull(fQuadIndexBuffer);
+    GrSafeSetNull(fUnitSquareVertexBuffer);
+    delete fVertexPool;
+    fVertexPool = NULL;
+    delete fIndexPool;
+    fIndexPool = NULL;
+}
+
+void GrGpu::insertResource(GrResource* resource) {
+    GrAssert(NULL != resource);
+    GrAssert(this == resource->getGpu());
+    GrAssert(NULL == resource->fNext);
+    GrAssert(NULL == resource->fPrevious);
+
+    resource->fNext = fResourceHead;
+    if (NULL != fResourceHead) {
+        GrAssert(NULL == fResourceHead->fPrevious);
+        fResourceHead->fPrevious = resource;
+    }
+    fResourceHead = resource;
+}
+
+void GrGpu::removeResource(GrResource* resource) {
+    GrAssert(NULL != resource);
+    GrAssert(NULL != fResourceHead);
+
+    if (fResourceHead == resource) {
+        GrAssert(NULL == resource->fPrevious);
+        fResourceHead = resource->fNext;
+    } else {
+        GrAssert(NULL != fResourceHead);
+        resource->fPrevious->fNext = resource->fNext;
+    }
+    if (NULL != resource->fNext) {
+        resource->fNext->fPrevious = resource->fPrevious;
+    }
+    resource->fNext = NULL;
+    resource->fPrevious = NULL;
+}
+
+
 void GrGpu::unimpl(const char msg[]) {
 #if GR_DEBUG
     GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg);
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 6833a31..bb71255 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -232,7 +232,7 @@
     fMSFBOType = kNone_MSFBO;
     if (GR_GL_SUPPORT_ES) {
        if (has_gl_extension("GL_CHROMIUM_framebuffer_multisample")) {
-           // chrome's extension is equivalent to the EXT msaa 
+           // chrome's extension is equivalent to the EXT msaa
            // and fbo_blit extensions.
             fMSFBOType = kDesktopEXT_MSFBO;
        } else if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
@@ -552,7 +552,7 @@
     rtIDs.fRTFBOID  = (GrGLuint)platformRenderTarget;
     rtIDs.fTexFBOID = (GrGLuint)platformRenderTarget;
 
-    return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
+    return new GrGLRenderTarget(this, rtIDs, NULL, stencilBits, viewport, NULL);
 }
 
 GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() {
@@ -571,7 +571,7 @@
 
     rtIDs.fOwnIDs = false;
 
-    return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
+    return new GrGLRenderTarget(this, rtIDs, NULL, stencilBits, viewport, NULL);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -833,7 +833,7 @@
         GR_GL(GenFramebuffers(1, &rtIDs.fTexFBOID));
         GrAssert(rtIDs.fTexFBOID);
 
-        // If we are using multisampling and we will create two FBOS We render 
+        // If we are using multisampling and we will create two FBOS We render
         // to one and then resolve to the texture bound to the other.
         if (samples > 1 && kNone_MSFBO != fMSFBOType) {
             GR_GL(GenFramebuffers(1, &rtIDs.fRTFBOID));
@@ -997,7 +997,7 @@
     GrPrintf("--- new texture [%d] size=(%d %d) bpp=%d\n",
              tex->fTextureID, width, height, tex->fUploadByteCount);
 #endif
-    GrGLTexture* tex = new GrGLTexture(glDesc, rtIDs, DEFAULT_PARAMS, this);
+    GrGLTexture* tex = new GrGLTexture(this, glDesc, rtIDs, DEFAULT_PARAMS);
 
     if (0 != rtIDs.fTexFBOID) {
         GrRenderTarget* rt = tex->asRenderTarget();
@@ -1032,7 +1032,7 @@
             fHWGeometryState.fVertexBuffer = NULL;
             return NULL;
         }
-        GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(id, this,
+        GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, id,
                                                               size, dynamic);
         fHWGeometryState.fVertexBuffer = vertexBuffer;
         return vertexBuffer;
@@ -1055,7 +1055,7 @@
             fHWGeometryState.fIndexBuffer = NULL;
             return NULL;
         }
-        GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(id, this,
+        GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, id,
                                                          size, dynamic);
         fHWGeometryState.fIndexBuffer = indexBuffer;
         return indexBuffer;
diff --git a/gpu/src/GrResource.cpp b/gpu/src/GrResource.cpp
new file mode 100644
index 0000000..70e87d5
--- /dev/null
+++ b/gpu/src/GrResource.cpp
@@ -0,0 +1,41 @@
+/*
+    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.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrResource.h"
+#include "GrGpu.h"
+
+GrResource::GrResource(GrGpu* gpu) {
+    fGpu        = gpu;
+    fNext       = NULL;
+    fPrevious   = NULL;
+    fGpu->insertResource(this);
+}
+
+void GrResource::release() {
+    if (NULL != fGpu) {
+        this->onRelease();
+        fGpu->removeResource(this);
+        fGpu = NULL;
+    }
+}
+
+void GrResource::abandon() {
+    if (NULL != fGpu) {
+        this->onAbandon();
+        fGpu->removeResource(this);
+        fGpu = NULL;
+    }
+}
diff --git a/gpu/src/GrTextStrike.cpp b/gpu/src/GrTextStrike.cpp
index 6cdb61c..a245997 100644
--- a/gpu/src/GrTextStrike.cpp
+++ b/gpu/src/GrTextStrike.cpp
@@ -58,19 +58,12 @@
     return strike;
 }
 
-void GrFontCache::abandonAll() {
-    fCache.deleteAll();
-    if (fAtlasMgr) {
-        fAtlasMgr->abandonAll();
-        delete fAtlasMgr;
-        fAtlasMgr = NULL;
-    }
-}
-
 void GrFontCache::freeAll() {
     fCache.deleteAll();
     delete fAtlasMgr;
     fAtlasMgr = NULL;
+    fHead = NULL;
+    fTail = NULL;
 }
 
 void GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) {
diff --git a/gpu/src/GrTextureCache.cpp b/gpu/src/GrTextureCache.cpp
index fe3ff68..c3a61ac 100644
--- a/gpu/src/GrTextureCache.cpp
+++ b/gpu/src/GrTextureCache.cpp
@@ -55,7 +55,7 @@
 GrTextureCache::~GrTextureCache() {
     GrAutoTextureCacheValidate atcv(this);
 
-    this->deleteAll(kFreeTexture_DeleteMode);
+    this->removeAll();
 }
 
 void GrTextureCache::getLimits(int* maxTextures, size_t* maxTextureBytes) const{
@@ -237,7 +237,7 @@
     }
 }
 
-void GrTextureCache::deleteAll(DeleteMode mode) {
+void GrTextureCache::removeAll() {
     GrAssert(!fClientDetachedCount);
     GrAssert(!fClientDetachedBytes);
 
@@ -246,9 +246,6 @@
         GrAssert(!entry->isLocked());
 
         GrTextureEntry* next = entry->fNext;
-        if (kAbandonTexture_DeleteMode == mode) {
-            entry->texture()->abandon();
-        }
         delete entry;
         entry = next;
     }