Reland of 8525 with fix for case when GrRT outlives GrTexture.
Review URL: https://codereview.chromium.org/13814015

git-svn-id: http://skia.googlecode.com/svn/trunk@8573 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index fcb4c3d..2755bec 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -148,22 +148,18 @@
         fResolveRect.setLargestInverted();
     }
 
-    friend class GrTexture;
-    // When a texture unrefs an owned render target this func
-    // removes the back pointer. This could be called from
-    // texture's destructor but would have to be done in derived
-    // classes. By the time of texture base destructor it has already
-    // lost its pointer to the rt.
-    void onTextureReleaseRenderTarget() {
-        GrAssert(NULL != fTexture);
-        fTexture = NULL;
-    }
-
     // override of GrResource
     virtual void onAbandon() SK_OVERRIDE;
     virtual void onRelease() SK_OVERRIDE;
 
 private:
+    friend class GrTexture;
+    // called by ~GrTexture to remove the non-ref'ed back ptr.
+    void owningTextureDestroyed() {
+        GrAssert(NULL != fTexture);
+        fTexture = NULL;
+    }
+
     GrStencilBuffer*  fStencilBuffer;
     GrTexture*        fTexture; // not ref'ed
 
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index 02fc0d5..52a5665 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -64,6 +64,22 @@
     virtual const GrRenderTarget* asRenderTarget() const = 0;
 
     /**
+     * Checks whether this GrSurface refers to the same GPU object as other. This
+     * catches the case where a GrTexture and GrRenderTarget refer to the same
+     * GPU memory.
+     */
+    bool isSameAs(const GrSurface* other) const {
+        const GrRenderTarget* thisRT = this->asRenderTarget();
+        if (NULL != thisRT) {
+            return thisRT == other->asRenderTarget();
+        } else {
+            const GrTexture* thisTex = this->asTexture();
+            GrAssert(NULL != thisTex); // We must be one or the other
+            return thisTex == other->asTexture();
+        }
+    }
+
+    /**
      * Reads a rectangle of pixels from the surface.
      * @param left          left edge of the rectangle to read (inclusive)
      * @param top           top edge of the rectangle to read (inclusive)
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index 5d8ecaa..422814b 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -11,8 +11,8 @@
 
 #include "GrSurface.h"
 #include "SkPoint.h"
+#include "GrRenderTarget.h"
 
-class GrRenderTarget;
 class GrResourceKey;
 class GrTextureParams;
 
@@ -80,10 +80,10 @@
      *            render target
      */
     virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE {
-        return fRenderTarget;
+        return fRenderTarget.get();
     }
     virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE {
-        return fRenderTarget;
+        return fRenderTarget.get();
     }
 
     // GrTexture
@@ -101,13 +101,6 @@
     }
 
     /**
-     * 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.
-     */
-    void releaseRenderTarget();
-
-    /**
      *  Return the native ID or handle to the texture, depending on the
      *  platform. e.g. on OpenGL, return the texture ID.
      */
@@ -137,9 +130,9 @@
     static bool NeedsFiltering(const GrResourceKey& key);
 
 protected:
-    GrRenderTarget* fRenderTarget; // texture refs its rt representation
-                                   // base class cons sets to NULL
-                                   // subclass cons can create and set
+    // A texture refs its rt representation but not vice-versa. It is up to
+    // the subclass constructor to initialize this pointer.
+    SkAutoTUnref<GrRenderTarget> fRenderTarget;
 
     GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
     : INHERITED(gpu, isWrapped, desc)
@@ -149,6 +142,7 @@
         fShiftFixedX = 31 - SkCLZ(fDesc.fWidth);
         fShiftFixedY = 31 - SkCLZ(fDesc.fHeight);
     }
+    virtual ~GrTexture();
 
     // GrResource overrides
     virtual void onRelease() SK_OVERRIDE;