Fix dangling ptr when GrRenderTarget outlives its GrTexture representation
Move management of fRenderTarget ptr from GL texture class to base class

Minor:
Remove redundant GrContext-per-frame debug code in SampleApp.cpp
Add GrTexture.cpp to legacy VS2010 vcxproj

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



git-svn-id: http://skia.googlecode.com/svn/trunk@1061 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h
index 2cd833c..7924cc3 100644
--- a/gpu/include/GrGLTexture.h
+++ b/gpu/include/GrGLTexture.h
@@ -125,9 +125,7 @@
 
     virtual ~GrGLTexture() { this->release(); }
 
-    // overloads of GrTexture
-    virtual GrRenderTarget* asRenderTarget();
-    virtual void releaseRenderTarget();
+    // overrides of GrTexture
     virtual void uploadTextureData(uint32_t x,
                                    uint32_t y,
                                    uint32_t width,
@@ -198,7 +196,7 @@
                 const GLRenderTargetIDs& rtIDs,
                 const TexParams& initialTexParams);
 
-    // overloads of GrResource
+    // overrides of GrTexture
     virtual void onAbandon();
     virtual void onRelease();
 
@@ -214,7 +212,6 @@
     GrScalar            fScaleX;
     GrScalar            fScaleY;
     Orientation         fOrientation;
-    GrGLRenderTarget*   fRenderTarget;
     GrGpuGL*            fGpuGL;
 
     static const GrGLenum* WrapMode2GLWrap();
diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h
index 2aa80ab..8f9952a 100644
--- a/gpu/include/GrTexture.h
+++ b/gpu/include/GrTexture.h
@@ -32,6 +32,7 @@
  * that wrap externally created render targets.
  */
 class GrRenderTarget : public GrResource {
+
 public:
     /**
      * @return the width of the rendertarget
@@ -80,8 +81,18 @@
         , fStencilBits(stencilBits)
     {}
 
+    friend class GrTexture;
+    // When a texture unrefs an owned rendertarget this func
+    // removes the back pointer. This could be done called from 
+    // texture's destructor but would have to be done in derived
+    // class. By the time of texture base destructor it has already
+    // lost its pointer to the rt.
+    void onTextureReleaseRenderTarget() {
+        GrAssert(NULL != fTexture);
+        fTexture = NULL;
+    }
 
-    GrTexture* fTexture;
+    GrTexture* fTexture; // not ref'ed
     int        fWidth;
     int        fHeight;
     int        fStencilBits;
@@ -96,23 +107,8 @@
 };
 
 class GrTexture : public GrResource {
-protected:
-    GrTexture(GrGpu* gpu,
-              int width,
-              int height,
-              GrPixelConfig config)
-    : INHERITED(gpu)
-    , fWidth(width)
-    , fHeight(height)
-    , fConfig(config) {
-        // only make sense if alloc size is pow2
-        fShiftFixedX = 31 - Gr_clz(fWidth);
-        fShiftFixedY = 31 - Gr_clz(fHeight);
-    }
 
 public:
-    virtual ~GrTexture();
-
     /**
      * Retrieves the width of the texture.
      *
@@ -183,17 +179,24 @@
      * Retrieves the render target underlying this texture that can be passed to
      * GrGpu::setRenderTarget().
      *
-     * @return    handle to render target or undefined if the texture is not a
+     * @return    handle to render target or NULL if the texture is not a
      *            render target
      */
-    virtual GrRenderTarget* asRenderTarget() = 0;
+    GrRenderTarget* asRenderTarget() { return fRenderTarget; }
 
     /**
      * 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 releaseRenderTarget() = 0;
+    void releaseRenderTarget() {
+        if (NULL != fRenderTarget) {
+            GrAssert(fRenderTarget->asTexture() == this);
+            fRenderTarget->onTextureReleaseRenderTarget();
+            fRenderTarget->unref();
+            fRenderTarget = NULL;
+        }
+    }
 
     /**
      *  Return the native ID or handle to the texture, depending on the
@@ -209,6 +212,36 @@
     void validate() const {}
 #endif
 
+protected:
+    GrRenderTarget* fRenderTarget; // texture refs its rt representation
+                                   // base class cons sets to NULL
+                                   // subclass cons can create and set
+
+    GrTexture(GrGpu* gpu,
+              int width,
+              int height,
+              GrPixelConfig config)
+    : INHERITED(gpu)
+    , fRenderTarget(NULL)
+    , fWidth(width)
+    , fHeight(height)
+    , fConfig(config) {
+        // only make sense if alloc size is pow2
+        fShiftFixedX = 31 - Gr_clz(fWidth);
+        fShiftFixedY = 31 - Gr_clz(fHeight);
+    }
+    
+    // GrResource overrides
+    virtual void onRelease() {
+        releaseRenderTarget();
+    }
+
+    virtual void onAbandon() {
+        if (NULL != fRenderTarget) {
+            fRenderTarget->abandon();
+        }
+    }
+
 private:
     int fWidth;
     int fHeight;
diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp
index bd157d2..ce9345b 100644
--- a/gpu/src/GrGLTexture.cpp
+++ b/gpu/src/GrGLTexture.cpp
@@ -118,7 +118,6 @@
                             textureDesc.fAllocWidth;
     fScaleY             = GrIntToScalar(textureDesc.fContentHeight) /
                             textureDesc.fAllocHeight;
-    fRenderTarget       = NULL;
 
     GrAssert(0 != textureDesc.fTextureID);
 
@@ -137,30 +136,19 @@
 }
 
 void GrGLTexture::onRelease() {
+    INHERITED::onRelease();
     if (NULL != fTexIDObj) {
         GPUGL->notifyTextureDelete(this);
         fTexIDObj->unref();
         fTexIDObj = NULL;
-        GrSafeUnref(fRenderTarget);
     }
 }
 
 void GrGLTexture::onAbandon() {
+    INHERITED::onAbandon();
     if (NULL != fTexIDObj) {
         fTexIDObj->abandon();
     }
-    if (NULL != fRenderTarget) {
-        fRenderTarget->abandon();
-    }
-}
-
-GrRenderTarget* GrGLTexture::asRenderTarget() {
-    return fRenderTarget;
-}
-
-void GrGLTexture::releaseRenderTarget() {
-    GrSafeUnref(fRenderTarget);
-    fRenderTarget = NULL;
 }
 
 void GrGLTexture::uploadTextureData(uint32_t x,
@@ -189,5 +177,3 @@
     return fTexIDObj->id();
 }
 
-
-
diff --git a/gpu/src/GrTexture.cpp b/gpu/src/GrTexture.cpp
index 7c5f87f..1ea02a7 100644
--- a/gpu/src/GrTexture.cpp
+++ b/gpu/src/GrTexture.cpp
@@ -28,11 +28,6 @@
                                            config, buffer);
 }
 
-GrTexture::~GrTexture() {
-    // use this to set a break-point if needed
-//    Gr_clz(3);
-}
-
 bool GrTexture::readPixels(int left, int top, int width, int height,
                            GrPixelConfig config, void* buffer) {
     // go through context so that all necessary flushing occurs
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index e58fa26..1e8d9aa 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -804,12 +804,6 @@
             delete fGpuCanvas;
             fGpuCanvas = NULL;
             presentGL();
-            
-#if 1
-            SkDebugf("---- destructor %d\n", fGrContext->refcnt());
-            fGrContext->unref();
-            fGrContext = NULL;
-#endif
             break;
 #endif
     }
diff --git a/vs/SampleApp/SampleApp.vcxproj b/vs/SampleApp/SampleApp.vcxproj
index 5eafc89..2d88f14 100644
--- a/vs/SampleApp/SampleApp.vcxproj
+++ b/vs/SampleApp/SampleApp.vcxproj
@@ -247,6 +247,7 @@
     <ClCompile Include="..\..\gpu\src\GrStencil.cpp" />

     <ClCompile Include="..\..\gpu\src\GrTextContext.cpp" />

     <ClCompile Include="..\..\gpu\src\GrTextStrike.cpp" />

+    <ClCompile Include="..\..\gpu\src\GrTexture.cpp" />

     <ClCompile Include="..\..\gpu\src\GrTextureCache.cpp" />

     <ClCompile Include="..\..\gpu\src\gr_unittests.cpp" />

     <ClCompile Include="..\..\gpu\src\win\GrGLDefaultInterface_win.cpp" />

diff --git a/vs/SampleApp/SampleApp.vcxproj.filters b/vs/SampleApp/SampleApp.vcxproj.filters
index 7f9e743..c32978f 100644
--- a/vs/SampleApp/SampleApp.vcxproj.filters
+++ b/vs/SampleApp/SampleApp.vcxproj.filters
@@ -472,6 +472,9 @@
     <ClCompile Include="..\..\gpu\src\GrPathUtils.cpp">

       <Filter>Gr\src</Filter>

     </ClCompile>

+    <ClCompile Include="..\..\gpu\src\GrTexture.cpp">

+      <Filter>Gr\src</Filter>

+    </ClCompile>

   </ItemGroup>

   <ItemGroup>

     <ClInclude Include="..\..\gpu\include\FlingState.h" />