add null-surface

Bug:crbug.com/737726
Change-Id: Iec9094d8d7232943e90fe2d9745fc83bcdf90954
Reviewed-on: https://skia-review.googlesource.com/21190
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index 08e558c..f6142c9 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -176,6 +176,12 @@
         return MakeRenderTarget(gr, b, info, 0, kBottomLeft_GrSurfaceOrigin, nullptr);
     }
 
+    /**
+     *  Returns a surface that stores no pixels. It can be drawn to via its canvas, but that
+     *  canvas does not draw anything. Calling makeImageSnapshot() will return nullptr.
+     */
+    static sk_sp<SkSurface> MakeNull(int width, int height);
+
     int width() const { return fWidth; }
     int height() const { return fHeight; }
 
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 57d419c..dcf5649 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -200,6 +200,32 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////////////
+#include "SkNoDrawCanvas.h"
+
+class SkNullSurface : public SkSurface_Base {
+public:
+    SkNullSurface(int width, int height) : SkSurface_Base(width, height, nullptr) {}
+
+protected:
+    SkCanvas* onNewCanvas() override {
+        return new SkNoDrawCanvas(this->width(), this->height());
+    }
+    sk_sp<SkSurface> onNewSurface(const SkImageInfo& info) override {
+        return MakeNull(info.width(), info.height());
+    }
+    sk_sp<SkImage> onNewImageSnapshot() override { return nullptr; }
+    void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) override {}
+    void onCopyOnWrite(ContentChangeMode) override {}
+};
+
+sk_sp<SkSurface> SkSurface::MakeNull(int width, int height) {
+    if (width < 1 || height < 1) {
+        return nullptr;
+    }
+    return sk_sp<SkSurface>(new SkNullSurface(width, height));
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
 
 #if !SK_SUPPORT_GPU
 
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index dc051a5..5249b3d 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -948,3 +948,15 @@
     test_overdraw_surface(r, surface.get());
 }
 #endif
+
+DEF_TEST(Surface_null, r) {
+    REPORTER_ASSERT(r, SkSurface::MakeNull(0, 0) == nullptr);
+
+    const int w = 37;
+    const int h = 1000;
+    auto surf = SkSurface::MakeNull(w, h);
+    auto canvas = surf->getCanvas();
+
+    canvas->drawPaint(SkPaint());   // should not crash, but don't expect anything to draw
+    REPORTER_ASSERT(r, surf->makeImageSnapshot() == nullptr);
+}