Add GrRenderTexture cons for gpu dev. Remove factory from gpu device.

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


git-svn-id: http://skia.googlecode.com/svn/trunk@1634 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 3a675be..afb1459 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -50,6 +50,13 @@
     SkGpuDevice(GrContext*, GrRenderTarget*);
 
     /**
+     *  New device that will render to the texture (as a rendertarget).
+     *  The GrTexture's asRenderTarget() must be non-NULL or device will not
+     *  function.
+     */
+    SkGpuDevice(GrContext*, GrTexture*);
+
+    /**
      * Magic value that can be passed to constructor. Causes
      * the device to infer rendertarget from underlying 3D API (e.g. GL or D3D).
      * This isn't a valid pointer, don't attempt to dereference.
@@ -129,8 +136,6 @@
     virtual void makeRenderTargetCurrent();
 
 protected:
-    // override
-    virtual SkDeviceFactory* onNewDeviceFactory();
 
     class TexCache;
     enum TexType {
@@ -173,6 +178,9 @@
     bool            fNeedClear;
     bool            fNeedPrepareRenderTarget;
 
+    // called from rt and tex cons
+    void initFromRenderTarget(GrContext*, GrRenderTarget*);
+
     // doesn't set the texture/sampler/matrix state
     // caller needs to null out GrPaint's texture if
     // non-textured drawing is desired.
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index cda10d2..5f08847 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -140,9 +140,18 @@
     return bitmap;
 }
 
+SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture)
+: SkDevice(make_bitmap(context, texture->asRenderTarget())) {
+    this->initFromRenderTarget(context, texture->asRenderTarget());
+}
+
 SkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget)
 : SkDevice(make_bitmap(context, renderTarget)) {
-    
+    this->initFromRenderTarget(context, renderTarget);
+}
+
+void SkGpuDevice::initFromRenderTarget(GrContext* context, 
+                                       GrRenderTarget* renderTarget) {
     fNeedPrepareRenderTarget = false;
     fDrawProcs = NULL;
     
@@ -157,8 +166,12 @@
     if (Current3DApiRenderTarget() == renderTarget) {
         fRenderTarget = fContext->createRenderTargetFrom3DApiState();
     } else {
+        GrAssert(NULL != renderTarget);
         fRenderTarget = renderTarget;
         fRenderTarget->ref();
+        // if this RT is also a texture, hold a ref on it
+        fTexture = fRenderTarget->asTexture();
+        SkSafeRef(fTexture);
     }
 
     SkGrRenderTargetPixelRef* pr = new SkGrRenderTargetPixelRef(fRenderTarget);
@@ -194,6 +207,9 @@
     if (fCache) {
         SkASSERT(NULL != fTexture);
         SkASSERT(NULL != fTexture->asRenderTarget());
+        // hold a ref directly on fTexture (even though fCache has one) to match
+        // other constructor paths. Simplifies cleanup.
+        fTexture->ref();
     }
 #else
     const GrTextureDesc desc = {
@@ -208,6 +224,7 @@
 #endif
     if (NULL != fTexture) {
         fRenderTarget = fTexture->asRenderTarget();
+        fRenderTarget->ref();
 
         GrAssert(NULL != fRenderTarget);
 
@@ -229,17 +246,13 @@
         delete fDrawProcs;
     }
 
+    SkSafeUnref(fTexture);
+    SkSafeUnref(fRenderTarget);
     if (fCache) {
         GrAssert(NULL != fTexture);
         GrAssert(fRenderTarget == fTexture->asRenderTarget());
         fContext->unlockTexture((GrTextureEntry*)fCache);
-    } else if (NULL != fTexture) {
-        GrAssert(!CACHE_LAYER_TEXTURES);
-        GrAssert(fRenderTarget == fTexture->asRenderTarget());
-        fTexture->unref();
-    } else if (NULL != fRenderTarget) {
-        fRenderTarget->unref();
-    }
+    } 
     fContext->unref();
 }
 
@@ -251,10 +264,6 @@
     }
 }
 
-SkDeviceFactory* SkGpuDevice::onNewDeviceFactory() {
-    return SkNEW_ARGS(SkGpuDeviceFactory, (fContext, fRenderTarget));
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkGpuDevice::makeRenderTargetCurrent() {