Cleanup: Removing unnecessary args/complexity in SkSurface_Base and friends
Review URL: https://codereview.chromium.org/14263017

git-svn-id: http://skia.googlecode.com/svn/trunk@8708 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 5b2e381..2d8212d 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -122,7 +122,7 @@
 
 void SkCanvas::predrawNotify() {
     if (fSurfaceBase) {
-        fSurfaceBase->aboutToDraw(this);
+        fSurfaceBase->aboutToDraw();
     }
 }
 
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 8cce965..e233dd0 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -59,21 +59,21 @@
     return fCachedImage;
 }
 
-void SkSurface_Base::aboutToDraw(SkCanvas* canvas) {
+void SkSurface_Base::aboutToDraw() {
     this->dirtyGenerationID();
 
-    if (canvas) {
-        SkASSERT(canvas == fCachedCanvas);
-        SkASSERT(canvas->getSurfaceBase() == this);
-        canvas->setSurfaceBase(NULL);
+    if (NULL != fCachedCanvas) {
+        SkASSERT(fCachedCanvas->getSurfaceBase() == this || \
+                 NULL == fCachedCanvas->getSurfaceBase());
+        fCachedCanvas->setSurfaceBase(NULL);
     }
 
-    if (fCachedImage) {
+    if (NULL != fCachedImage) {
         // the surface may need to fork its backend, if its sharing it with
         // the cached image. Note: we only call if there is an outstanding owner
         // on the image (besides us).
         if (fCachedImage->getRefCnt() > 1) {
-            this->onCopyOnWrite(fCachedImage, canvas);
+            this->onCopyOnWrite();
         }
 
         // regardless of copy-on-write, we must drop our cached image now, so
@@ -110,7 +110,7 @@
 }
 
 void SkSurface::notifyContentChanged() {
-    asSB(this)->aboutToDraw(NULL);
+    asSB(this)->aboutToDraw();
 }
 
 SkCanvas* SkSurface::getCanvas() {
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index bda271b..d0590bc 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -51,7 +51,7 @@
      *
      *  The default implementation does nothing.
      */
-    virtual void onCopyOnWrite(SkImage* cachedImage, SkCanvas*) = 0;
+    virtual void onCopyOnWrite() = 0;
 
     inline SkCanvas* getCachedCanvas();
     inline SkImage* getCachedImage();
@@ -63,7 +63,7 @@
     SkCanvas*   fCachedCanvas;
     SkImage*    fCachedImage;
 
-    void aboutToDraw(SkCanvas*);
+    void aboutToDraw();
     friend class SkCanvas;
     friend class SkSurface;
 
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index ec709ca..098c92b 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -23,7 +23,7 @@
     virtual SkImage* onNewImageSnapshot() SK_OVERRIDE;
     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
                         const SkPaint*) SK_OVERRIDE;
-    virtual void onCopyOnWrite(SkImage*, SkCanvas*) SK_OVERRIDE;
+    virtual void onCopyOnWrite() SK_OVERRIDE;
 
 private:
     SkGpuDevice* fDevice;
@@ -86,20 +86,21 @@
 // Create a new SkGpuDevice and, if necessary, copy the contents of the old
 // device into it. Note that this flushes the SkGpuDevice but
 // doesn't force an OpenGL flush.
-void SkSurface_Gpu::onCopyOnWrite(SkImage* image, SkCanvas* canvas) {
+void SkSurface_Gpu::onCopyOnWrite() {
     GrRenderTarget* rt = (GrRenderTarget*) fDevice->accessRenderTarget();
 
     // are we sharing our render target with the image?
-    if (rt->asTexture() == SkTextureImageGetTexture(image)) {
+    SkASSERT(NULL != this->getCachedImage());
+    if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) {
         SkGpuDevice* newDevice = static_cast<SkGpuDevice*>(
             fDevice->createCompatibleDevice(fDevice->config(), fDevice->width(),
             fDevice->height(), fDevice->isOpaque()));
         SkAutoTUnref<SkGpuDevice> aurd(newDevice);
         fDevice->context()->copyTexture(rt->asTexture(),
             (GrRenderTarget*)newDevice->accessRenderTarget());
-        SkASSERT(NULL != canvas);
-        SkASSERT(canvas->getDevice() == fDevice);
-        canvas->setDevice(newDevice);
+        SkASSERT(NULL != this->getCachedCanvas());
+        SkASSERT(this->getCachedCanvas()->getDevice() == fDevice);
+        this->getCachedCanvas()->setDevice(newDevice);
         SkRefCnt_SafeAssign(fDevice, newDevice);
     }
 }
diff --git a/src/image/SkSurface_Picture.cpp b/src/image/SkSurface_Picture.cpp
index d7b84ec..affa05c 100644
--- a/src/image/SkSurface_Picture.cpp
+++ b/src/image/SkSurface_Picture.cpp
@@ -24,7 +24,7 @@
     virtual SkImage* onNewImageSnapshot() SK_OVERRIDE;
     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
                         const SkPaint*) SK_OVERRIDE;
-    virtual void onCopyOnWrite(SkImage*, SkCanvas*) SK_OVERRIDE;
+    virtual void onCopyOnWrite() SK_OVERRIDE;
 
 private:
     SkPicture*  fPicture;
@@ -75,7 +75,7 @@
     SkImagePrivDrawPicture(canvas, fPicture, x, y, paint);
 }
 
-void SkSurface_Picture::onCopyOnWrite(SkImage* cachedImage, SkCanvas*) {
+void SkSurface_Picture::onCopyOnWrite() {
     // We always spawn a copy of the recording picture when we
     // are asked for a snapshot, so we never need to do anything here.
 }
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index b88d0e2..9a1f312 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -25,7 +25,7 @@
     virtual SkImage* onNewImageSnapshot() SK_OVERRIDE;
     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y,
                         const SkPaint*) SK_OVERRIDE;
-    virtual void onCopyOnWrite(SkImage*, SkCanvas*) SK_OVERRIDE;
+    virtual void onCopyOnWrite() SK_OVERRIDE;
 
 private:
     SkBitmap    fBitmap;
@@ -124,16 +124,18 @@
     return SkNewImageFromBitmap(fBitmap, fWeOwnThePixels);
 }
 
-void SkSurface_Raster::onCopyOnWrite(SkImage* image, SkCanvas* canvas) {
+void SkSurface_Raster::onCopyOnWrite() {
     // are we sharing pixelrefs with the image?
-    if (SkBitmapImageGetPixelRef(image) == fBitmap.pixelRef()) {
+    SkASSERT(NULL !=this->getCachedImage());
+    if (SkBitmapImageGetPixelRef(this->getCachedImage()) == fBitmap.pixelRef()) {
         SkASSERT(fWeOwnThePixels);
         SkBitmap prev(fBitmap);
         prev.deepCopyTo(&fBitmap, prev.config());
         // Now fBitmap is a deep copy of itself (and therefore different from
         // what is being used by the image. Next we update the canvas to use
         // this as its backend, so we can't modify the image's pixels anymore.
-        canvas->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap);
+        SkASSERT(NULL != this->getCachedCanvas());
+        this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap);
     }
 }
 
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 5f2dca6..27029a1 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -146,17 +146,49 @@
     surface->newImageSnapshot()->unref();  // Create and destroy SkImage
     canvas->clear(2);
 }
+static void TestSurfaceNoCanvas(skiatest::Reporter* reporter,
+                                          SurfaceType surfaceType,
+                                          GrContext* context) {
+    // Verifies the robustness of SkSurface for handling use cases where calls
+    // are made before a canvas is created.
+    {
+        // Test passes by not asserting
+        SkSurface* surface = createSurface(surfaceType, context);
+        SkAutoTUnref<SkSurface> aur_surface(surface);
+        surface->notifyContentChanged();
+        surface->validate();
+    }
+    {
+        SkSurface* surface = createSurface(surfaceType, context);
+        SkAutoTUnref<SkSurface> aur_surface(surface);
+        SkImage* image1 = surface->newImageSnapshot();
+        SkAutoTUnref<SkImage> aur_image1(image1);
+        image1->validate();
+        surface->validate();
+        surface->notifyContentChanged();
+        image1->validate();
+        surface->validate();
+        SkImage* image2 = surface->newImageSnapshot();
+        SkAutoTUnref<SkImage> aur_image2(image2);
+        image2->validate();
+        surface->validate();
+        REPORTER_ASSERT(reporter, image1 != image2);
+    }
+    
+}
 
 static void TestSurface(skiatest::Reporter* reporter, GrContextFactory* factory) {
     TestSurfaceCopyOnWrite(reporter, kRaster_SurfaceType, NULL);
     TestSurfaceCopyOnWrite(reporter, kPicture_SurfaceType, NULL);
     TestSurfaceWritableAfterSnapshotRelease(reporter, kRaster_SurfaceType, NULL);
     TestSurfaceWritableAfterSnapshotRelease(reporter, kPicture_SurfaceType, NULL);
+    TestSurfaceNoCanvas(reporter, kRaster_SurfaceType, NULL);
 #if SK_SUPPORT_GPU
     if (NULL != factory) {
         GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
         TestSurfaceCopyOnWrite(reporter, kGpu_SurfaceType, context);
         TestSurfaceWritableAfterSnapshotRelease(reporter, kGpu_SurfaceType, context);
+        TestSurfaceNoCanvas(reporter, kGpu_SurfaceType, context);
     }
 #endif
 }