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 @@
     };
     
     GrGLRenderTarget(const GLRenderTargetIDs& ids,
+                     GrGLTexID* texID,
                      GLuint stencilBits,
                      const GrGLIRect& fViewport,
                      GrGLTexture* texture,
@@ -59,7 +80,7 @@
 private:
     GrGpuGL*    fGL;
     GLuint      fRTFBOID;
-    GLuint      fTexFBOID;    
+    GLuint      fTexFBOID;
     GLuint      fStencilRenderbufferID;
     GLuint      fMSColorRenderbufferID;
    
@@ -75,7 +96,10 @@
     // 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 @@
     
     // 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 @@
 
     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 @@
 
 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 @@
      * 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 @@
     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 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 @@
     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