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/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;