stop calling SkCanvas::getDevice

BUG=skia:
R=bsalomon@google.com, robertphillips@google.com, junov@google.com

Author: reed@google.com

Review URL: https://codereview.chromium.org/355193006
diff --git a/bench/DeferredSurfaceCopyBench.cpp b/bench/DeferredSurfaceCopyBench.cpp
index f4002b8..cbf98ec 100644
--- a/bench/DeferredSurfaceCopyBench.cpp
+++ b/bench/DeferredSurfaceCopyBench.cpp
@@ -34,26 +34,11 @@
     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
         // The canvas is not actually used for this test except to provide
         // configuration information: gpu, multisampling, size, etc?
-        SkImageInfo info;
-        info.fWidth = kSurfaceWidth;
-        info.fHeight = kSurfaceHeight;
-        info.fColorType = kN32_SkColorType;
-        info.fAlphaType = kPremul_SkAlphaType;
+        SkImageInfo info = SkImageInfo::MakeN32Premul(kSurfaceWidth, kSurfaceHeight);
         const SkRect fullCanvasRect = SkRect::MakeWH(
             SkIntToScalar(kSurfaceWidth), SkIntToScalar(kSurfaceHeight));
-        SkSurface* surface;
-#if SK_SUPPORT_GPU
-        GrRenderTarget* rt = reinterpret_cast<GrRenderTarget*>(
-            canvas->getDevice()->accessRenderTarget());
-        if (NULL != rt) {
-            surface = SkSurface::NewRenderTarget(rt->getContext(), info, rt->numSamples());
-        } else
-#endif
-        {
-            surface = SkSurface::NewRaster(info);
-        }
+        SkAutoTUnref<SkSurface> surface(canvas->newSurface(info));
         SkAutoTUnref<SkDeferredCanvas> drawingCanvas(SkDeferredCanvas::Create(surface));
-        surface->unref();
 
         for (int iteration = 0; iteration < loops; iteration++) {
             drawingCanvas->clear(0);
diff --git a/gm/srcmode.cpp b/gm/srcmode.cpp
index 6aa236f..a8e0201 100644
--- a/gm/srcmode.cpp
+++ b/gm/srcmode.cpp
@@ -115,18 +115,21 @@
         }
     }
 
