retool so we don't need to call SkCanvas::setDevice
Review URL: https://codereview.appspot.com/6591054

git-svn-id: http://skia.googlecode.com/svn/trunk@5759 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/iOSSampleApp/SkSampleUIView.mm b/experimental/iOSSampleApp/SkSampleUIView.mm
index a6ab105..b716402 100644
--- a/experimental/iOSSampleApp/SkSampleUIView.mm
+++ b/experimental/iOSSampleApp/SkSampleUIView.mm
@@ -117,32 +117,35 @@
         win->detach();
         fBackend = SampleWindow::kNone_BackEndType;
     }
-    
-    virtual bool prepareCanvas(SampleWindow::DeviceType dType,
-                               SkCanvas* canvas,
-                               SampleWindow* win) SK_OVERRIDE {
+
+    virtual SkCanvas* createCanvas(SampleWindow::DeviceType dType,
+                                   SampleWindow* win) {
         switch (dType) {
-            // use the window's bmp for these two
             case SampleWindow::kRaster_DeviceType:
+                // fallthrough
             case SampleWindow::kPicture_DeviceType:
-                canvas->setDevice(SkNEW_ARGS(SkDevice, (win->getBitmap())))->unref();
+                // fallthrough
+#if SK_ANGLE
+            case SampleWindow::kANGLE_DeviceType:
+#endif
                 break;
 #if SK_SUPPORT_GPU
-            // create a GPU device for these two
             case SampleWindow::kGPU_DeviceType:
             case SampleWindow::kNullGPU_DeviceType:
-                if (NULL != fCurContext) {
-                    canvas->setDevice(new SkGpuDevice(fCurContext, fCurRenderTarget))->unref();
+                if (fCurContext) {
+                    SkAutoTUnref<SkDevice> device(new SkGpuDevice(fCurContext,
+                                                                  fCurRenderTarget));
+                    return new SkCanvas(device);
                 } else {
-                    return false;
+                    return NULL;
                 }
                 break;
 #endif
             default:
                 SkASSERT(false);
-                return false;
+                return NULL;
         }
-        return true;
+        return NULL;
     }
     
     virtual void publishCanvas(SampleWindow::DeviceType dType,
@@ -428,13 +431,13 @@
     glViewport(0, 0, fGL.fWidth, fGL.fHeight);
     
    
-    SkCanvas canvas;
+    SkAutoTUnref<SkCanvas> canvas(fWind->createCanvas());
     // if we're not "retained", then we have to always redraw everything.
     // This call forces us to ignore the fDirtyRgn, and draw everywhere.
     // If we are "retained", we can skip this call (as the raster case does)
     fWind->forceInvalAll();
 
-    [self drawWithCanvas:&canvas];
+    [self drawWithCanvas:canvas];
     
     // This application only creates a single color renderbuffer which is already bound at this point.
     // This call is redundant, but needed if dealing with multiple renderbuffers.
@@ -444,8 +447,8 @@
 }
 
 - (void)drawInRaster {
-    SkCanvas canvas;
-    [self drawWithCanvas:&canvas];
+    SkAutoTUnref<SkCanvas> canvas(fWind->createCanvas());
+    [self drawWithCanvas:canvas];
     CGImageRef cgimage = SkCreateCGImageRef(fWind->getBitmap());
     fRasterLayer.contents = (id)cgimage;
     CGImageRelease(cgimage);
diff --git a/include/views/SkWindow.h b/include/views/SkWindow.h
index 8ba0e80..f1d3881 100644
--- a/include/views/SkWindow.h
+++ b/include/views/SkWindow.h
@@ -61,6 +61,8 @@
     void    preConcat(const SkMatrix&);
     void    postConcat(const SkMatrix&);
 
+    virtual SkCanvas* createCanvas();
+
     virtual void onPDFSaved(const char title[], const char desc[],
         const char path[]) {}
 protected:
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index a98f2fc..c55a5c0 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -257,9 +257,8 @@
         fBackend = kNone_BackEndType;
     }
 
-    virtual bool prepareCanvas(SampleWindow::DeviceType dType,
-                               SkCanvas* canvas,
-                               SampleWindow* win) {
+    virtual SkCanvas* createCanvas(SampleWindow::DeviceType dType,
+                                   SampleWindow* win) {
         switch (dType) {
             case kRaster_DeviceType:
                 // fallthrough
@@ -273,18 +272,19 @@
             case kGPU_DeviceType:
             case kNullGPU_DeviceType:
                 if (fCurContext) {
-                    canvas->setDevice(new SkGpuDevice(fCurContext,
-                                                    fCurRenderTarget))->unref();
+                    SkAutoTUnref<SkDevice> device(new SkGpuDevice(fCurContext,
+                                                                  fCurRenderTarget));
+                    return new SkCanvas(device);
                 } else {
-                    return false;
+                    return NULL;
                 }
                 break;
 #endif
             default:
                 SkASSERT(false);
-                return false;
+                return NULL;
         }
-        return true;
+        return NULL;
     }
 
     virtual void publishCanvas(SampleWindow::DeviceType dType,
@@ -1035,9 +1035,6 @@
 #define YCLIP_N  8
 
 void SampleWindow::draw(SkCanvas* canvas) {
-    if (!fDevManager->prepareCanvas(fDeviceType, canvas, this)) {
-        return;
-    }
     // update the animation time
     if (!gAnimTimePrev && !gAnimTime) {
         // first time make delta be 0
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index abd8ac7..85392e0 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -58,9 +58,7 @@
 
         // called before drawing. should install correct device
         // type on the canvas. Will skip drawing if returns false.
-        virtual bool prepareCanvas(DeviceType dType,
-                                   SkCanvas* canvas,
-                                   SampleWindow* win) = 0;
+        virtual SkCanvas* createCanvas(DeviceType dType, SampleWindow* win) = 0;
 
         // called after drawing, should get the results onto the
         // screen.
@@ -84,6 +82,17 @@
     SampleWindow(void* hwnd, int argc, char** argv, DeviceManager*);
     virtual ~SampleWindow();
 
+    virtual SkCanvas* createCanvas() SK_OVERRIDE {
+        SkCanvas* canvas = NULL;
+        if (fDevManager) {
+            canvas = fDevManager->createCanvas(fDeviceType, this);
+        }
+        if (NULL == canvas) {
+            canvas = this->INHERITED::createCanvas();
+        }
+        return canvas;
+    }
+
     virtual void draw(SkCanvas* canvas);
 
     void setDeviceType(DeviceType type);
diff --git a/src/views/SkWindow.cpp b/src/views/SkWindow.cpp
index d427efb..b20267a 100644
--- a/src/views/SkWindow.cpp
+++ b/src/views/SkWindow.cpp
@@ -66,6 +66,10 @@
     fMenus.deleteAll();
 }
 
+SkCanvas* SkWindow::createCanvas() {
+    return new SkCanvas(this->getBitmap());
+}
+
 void SkWindow::setMatrix(const SkMatrix& matrix) {
     if (fMatrix != matrix) {
         fMatrix = matrix;
diff --git a/src/views/mac/SkNSView.mm b/src/views/mac/SkNSView.mm
index f43af64..ffa9d7c 100644
--- a/src/views/mac/SkNSView.mm
+++ b/src/views/mac/SkNSView.mm
@@ -81,8 +81,8 @@
 - (void)drawSkia {
     fRedrawRequestPending = false;
     if (NULL != fWind) {
-        SkCanvas canvas(fWind->getBitmap());
-        fWind->draw(&canvas);
+        SkAutoTUnref<SkCanvas> canvas(fWind->createCanvas());
+        fWind->draw(canvas);
 #ifdef FORCE_REDRAW
         fWind->inval(NULL);
 #endif