-    static SkSurface* compat_surface(SkCanvas* canvas, const SkISize& size,
-                                     bool skipGPU) {
+    static SkSurface* compat_surface(SkCanvas* canvas, const SkISize& size, bool skipGPU) {
         SkImageInfo info = SkImageInfo::MakeN32Premul(size);
+
+        bool callNewSurface = true;
 #if SK_SUPPORT_GPU
-        SkBaseDevice* dev = canvas->getDevice();
-        if (!skipGPU && dev->accessRenderTarget()) {
-            SkGpuDevice* gd = (SkGpuDevice*)dev;
-            GrContext* ctx = gd->context();
-            return SkSurface::NewRenderTarget(ctx, info, 0);
+        if (canvas->getGrContext() && skipGPU) {
+            callNewSurface = false;
         }
 #endif
-        return SkSurface::NewRaster(info);
+        SkSurface* surface = callNewSurface ? canvas->newSurface(info) : NULL;
+        if (NULL == surface) {
+            // picture canvas will return null, so fall-back to raster
+            surface = SkSurface::NewRaster(info);
+        }
+        return surface;
     }
 
     virtual void onDraw(SkCanvas* canvas) {
diff --git a/gm/xfermodes3.cpp b/gm/xfermodes3.cpp
index 92367f3..50b92c8 100644
--- a/gm/xfermodes3.cpp
+++ b/gm/xfermodes3.cpp
@@ -123,13 +123,12 @@
     SkCanvas* possiblyCreateTempCanvas(SkCanvas* baseCanvas, int w, int h) {
         SkCanvas* tempCanvas = NULL;
 #if SK_SUPPORT_GPU
-        GrRenderTarget* rt = baseCanvas->getDevice()->accessRenderTarget();
-        if (NULL != rt) {
-            GrContext* context = rt->getContext();
+        GrContext* context = baseCanvas->getGrContext();
+        if (NULL != context) {
             GrTextureDesc desc;
             desc.fWidth = w;
             desc.fHeight = h;
-            desc.fConfig = rt->config();
+            desc.fConfig = SkImageInfo2GrPixelConfig(baseCanvas->imageInfo());
             desc.fFlags = kRenderTarget_GrTextureFlagBit;
             SkAutoTUnref<GrSurface> surface(context->createUncachedTexture(desc, NULL, 0));
             SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(surface.get()));
diff --git a/gyp/skia_for_android_framework_defines.gypi b/gyp/skia_for_android_framework_defines.gypi
index 9559f43..66bb059 100644
--- a/gyp/skia_for_android_framework_defines.gypi
+++ b/gyp/skia_for_android_framework_defines.gypi
@@ -14,6 +14,7 @@
     #
     'skia_for_android_framework_defines': [
       'SK_SUPPORT_LEGACY_SETCONFIG_INFO',
+      'SK_SUPPORT_LEGACY_GETDEVICE',
       'SK_SUPPORT_LEGACY_SETCONFIG',
       'SK_SUPPORT_LEGACY_IMAGEDECODER_CONFIG',
       'SK_SUPPORT_LEGACY_DEVICE_VIRTUAL_ISOPAQUE',
diff --git a/gyp/skia_for_chromium_defines.gypi b/gyp/skia_for_chromium_defines.gypi
index 9d0e963..967e1ff 100644
--- a/gyp/skia_for_chromium_defines.gypi
+++ b/gyp/skia_for_chromium_defines.gypi
@@ -14,6 +14,7 @@
     #
     'skia_for_chromium_defines': [
       'SK_SUPPORT_LEGACY_PICTURE_CLONE',
+      'SK_SUPPORT_LEGACY_GETDEVICE',
       'SK_SUPPORT_LEGACY_GETTOPDEVICE',
       'SK_SUPPORT_LEGACY_BITMAP_CONFIG',
       'SK_SUPPORT_LEGACY_N32_NAME',
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 7a4ddd9..c114eb2 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -164,7 +164,11 @@
      *  the bitmap of the pixels that the canvas draws into. The reference count
      *  of the returned device is not changed by this call.
      */
+#ifndef SK_SUPPORT_LEGACY_GETDEVICE
+protected:  // Can we make this private?
+#endif
     SkBaseDevice* getDevice() const;
+public:
 
     /**
      *  saveLayer() can create another device (which is later drawn onto
@@ -1270,6 +1274,7 @@
     friend class SkLua;             // needs top layer size and offset
     friend class SkDebugCanvas;     // needs experimental fAllowSimplifyClip
     friend class SkDeferredDevice;  // needs getTopDevice()
+    friend class SkSurface_Raster;  // needs getDevice()
 
     SkBaseDevice* createLayerDevice(const SkImageInfo&);
 
diff --git a/include/utils/SkDeferredCanvas.h b/include/utils/SkDeferredCanvas.h
index 5abff74..0e2ed45 100644
--- a/include/utils/SkDeferredCanvas.h
+++ b/include/utils/SkDeferredCanvas.h
@@ -131,6 +131,7 @@
      * rendered using the deferred canvas.
      */
     void setBitmapSizeThreshold(size_t sizeThreshold);
+    size_t getBitmapSizeThreshold() const { return fBitmapSizeThreshold; }
 
     /**
      * Executes all pending commands without drawing
@@ -240,7 +241,9 @@
     bool isFullFrame(const SkRect*, const SkPaint*) const;
     void validate() const;
     void init();
-    bool            fDeferredDrawing;
+
+    size_t fBitmapSizeThreshold;
+    bool   fDeferredDrawing;
 
     friend class SkDeferredCanvasTester; // for unit testing
     typedef SkCanvas INHERITED;
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index df10b1e..8825f53 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -1007,7 +1007,7 @@
 
 static bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
                         SkBitmap* diff) {
-    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
+    SkBitmap src = capture_bitmap(canvas);
 
     SkAutoLockPixels alp0(src);
     SkAutoLockPixels alp1(orig);
@@ -1282,7 +1282,7 @@
 
 SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
     if (fSaveToPdf) {
-        const SkBitmap& bmp = canvas->getDevice()->accessBitmap(false);
+        const SkBitmap bmp = capture_bitmap(canvas);
         SkISize size = SkISize::Make(bmp.width(), bmp.height());
         SkPDFDevice* pdfDevice = new SkPDFDevice(size, size,
                 canvas->getTotalMatrix());
@@ -1308,15 +1308,6 @@
     return canvas;
 }
 
-static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
-                      const SkRegion& rgn) {
-    SkCanvas    canvas(bm);
-    SkRegion    inval(rgn);
-
-    inval.translate(r.fLeft, r.fTop);
-    canvas.clipRegion(inval);
-    canvas.drawColor(0xFFFF8080);
-}
 #include "SkData.h"
 void SampleWindow::afterChildren(SkCanvas* orig) {
     if (fSaveToPdf) {
@@ -1327,7 +1318,8 @@
         SkString name;
         name.printf("%s.pdf", this->getTitle());
         SkPDFDocument doc;
-        SkPDFDevice* device = static_cast<SkPDFDevice*>(fPdfCanvas->getDevice());
+        SkPDFDevice* device = NULL;//static_cast<SkPDFDevice*>(fPdfCanvas->getDevice());
+        SkASSERT(false);
         doc.appendPage(device);
 #ifdef SK_BUILD_FOR_ANDROID
         name.prepend("/sdcard/");
@@ -1357,9 +1349,8 @@
     if (fRequestGrabImage) {
         fRequestGrabImage = false;
 
-        SkBaseDevice* device = orig->getDevice();
-        SkBitmap bmp;
-        if (device->accessBitmap(false).copyTo(&bmp, kN32_SkColorType)) {
+        SkBitmap bmp = capture_bitmap(orig);
+        if (!bmp.isNull()) {
             static int gSampleGrabCounter;
             SkString name;
             name.printf("sample_grab_%d.png", gSampleGrabCounter++);
@@ -1395,19 +1386,6 @@
     if (fMeasureFPS && fMeasureFPS_StartTime) {
         fMeasureFPS_Time += SkTime::GetMSecs() - fMeasureFPS_StartTime;
     }
-
-    //    if ((fScrollTestX | fScrollTestY) != 0)
-    if (false) {
-        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
-        int dx = fScrollTestX * 7;
-        int dy = fScrollTestY * 7;
-        SkIRect r;
-        SkRegion inval;
-
-        r.set(50, 50, 50+100, 50+100);
-        bm.scrollRect(&r, dx, dy, &inval);
-        paint_rgn(bm, r, inval);
-    }
 }
 
 void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
@@ -2257,9 +2235,8 @@
     } else {
         SkGPipeWriter writer;
         SimplePC controller(canvas);
-        TiledPipeController tc(canvas->getDevice()->accessBitmap(false),
-                               &SkImageDecoder::DecodeMemory,
-                               &canvas->getTotalMatrix());
+        SkBitmap bitmap = capture_bitmap(canvas);
+        TiledPipeController tc(bitmap, &SkImageDecoder::DecodeMemory, &canvas->getTotalMatrix());
         SkGPipeController* pc;
         if (SkOSMenu::kMixedState == fPipeState) {
             pc = &tc;
diff --git a/samplecode/SampleTextAlpha.cpp b/samplecode/SampleTextAlpha.cpp
index fcef92f..3f4e0db 100644
--- a/samplecode/SampleTextAlpha.cpp
+++ b/samplecode/SampleTextAlpha.cpp
@@ -28,22 +28,6 @@
 #include "SkOSFile.h"
 #include "SkStream.h"
 
-static void check_for_nonwhite(const SkBitmap& bm, int alpha) {
-    if (bm.colorType() != kRGB_565_SkColorType) {
-        return;
-    }
-
-    for (int y = 0; y < bm.height(); y++) {
-        for (int x = 0; x < bm.width(); x++) {
-            uint16_t c = *bm.getAddr16(x, y);
-            if (c != 0xFFFF) {
-                SkDebugf("------ nonwhite alpha=%x [%d %d] %x\n", alpha, x, y, c);
-                return;
-            }
-        }
-    }
-}
-
 class TextAlphaView : public SampleView {
 public:
     TextAlphaView() {
@@ -83,16 +67,6 @@
             canvas->drawText(str, strlen(str), x, y, paint);
             y += paint.getFontMetrics(NULL);
         }
-        if (false) { // avoid bit rot, suppress warning
-            check_for_nonwhite(canvas->getDevice()->accessBitmap(false), fByte);
-            SkDebugf("------ byte %x\n", fByte);
-        }
-
-        if (false) {
-            fByte += 1;
-            fByte &= 0xFF;
-            this->inval(NULL);
-        }
     }
 
     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) SK_OVERRIDE {
diff --git a/src/animator/SkSnapshot.cpp b/src/animator/SkSnapshot.cpp
index 6f818a6..b61d602 100644
--- a/src/animator/SkSnapshot.cpp
+++ b/src/animator/SkSnapshot.cpp
@@ -60,8 +60,10 @@
         name.append(".jpg");
     else if (type == SkImageEncoder::kPNG_Type)
         name.append(".png");
-    encoder->encodeFile(name.c_str(),
-                        maker.fCanvas->getDevice()->accessBitmap(false),
-                        SkScalarFloorToInt(quality));
+
+    SkBitmap pixels;
+    pixels.allocPixels(maker.fCanvas->imageInfo());
+    maker.fCanvas->readPixels(&pixels, 0, 0);
+    encoder->encodeFile(name.c_str(), pixels, SkScalarFloorToInt(quality));
     return false;
 }
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index c35f284..583352c 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -857,12 +857,6 @@
     return this->internalSaveLayer(bounds, paint, flags, false, strategy);
 }
 
-static SkBaseDevice* create_compatible_device(SkCanvas* canvas,
-                                              const SkImageInfo& info) {
-    SkBaseDevice* device = canvas->getDevice();
-    return device ? device->createCompatibleDevice(info) : NULL;
-}
-
 int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags,
                                 bool justForImageFilter, SaveLayerStrategy strategy) {
 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
@@ -906,7 +900,10 @@
 
     SkBaseDevice* device;
     if (paint && paint->getImageFilter()) {
-        device = create_compatible_device(this, info);
+        device = this->getDevice();
+        if (device) {
+            device = device->createCompatibleDevice(info);
+        }
     } else {
         device = this->createLayerDevice(info);
     }
@@ -1382,13 +1379,8 @@
             currClip->op(clip, op);
         }
     } else {
-        const SkBaseDevice* device = canvas->getDevice();
-        if (!device) {
-            currClip->setEmpty();
-            return;
-        }
-
-        base.setRect(0, 0, device->width(), device->height());
+        const SkISize size = canvas->getBaseLayerSize();
+        base.setRect(0, 0, size.width(), size.height());
 
         if (SkRegion::kReplace_Op == op) {
             currClip->setPath(devPath, base, doAA);
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index 299e7ca..19957fd 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -30,8 +30,8 @@
     kSilent_PlaybackMode,
 };
 
-static bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint,
-                           size_t bitmapSizeThreshold) {
+static bool should_draw_immediately(const SkBitmap* bitmap, const SkPaint* paint,
+                                    size_t bitmapSizeThreshold) {
     if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) ||
         (bitmap->getSize() > bitmapSizeThreshold))) {
         return true;
@@ -150,8 +150,6 @@
     bool hasPendingCommands();
     size_t storageAllocatedForRecording() const;
     size_t freeMemoryIfPossible(size_t bytesToFree);
-    size_t getBitmapSizeThreshold() const;
-    void setBitmapSizeThreshold(size_t sizeThreshold);
     void flushPendingCommands(PlaybackMode);
     void skipPendingCommands();
     void setMaxRecordingStorage(size_t);
@@ -263,7 +261,6 @@
     bool fCanDiscardCanvasContents;
     size_t fMaxRecordingStorageBytes;
     size_t fPreviousStorageAllocated;
-    size_t fBitmapSizeThreshold;
 };
 
 SkDeferredDevice::SkDeferredDevice(SkSurface* surface) {
@@ -286,7 +283,6 @@
     fFreshFrame = true;
     fCanDiscardCanvasContents = false;
     fPreviousStorageAllocated = 0;
-    fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
     fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes;
     fNotificationClient = NULL;
     this->beginRecording();
@@ -378,14 +374,6 @@
     return val;
 }
 
-size_t SkDeferredDevice::getBitmapSizeThreshold() const {
-    return fBitmapSizeThreshold;
-}
-
-void SkDeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) {
-    fBitmapSizeThreshold = sizeThreshold;
-}
-
 size_t SkDeferredDevice::storageAllocatedForRecording() const {
     return (fPipeController.storageAllocatedForRecording()
             + fPipeWriter.storageAllocatedForRecording());
@@ -509,11 +497,9 @@
         }
     }
 private:
-    void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint)
-    {
-        SkDeferredDevice* device = static_cast<SkDeferredDevice*>(canvas.getDevice());
-        if (canvas.isDeferredDrawing() && (NULL != device) &&
-            shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) {
+    void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) {
+        if (canvas.isDeferredDrawing() &&
+            should_draw_immediately(bitmap, paint, canvas.getBitmapSizeThreshold())) {
             canvas.setDeferredDrawing(false);
             fCanvas = &canvas;
         } else {
@@ -534,6 +520,7 @@
 }
 
 void SkDeferredCanvas::init() {
+    fBitmapSizeThreshold = kDeferredCanvasBitmapSizeThreshold;
     fDeferredDrawing = true; // On by default
 }
 
@@ -551,9 +538,7 @@
 }
 
 void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) {
-    SkDeferredDevice* deferredDevice = this->getDeferredDevice();
-    SkASSERT(deferredDevice);
-    deferredDevice->setBitmapSizeThreshold(sizeThreshold);
+    fBitmapSizeThreshold = sizeThreshold;
 }
 
 void SkDeferredCanvas::recordedDrawCommand() {
diff --git a/tests/DeferredCanvasTest.cpp b/tests/DeferredCanvasTest.cpp
index 8aaeaed..cc8a1f2 100644
--- a/tests/DeferredCanvasTest.cpp
+++ b/tests/DeferredCanvasTest.cpp
@@ -49,23 +49,6 @@
     return pixel;
 }
 
-static void TestDeferredCanvasBitmapAccess(skiatest::Reporter* reporter) {
-    SkBitmap store;
-
-    SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
-    SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()));
-
-    canvas->clear(0x00000000);
-
-    // verify that the clear() was deferred
-    REPORTER_ASSERT(reporter, 0xFFFFFFFF == read_pixel(surface, 0, 0));
-
-    SkBitmap accessed = canvas->getDevice()->accessBitmap(false);
-
-    // verify that clear was executed
-    REPORTER_ASSERT(reporter, 0 == read_pixel(surface, 0, 0));
-}
-
 class MockSurface : public SkSurface_Base {
 public:
     MockSurface(int width, int height) : SkSurface_Base(width, height) {
@@ -681,13 +664,19 @@
 }
 
 
-typedef void* PixelPtr;
+typedef const void* PixelPtr;
 // Returns an opaque pointer which, either points to a GrTexture or RAM pixel
 // buffer. Used to test pointer equality do determine whether a surface points
 // to the same pixel data storage as before.
-static PixelPtr getSurfacePixelPtr(SkSurface* surface, bool useGpu) {
-    return useGpu ? surface->getCanvas()->getDevice()->accessBitmap(false).getTexture() :
-        surface->getCanvas()->getDevice()->accessBitmap(false).getPixels();
+static PixelPtr get_surface_ptr(SkSurface* surface, bool useGpu) {
+#if SK_SUPPORT_GPU
+    if (useGpu) {
+        return surface->getCanvas()->internal_private_accessTopLayerRenderTarget()->asTexture();
+    } else
+#endif
+    {
+        return surface->peekPixels(NULL, NULL);
+    }
 }
 
 static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFactory* factory) {
@@ -715,7 +704,7 @@
 
     SkImage* image1 = canvas->newImageSnapshot();
     SkAutoTUnref<SkImage> aur_i1(image1);
-    PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu);
+    PixelPtr pixels1 = get_surface_ptr(surface, useGpu);
     // The following clear would normally trigger a copy on write, but
     // it won't because rendering is deferred.
     canvas->clear(SK_ColorBLACK);
@@ -733,7 +722,7 @@
     REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID());
     // Verify that backing store is now a different buffer because of copy on
     // write
-    PixelPtr pixels2 = getSurfacePixelPtr(surface, useGpu);
+    PixelPtr pixels2 = get_surface_ptr(surface, useGpu);
     REPORTER_ASSERT(reporter, pixels1 != pixels2);
     // Verify copy-on write with a draw operation that gets deferred by
     // the in order draw buffer.
@@ -742,17 +731,17 @@
     SkImage* image4 = canvas->newImageSnapshot();  // implicit flush
     SkAutoTUnref<SkImage> aur_i4(image4);
     REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID());
-    PixelPtr pixels3 = getSurfacePixelPtr(surface, useGpu);
+    PixelPtr pixels3 = get_surface_ptr(surface, useGpu);
     REPORTER_ASSERT(reporter, pixels2 != pixels3);
     // Verify that a direct canvas flush with a pending draw does not trigger
     // a copy on write when the surface is not sharing its buffer with an
     // SkImage.
     canvas->clear(SK_ColorWHITE);
     canvas->flush();
-    PixelPtr pixels4 = getSurfacePixelPtr(surface, useGpu);
+    PixelPtr pixels4 = get_surface_ptr(surface, useGpu);
     canvas->drawPaint(paint);
     canvas->flush();
-    PixelPtr pixels5 = getSurfacePixelPtr(surface, useGpu);
+    PixelPtr pixels5 = get_surface_ptr(surface, useGpu);
     REPORTER_ASSERT(reporter, pixels4 == pixels5);
 }
 
@@ -782,21 +771,21 @@
     SkASSERT(NULL != alternateSurface);
     SkAutoTUnref<SkSurface> aur1(surface);
     SkAutoTUnref<SkSurface> aur2(alternateSurface);
-    PixelPtr pixels1 = getSurfacePixelPtr(surface, useGpu);
-    PixelPtr pixels2 = getSurfacePixelPtr(alternateSurface, useGpu);
+    PixelPtr pixels1 = get_surface_ptr(surface, useGpu);
+    PixelPtr pixels2 = get_surface_ptr(alternateSurface, useGpu);
     SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface));
     SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot());
     canvas->setSurface(alternateSurface);
     SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot());
     REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID());
     // Verify that none of the above operations triggered a surface copy on write.
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1);
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) == pixels2);
+    REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1);
+    REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) == pixels2);
     // Verify that a flushed draw command will trigger a copy on write on alternateSurface.
     canvas->clear(SK_ColorWHITE);
     canvas->flush();
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(surface, useGpu) == pixels1);
-    REPORTER_ASSERT(reporter, getSurfacePixelPtr(alternateSurface, useGpu) != pixels2);
+    REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1);
+    REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) != pixels2);
 }
 
 static void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporter) {
@@ -821,7 +810,6 @@
 }
 
 DEF_TEST(DeferredCanvas_CPU, reporter) {
-    TestDeferredCanvasBitmapAccess(reporter);
     TestDeferredCanvasFlush(reporter);
     TestDeferredCanvasSilentFlush(reporter);
     TestDeferredCanvasFreshFrame(reporter);
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index 3e22f7c..d0bf903 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -10,6 +10,7 @@
 #include "SkColorPriv.h"
 #include "SkMathPriv.h"
 #include "SkRegion.h"
+#include "SkSurface.h"
 #include "Test.h"
 
 #if SK_SUPPORT_GPU
@@ -297,11 +298,11 @@
             glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt;
         }
 #endif
+        const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
         for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) {
-            SkAutoTUnref<SkBaseDevice> device;
+            SkAutoTUnref<SkSurface> surface;
             if (0 == dtype) {
-                SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
-                device.reset(SkBitmapDevice::Create(info));
+                surface.reset(SkSurface::NewRaster(info));
             } else {
 #if SK_SUPPORT_GPU
                 GrContextFactory::GLContextType type =
@@ -318,16 +319,15 @@
                 desc.fWidth = DEV_W;
                 desc.fHeight = DEV_H;
                 desc.fConfig = kSkia8888_GrPixelConfig;
-                desc.fOrigin = 1 == dtype ? kBottomLeft_GrSurfaceOrigin
-                                          : kTopLeft_GrSurfaceOrigin;
+                desc.fOrigin = 1 == dtype ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
                 GrAutoScratchTexture ast(context, desc, GrContext::kExact_ScratchTexMatch);
                 SkAutoTUnref<GrTexture> tex(ast.detach());
-                device.reset(new SkGpuDevice(context, tex));
+                surface.reset(SkSurface::NewRenderTargetDirect(tex->asRenderTarget()));
 #else
                 continue;
 #endif
             }
-            SkCanvas canvas(device);
+            SkCanvas& canvas = *surface->getCanvas();
             fillCanvas(&canvas);
 
             static const struct {
@@ -353,9 +353,9 @@
                         if (startsWithPixels) {
                             fillBitmap(&bmp);
                         }
-                        uint32_t idBefore = canvas.getDevice()->accessBitmap(false).getGenerationID();
+                        uint32_t idBefore = surface->generationID();
                         bool success = canvas.readPixels(&bmp, srcRect.fLeft, srcRect.fTop);
-                        uint32_t idAfter = canvas.getDevice()->accessBitmap(false).getGenerationID();
+                        uint32_t idAfter = surface->generationID();
 
                         // we expect to succeed when the read isn't fully clipped
                         // out.
diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp
index 70b91f2..2a8d059 100644
--- a/tests/WritePixelsTest.cpp
+++ b/tests/WritePixelsTest.cpp
@@ -186,9 +186,9 @@
            SkAbs32(aB - bB) <= 1;
 }
 
-static bool checkWrite(skiatest::Reporter* reporter, SkCanvas* canvas, const SkBitmap& bitmap,
+static bool check_write(skiatest::Reporter* reporter, SkCanvas* canvas, const SkBitmap& bitmap,
                        int writeX, int writeY) {
-    SkImageInfo canvasInfo;
+    const SkImageInfo canvasInfo = canvas->imageInfo();
     size_t canvasRowBytes;
     const uint32_t* canvasPixels;
 
@@ -196,15 +196,9 @@
     // At some point this will be unsupported, as we won't allow accessBitmap() to magically call
     // readPixels for the client.
     SkBitmap secretDevBitmap;
-    {
-        SkBaseDevice* dev = canvas->getDevice();
-        if (!dev) {
-            return false;
-        }
-        secretDevBitmap = dev->accessBitmap(false);
-    }
+    canvas->readPixels(SkIRect::MakeWH(canvasInfo.width(), canvasInfo.height()), &secretDevBitmap);
+
     SkAutoLockPixels alp(secretDevBitmap);
-    canvasInfo = secretDevBitmap.info();
     canvasRowBytes = secretDevBitmap.rowBytes();
     canvasPixels = static_cast<const uint32_t*>(secretDevBitmap.getPixels());
 
@@ -299,25 +293,22 @@
     return true;
 }
 
-static SkBaseDevice* createDevice(const CanvasConfig& c, GrContext* grCtx) {
+static void free_pixels(void* pixels, void* ctx) {
+    sk_free(pixels);
+}
+
+static SkSurface* create_surface(const CanvasConfig& c, GrContext* grCtx) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
     switch (c.fDevType) {
         case kRaster_DevType: {
-            SkBitmap bmp;
-            size_t rowBytes = c.fTightRowBytes ? 0 : 4 * DEV_W + 100;
-            SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H);
-            if (!allocRowBytes(&bmp, info, rowBytes)) {
-                sk_throw();
-                return NULL;
-            }
+            const size_t rowBytes = c.fTightRowBytes ? info.minRowBytes() : 4 * DEV_W + 100;
+            const size_t size = info.getSafeSize(rowBytes);
+            void* pixels = sk_malloc_throw(size);
             // if rowBytes isn't tight then set the padding to a known value
-            if (rowBytes) {
-                SkAutoLockPixels alp(bmp);
-                // We'd just use memset here but GCC 4.8.1 throws up a bogus warning when we do.
-                for (size_t i = 0; i < bmp.getSafeSize(); i++) {
-                    ((uint8_t*)bmp.getPixels())[i] = DEV_PAD;
-                }
+            if (!c.fTightRowBytes) {
+                memset(pixels, DEV_PAD, size);
             }
-            return new SkBitmapDevice(bmp);
+            return SkSurface::NewRasterDirectReleaseProc(info, pixels, rowBytes, free_pixels, NULL);
         }
 #if SK_SUPPORT_GPU
         case kGpu_BottomLeft_DevType:
@@ -331,13 +322,13 @@
                 kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
             GrAutoScratchTexture ast(grCtx, desc, GrContext::kExact_ScratchTexMatch);
             SkAutoTUnref<GrTexture> tex(ast.detach());
-            return new SkGpuDevice(grCtx, tex);
+            return SkSurface::NewRenderTargetDirect(tex->asRenderTarget());
 #endif
     }
     return NULL;
 }
 
-static bool setupBitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, int h, int tightRB) {
+static bool setup_bitmap(SkBitmap* bm, SkColorType ct, SkAlphaType at, int w, int h, int tightRB) {
     size_t rowBytes = tightRB ? 0 : 4 * w + 60;
     SkImageInfo info = SkImageInfo::Make(w, h, ct, at);
     if (!allocRowBytes(bm, info, rowBytes)) {
@@ -444,8 +435,8 @@
             }
 #endif
 
-            SkAutoTUnref<SkBaseDevice> device(createDevice(gCanvasConfigs[i], context));
-            SkCanvas canvas(device);
+            SkAutoTUnref<SkSurface> surface(create_surface(gCanvasConfigs[i], context));
+            SkCanvas& canvas = *surface->getCanvas();
 
             static const struct {
                 SkColorType fColorType;
@@ -465,15 +456,16 @@
 
                         fillCanvas(&canvas);
                         SkBitmap bmp;
-                        REPORTER_ASSERT(reporter, setupBitmap(&bmp, ct, at, rect.width(),
-                                                              rect.height(), SkToBool(tightBmp)));
-                        uint32_t idBefore = canvas.getDevice()->accessBitmap(false).getGenerationID();
+                        REPORTER_ASSERT(reporter, setup_bitmap(&bmp, ct, at, rect.width(),
+                                                               rect.height(), SkToBool(tightBmp)));
+                        uint32_t idBefore = surface->generationID();
 
                        // sk_tool_utils::write_pixels(&canvas, bmp, rect.fLeft, rect.fTop, ct, at);
                         canvas.writePixels(bmp, rect.fLeft, rect.fTop);
 
-                        uint32_t idAfter = canvas.getDevice()->accessBitmap(false).getGenerationID();
-                        REPORTER_ASSERT(reporter, checkWrite(reporter, &canvas, bmp, rect.fLeft, rect.fTop));
+                        uint32_t idAfter = surface->generationID();
+                        REPORTER_ASSERT(reporter, check_write(reporter, &canvas, bmp,
+                                                              rect.fLeft, rect.fTop));
 
                         // we should change the genID iff pixels were actually written.
                         SkIRect canvasRect = SkIRect::MakeSize(canvas.getDeviceSize());
diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp
index ebd33d8..b5534f0 100644
--- a/tools/CopyTilesRenderer.cpp
+++ b/tools/CopyTilesRenderer.cpp
@@ -57,7 +57,8 @@
                 // Draw the picture
                 fCanvas->drawPicture(fPicture);
                 // Now extract the picture into tiles
-                const SkBitmap& baseBitmap = fCanvas->getDevice()->accessBitmap(false);
+                SkBitmap baseBitmap;
+                fCanvas->readPixels(SkIRect::MakeSize(fCanvas->getBaseLayerSize()), &baseBitmap);
                 SkIRect subset;
                 for (int tileY = 0; tileY < fLargeTileHeight; tileY += this->getTileHeight()) {
                     for (int tileX = 0; tileX < fLargeTileWidth; tileX += this->getTileWidth()) {