Split SkDevice into SkBaseDevice and SkBitmapDevice

https://codereview.chromium.org/22978012/



git-svn-id: http://skia.googlecode.com/svn/trunk@10995 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h
index b97e87b..a288f8a 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -11,6 +11,285 @@
 
 #include "SkDevice.h"
 
-typedef SkDevice SkBitmapDevice;
+///////////////////////////////////////////////////////////////////////////////
+class SK_API SkBitmapDevice : public SkBaseDevice {
+public:
+    SK_DECLARE_INST_COUNT(SkBitmapDevice)
+
+    /**
+     *  Construct a new device with the specified bitmap as its backend. It is
+     *  valid for the bitmap to have no pixels associated with it. In that case,
+     *  any drawing to this device will have no effect.
+    */
+    SkBitmapDevice(const SkBitmap& bitmap);
+
+    /**
+     *  Construct a new device with the specified bitmap as its backend. It is
+     *  valid for the bitmap to have no pixels associated with it. In that case,
+     *  any drawing to this device will have no effect.
+    */
+    SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties);
+
+    /**
+     *  Create a new raster device and have the pixels be automatically
+     *  allocated. The rowBytes of the device will be computed automatically
+     *  based on the config and the width.
+     *
+     *  @param config   The desired config for the pixels. If the request cannot
+     *                  be met, the closest matching support config will be used.
+     *  @param width    width (in pixels) of the device
+     *  @param height   height (in pixels) of the device
+     *  @param isOpaque Set to true if it is known that all of the pixels will
+     *                  be drawn to opaquely. Used as an accelerator when drawing
+     *                  these pixels to another device.
+     */
+    SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false);
+
+    /**
+     *  Create a new raster device and have the pixels be automatically
+     *  allocated. The rowBytes of the device will be computed automatically
+     *  based on the config and the width.
+     *
+     *  @param config   The desired config for the pixels. If the request cannot
+     *                  be met, the closest matching support config will be used.
+     *  @param width    width (in pixels) of the device
+     *  @param height   height (in pixels) of the device
+     *  @param isOpaque Set to true if it is known that all of the pixels will
+     *                  be drawn to opaquely. Used as an accelerator when drawing
+     *                  these pixels to another device.
+     *  @param deviceProperties Properties which affect compositing.
+     */
+    SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
+                   const SkDeviceProperties& deviceProperties);
+
+    virtual ~SkBitmapDevice();
+
+    virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; }
+
+    /** Return the width of the device (in pixels).
+    */
+    virtual int width() const SK_OVERRIDE { return fBitmap.width(); }
+    /** Return the height of the device (in pixels).
+    */
+    virtual int height() const SK_OVERRIDE { return fBitmap.height(); }
+
+    /**
+     *  Return the bounds of the device in the coordinate space of the root
+     *  canvas. The root device will have its top-left at 0,0, but other devices
+     *  such as those associated with saveLayer may have a non-zero origin.
+     */
+    virtual void getGlobalBounds(SkIRect* bounds) const SK_OVERRIDE;
+
+    /** Returns true if the device's bitmap's config treats every pixels as
+        implicitly opaque.
+    */
+    virtual bool isOpaque() const SK_OVERRIDE { return fBitmap.isOpaque(); }
+
+    /** Return the bitmap config of the device's pixels
+    */
+    virtual SkBitmap::Config config() const SK_OVERRIDE { return fBitmap.getConfig(); }
+
+    /**
+     *  DEPRECATED: This will be made protected once WebKit stops using it.
+     *              Instead use Canvas' writePixels method.
+     *
+     *  Similar to draw sprite, this method will copy the pixels in bitmap onto
+     *  the device, with the top/left corner specified by (x, y). The pixel
+     *  values in the device are completely replaced: there is no blending.
+     *
+     *  Currently if bitmap is backed by a texture this is a no-op. This may be
+     *  relaxed in the future.
+     *
+     *  If the bitmap has config kARGB_8888_Config then the config8888 param
+     *  will determines how the pixel valuess are intepreted. If the bitmap is
+     *  not kARGB_8888_Config then this parameter is ignored.
+     */
+    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
+                             SkCanvas::Config8888 config8888) SK_OVERRIDE;
+
+    /**
+     * Return the device's associated gpu render target, or NULL.
+     */
+    virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
+
+protected:
+    /**
+     *  Device may filter the text flags for drawing text here. If it wants to
+     *  make a change to the specified values, it should write them into the
+     *  textflags parameter (output) and return true. If the paint is fine as
+     *  is, then ignore the textflags parameter and return false.
+     *
+     *  The baseclass SkDevice filters based on its depth and blitters.
+     */
+    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE;
+
+    /** Clears the entire device to the specified color (including alpha).
+     *  Ignores the clip.
+     */
+    virtual void clear(SkColor color) SK_OVERRIDE;
+
+    /** These are called inside the per-device-layer loop for each draw call.
+     When these are called, we have already applied any saveLayer operations,
+     and are handling any looping from the paint, and any effects from the
+     DrawFilter.
+     */
+    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+                            const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawRect(const SkDraw&, const SkRect& r,
+                          const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawOval(const SkDraw&, const SkRect& oval,
+                          const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawRRect(const SkDraw&, const SkRRect& rr,
+                           const SkPaint& paint) SK_OVERRIDE;
+
+    /**
+     *  If pathIsMutable, then the implementation is allowed to cast path to a
+     *  non-const pointer and modify it in place (as an optimization). Canvas
+     *  may do this to implement helpers such as drawOval, by placing a temp
+     *  path on the stack to hold the representation of the oval.
+     *
+     *  If prePathMatrix is not null, it should logically be applied before any
+     *  stroking or other effects. If there are no effects on the paint that
+     *  affect the geometry/rasterization, then the pre matrix can just be
+     *  pre-concated with the current matrix.
+     */
+    virtual void drawPath(const SkDraw&, const SkPath& path,
+                          const SkPaint& paint,
+                          const SkMatrix* prePathMatrix = NULL,
+                          bool pathIsMutable = false) SK_OVERRIDE;
+    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+                            const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+                            int x, int y, const SkPaint& paint) SK_OVERRIDE;
+
+    /**
+     *  The default impl. will create a bitmap-shader from the bitmap,
+     *  and call drawRect with it.
+     */
+    virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
+                                const SkRect* srcOrNull, const SkRect& dst,
+                                const SkPaint& paint,
+                                SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE;
+
+    /**
+     *  Does not handle text decoration.
+     *  Decorations (underline and stike-thru) will be handled by SkCanvas.
+     */
+    virtual void drawText(const SkDraw&, const void* text, size_t len,
+                          SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+                             const SkScalar pos[], SkScalar constY,
+                             int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE;
+    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+                                const SkPath& path, const SkMatrix* matrix,
+                                const SkPaint& paint) SK_OVERRIDE;
+#ifdef SK_BUILD_FOR_ANDROID
+    virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
+                                   const SkPoint pos[], const SkPaint& paint,
+                                   const SkPath& path, const SkMatrix* matrix) SK_OVERRIDE;
+#endif
+    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+                              const SkPoint verts[], const SkPoint texs[],
+                              const SkColor colors[], SkXfermode* xmode,
+                              const uint16_t indices[], int indexCount,
+                              const SkPaint& paint) SK_OVERRIDE;
+    /** The SkBaseDevice passed will be an SkBaseDevice which was returned by a call to
+        onCreateCompatibleDevice on this device with kSaveLayer_Usage.
+     */
+    virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+                            const SkPaint&) SK_OVERRIDE;
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** Update as needed the pixel value in the bitmap, so that the caller can
+        access the pixels directly. Note: only the pixels field should be
+        altered. The config/width/height/rowbytes must remain unchanged.
+        @return the device contents as a bitmap
+    */
+    virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE;
+
+    SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
+    // just for subclasses, to assign a custom pixelref
+    SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
+        fBitmap.setPixelRef(pr, offset);
+        return pr;
+    }
+
+    /**
+     * Implements readPixels API. The caller will ensure that:
+     *  1. bitmap has pixel config kARGB_8888_Config.
+     *  2. bitmap has pixels.
+     *  3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is
+     *     contained in the device bounds.
+     */
+    virtual bool onReadPixels(const SkBitmap& bitmap,
+                              int x, int y,
+                              SkCanvas::Config8888 config8888) SK_OVERRIDE;
+
+    /** Called when this device is installed into a Canvas. Balanced by a call
+        to unlockPixels() when the device is removed from a Canvas.
+    */
+    virtual void lockPixels() SK_OVERRIDE;
+    virtual void unlockPixels() SK_OVERRIDE;
+
+    /**
+     *  Returns true if the device allows processing of this imagefilter. If
+     *  false is returned, then the filter is ignored. This may happen for
+     *  some subclasses that do not support pixel manipulations after drawing
+     *  has occurred (e.g. printing). The default implementation returns true.
+     */
+    virtual bool allowImageFilter(SkImageFilter*) SK_OVERRIDE;
+
+    /**
+     *  Override and return true for filters that the device can handle
+     *  intrinsically. Doing so means that SkCanvas will pass-through this
+     *  filter to drawSprite and drawDevice (and potentially filterImage).
+     *  Returning false means the SkCanvas will have apply the filter itself,
+     *  and just pass the resulting image to the device.
+     */
+    virtual bool canHandleImageFilter(SkImageFilter*) SK_OVERRIDE;
+
+    /**
+     *  Related (but not required) to canHandleImageFilter, this method returns
+     *  true if the device could apply the filter to the src bitmap and return
+     *  the result (and updates offset as needed).
+     *  If the device does not recognize or support this filter,
+     *  it just returns false and leaves result and offset unchanged.
+     */
+    virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&,
+                             SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
+
+private:
+    friend class SkCanvas;
+    friend struct DeviceCM; //for setMatrixClip
+    friend class SkDraw;
+    friend class SkDrawIter;
+    friend class SkDeviceFilteredPaint;
+    friend class SkDeviceImageFilterProxy;
+
+    friend class SkSurface_Raster;
+
+    // used to change the backend's pixels (and possibly config/rowbytes)
+    // but cannot change the width/height, so there should be no change to
+    // any clip information.
+    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE;
+
+    /**
+     * Subclasses should override this to implement createCompatibleDevice.
+     */
+    virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+                                                   int width, int height,
+                                                   bool isOpaque,
+                                                   Usage usage) SK_OVERRIDE;
+
+    /** Causes any deferred drawing to the device to be completed.
+     */
+    virtual void flush() SK_OVERRIDE {}
+
+    SkBitmap    fBitmap;
+
+    typedef SkBaseDevice INHERITED;
+};
 
 #endif // SkBitmapDevice_DEFINED
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 827ebe8..cfc252f 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -22,7 +22,7 @@
 #include "SkXfermode.h"
 
 class SkBounder;
-class SkDevice;
+class SkBaseDevice;
 class SkDraw;
 class SkDrawFilter;
 class SkMetaData;
@@ -55,7 +55,7 @@
 
         @param device   Specifies a device for the canvas to draw into.
     */
-    explicit SkCanvas(SkDevice* device);
+    explicit SkCanvas(SkBaseDevice* device);
 
     /** Deprecated - Construct a canvas with the specified bitmap to draw into.
         @param bitmap   Specifies a bitmap for the canvas to draw into. Its
@@ -84,7 +84,7 @@
         the bitmap of the pixels that the canvas draws into. The reference count
         of the returned device is not changed by this call.
     */
-    SkDevice* getDevice() const;
+    SkBaseDevice* getDevice() const;
 
     /**
      *  saveLayer() can create another device (which is later drawn onto
@@ -99,15 +99,15 @@
      *        is drawn to, but is optional here, as there is a small perf hit
      *        sometimes.
      */
-    SkDevice* getTopDevice(bool updateMatrixClip = false) const;
+    SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const;
 
     /**
      *  Shortcut for getDevice()->createCompatibleDevice(...).
      *  If getDevice() == NULL, this method does nothing, and returns NULL.
      */
-    SkDevice* createCompatibleDevice(SkBitmap::Config config,
-                                    int width, int height,
-                                    bool isOpaque);
+    SkBaseDevice* createCompatibleDevice(SkBitmap::Config config,
+                                         int width, int height,
+                                         bool isOpaque);
 
     ///////////////////////////////////////////////////////////////////////////
 
@@ -994,7 +994,7 @@
 
         // These reflect the current device in the iterator
 
-        SkDevice*       device() const;
+        SkBaseDevice*   device() const;
         const SkMatrix& matrix() const;
         const SkRegion& clip() const;
         const SkPaint&  paint() const;
@@ -1043,7 +1043,7 @@
      reference count is incremented. If the canvas was already holding a
      device, its reference count is decremented. The new device is returned.
      */
-    virtual SkDevice* setDevice(SkDevice* device);
+    virtual SkBaseDevice* setDevice(SkBaseDevice* device);
 
 private:
     class MCRec;
@@ -1074,10 +1074,10 @@
     friend class SkDrawIter;    // needs setupDrawForLayerDevice()
     friend class AutoDrawLooper;
 
-    SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
-                                bool isOpaque);
+    SkBaseDevice* createLayerDevice(SkBitmap::Config, int width, int height,
+                                    bool isOpaque);
 
-    SkDevice* init(SkDevice*);
+    SkBaseDevice* init(SkBaseDevice*);
 
     // internal methods are not virtual, so they can safely be called by other
     // canvas apis, without confusing subclasses (like SkPictureRecording)
@@ -1090,7 +1090,7 @@
     void internalDrawPaint(const SkPaint& paint);
     int internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
                           SaveFlags, bool justForImageFilter);
-    void internalDrawDevice(SkDevice*, int x, int y, const SkPaint*);
+    void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
 
     // shared by save() and saveLayer()
     int internalSave(SaveFlags flags);
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 990e833..1f10424 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -25,57 +25,21 @@
 
 class GrRenderTarget;
 
-class SK_API SkDevice : public SkRefCnt {
+class SK_API SkBaseDevice : public SkRefCnt {
 public:
-    SK_DECLARE_INST_COUNT(SkDevice)
+    SK_DECLARE_INST_COUNT(SkBaseDevice)
 
     /**
-     *  Construct a new device with the specified bitmap as its backend. It is
-     *  valid for the bitmap to have no pixels associated with it. In that case,
-     *  any drawing to this device will have no effect.
+     *  Construct a new device.
     */
-    SkDevice(const SkBitmap& bitmap);
+    SkBaseDevice();
 
     /**
-     *  Construct a new device with the specified bitmap as its backend. It is
-     *  valid for the bitmap to have no pixels associated with it. In that case,
-     *  any drawing to this device will have no effect.
+     *  Construct a new device.
     */
-    SkDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties);
+    SkBaseDevice(const SkDeviceProperties& deviceProperties);
 
-    /**
-     *  Create a new raster device and have the pixels be automatically
-     *  allocated. The rowBytes of the device will be computed automatically
-     *  based on the config and the width.
-     *
-     *  @param config   The desired config for the pixels. If the request cannot
-     *                  be met, the closest matching support config will be used.
-     *  @param width    width (in pixels) of the device
-     *  @param height   height (in pixels) of the device
-     *  @param isOpaque Set to true if it is known that all of the pixels will
-     *                  be drawn to opaquely. Used as an accelerator when drawing
-     *                  these pixels to another device.
-     */
-    SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false);
-
-    /**
-     *  Create a new raster device and have the pixels be automatically
-     *  allocated. The rowBytes of the device will be computed automatically
-     *  based on the config and the width.
-     *
-     *  @param config   The desired config for the pixels. If the request cannot
-     *                  be met, the closest matching support config will be used.
-     *  @param width    width (in pixels) of the device
-     *  @param height   height (in pixels) of the device
-     *  @param isOpaque Set to true if it is known that all of the pixels will
-     *                  be drawn to opaquely. Used as an accelerator when drawing
-     *                  these pixels to another device.
-     *  @param deviceProperties Properties which affect compositing.
-     */
-    SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
-             const SkDeviceProperties& deviceProperties);
-
-    virtual ~SkDevice();
+    virtual ~SkBaseDevice();
 
     /**
      *  Creates a device that is of the same type as this device (e.g. SW-raster,
@@ -88,9 +52,9 @@
      *                  draw into this device such that all of the pixels will
      *                  be opaque.
      */
-    SkDevice* createCompatibleDevice(SkBitmap::Config config,
-                                     int width, int height,
-                                     bool isOpaque);
+    SkBaseDevice* createCompatibleDevice(SkBitmap::Config config,
+                                         int width, int height,
+                                         bool isOpaque);
 
     SkMetaData& getMetaData();
 
@@ -99,14 +63,14 @@
         kVector_Capability = 0x2,  //!< mask indicating a vector representation
         kAll_Capabilities  = 0x3
     };
-    virtual uint32_t getDeviceCapabilities() { return 0; }
+    virtual uint32_t getDeviceCapabilities() = 0;
 
     /** Return the width of the device (in pixels).
     */
-    virtual int width() const { return fBitmap.width(); }
+    virtual int width() const = 0;
     /** Return the height of the device (in pixels).
     */
-    virtual int height() const { return fBitmap.height(); }
+    virtual int height() const = 0;
 
     /** Return the image properties of the device. */
     virtual const SkDeviceProperties& getDeviceProperties() const {
@@ -119,16 +83,16 @@
      *  canvas. The root device will have its top-left at 0,0, but other devices
      *  such as those associated with saveLayer may have a non-zero origin.
      */
-    void getGlobalBounds(SkIRect* bounds) const;
+    virtual void getGlobalBounds(SkIRect* bounds) const = 0;
 
     /** Returns true if the device's bitmap's config treats every pixels as
         implicitly opaque.
     */
-    bool isOpaque() const { return fBitmap.isOpaque(); }
-
-    /** Return the bitmap config of the device's pixels
-    */
-    SkBitmap::Config config() const { return fBitmap.getConfig(); }
+    virtual bool isOpaque() const = 0;
+    
+    /** DEPRECATED - Return the bitmap config of the device's pixels
+     */
+    virtual SkBitmap::Config config() const = 0;
 
     /** Return the bitmap associated with this device. Call this each time you need
         to access the bitmap, as it notifies the subclass to perform any flushing
@@ -154,12 +118,12 @@
      *  not kARGB_8888_Config then this parameter is ignored.
      */
     virtual void writePixels(const SkBitmap& bitmap, int x, int y,
-                             SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888);
+                             SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888) = 0;
 
     /**
      * Return the device's associated gpu render target, or NULL.
      */
-    virtual GrRenderTarget* accessRenderTarget() { return NULL; }
+    virtual GrRenderTarget* accessRenderTarget() = 0;
 
 
     /**
@@ -171,7 +135,7 @@
     /**
      * onAttachToCanvas is invoked whenever a device is installed in a canvas
      * (i.e., setDevice, saveLayer (for the new device created by the save),
-     * and SkCanvas' SkDevice & SkBitmap -taking ctors). It allows the
+     * and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the
      * devices to prepare for drawing (e.g., locking their pixels, etc.)
      */
     virtual void onAttachToCanvas(SkCanvas*) {
@@ -213,9 +177,9 @@
      *  textflags parameter (output) and return true. If the paint is fine as
      *  is, then ignore the textflags parameter and return false.
      *
-     *  The baseclass SkDevice filters based on its depth and blitters.
+     *  The baseclass SkBaseDevice filters based on its depth and blitters.
      */
-    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
+    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0;
 
     /**
      *
@@ -234,12 +198,12 @@
      *  passed in).
      */
      virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
-                                const SkClipStack&);
+                                const SkClipStack&) {};
 
     /** Clears the entire device to the specified color (including alpha).
      *  Ignores the clip.
      */
-    virtual void clear(SkColor color);
+    virtual void clear(SkColor color) = 0;
 
     /**
      * Deprecated name for clear.
@@ -251,15 +215,15 @@
      and are handling any looping from the paint, and any effects from the
      DrawFilter.
      */
-    virtual void drawPaint(const SkDraw&, const SkPaint& paint);
+    virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
     virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
-                            const SkPoint[], const SkPaint& paint);
+                            const SkPoint[], const SkPaint& paint) = 0;
     virtual void drawRect(const SkDraw&, const SkRect& r,
-                          const SkPaint& paint);
+                          const SkPaint& paint) = 0;
     virtual void drawOval(const SkDraw&, const SkRect& oval,
-                          const SkPaint& paint);
+                          const SkPaint& paint) = 0;
     virtual void drawRRect(const SkDraw&, const SkRRect& rr,
-                           const SkPaint& paint);
+                           const SkPaint& paint) = 0;
 
     /**
      *  If pathIsMutable, then the implementation is allowed to cast path to a
@@ -275,11 +239,11 @@
     virtual void drawPath(const SkDraw&, const SkPath& path,
                           const SkPaint& paint,
                           const SkMatrix* prePathMatrix = NULL,
-                          bool pathIsMutable = false);
+                          bool pathIsMutable = false) = 0;
     virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
-                            const SkMatrix& matrix, const SkPaint& paint);
+                            const SkMatrix& matrix, const SkPaint& paint) = 0;
     virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
-                            int x, int y, const SkPaint& paint);
+                            int x, int y, const SkPaint& paint) = 0;
 
     /**
      *  The default impl. will create a bitmap-shader from the bitmap,
@@ -288,35 +252,35 @@
     virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
                                 const SkRect* srcOrNull, const SkRect& dst,
                                 const SkPaint& paint,
-                                SkCanvas::DrawBitmapRectFlags flags);
+                                SkCanvas::DrawBitmapRectFlags flags) = 0;
 
     /**
      *  Does not handle text decoration.
      *  Decorations (underline and stike-thru) will be handled by SkCanvas.
      */
     virtual void drawText(const SkDraw&, const void* text, size_t len,
-                          SkScalar x, SkScalar y, const SkPaint& paint);
+                          SkScalar x, SkScalar y, const SkPaint& paint) = 0;
     virtual void drawPosText(const SkDraw&, const void* text, size_t len,
                              const SkScalar pos[], SkScalar constY,
-                             int scalarsPerPos, const SkPaint& paint);
+                             int scalarsPerPos, const SkPaint& paint) = 0;
     virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
                                 const SkPath& path, const SkMatrix* matrix,
-                                const SkPaint& paint);
+                                const SkPaint& paint) = 0;
 #ifdef SK_BUILD_FOR_ANDROID
     virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
                                    const SkPoint pos[], const SkPaint& paint,
-                                   const SkPath& path, const SkMatrix* matrix);
+                                   const SkPath& path, const SkMatrix* matrix) = 0;
 #endif
     virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
                               const SkPoint verts[], const SkPoint texs[],
                               const SkColor colors[], SkXfermode* xmode,
                               const uint16_t indices[], int indexCount,
-                              const SkPaint& paint);
+                              const SkPaint& paint) = 0;
     /** The SkDevice passed will be an SkDevice which was returned by a call to
         onCreateCompatibleDevice on this device with kSaveLayer_Usage.
      */
-    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
-                            const SkPaint&);
+    virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+                            const SkPaint&) = 0;
 
     /**
      *  On success (returns true), copy the device pixels into the bitmap.
@@ -352,20 +316,10 @@
     ///////////////////////////////////////////////////////////////////////////
 
     /** Update as needed the pixel value in the bitmap, so that the caller can
-        access the pixels directly. Note: only the pixels field should be
-        altered. The config/width/height/rowbytes must remain unchanged.
-        @param bitmap The device's bitmap
-        @return Echo the bitmap parameter, or an alternate (shadow) bitmap
-            maintained by the subclass.
+        access the pixels directly. 
+        @return The device contents as a bitmap
     */
-    virtual const SkBitmap& onAccessBitmap(SkBitmap*);
-
-    SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
-    // just for subclasses, to assign a custom pixelref
-    SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
-        fBitmap.setPixelRef(pr, offset);
-        return pr;
-    }
+    virtual const SkBitmap& onAccessBitmap() = 0;
 
     /**
      * Implements readPixels API. The caller will ensure that:
@@ -376,13 +330,13 @@
      */
     virtual bool onReadPixels(const SkBitmap& bitmap,
                               int x, int y,
-                              SkCanvas::Config8888 config8888);
+                              SkCanvas::Config8888 config8888) = 0;
 
     /** Called when this device is installed into a Canvas. Balanaced by a call
         to unlockPixels() when the device is removed from a Canvas.
     */
-    virtual void lockPixels();
-    virtual void unlockPixels();
+    virtual void lockPixels() = 0;
+    virtual void unlockPixels() = 0;
 
     /**
      *  Returns true if the device allows processing of this imagefilter. If
@@ -390,7 +344,7 @@
      *  some subclasses that do not support pixel manipulations after drawing
      *  has occurred (e.g. printing). The default implementation returns true.
      */
-    virtual bool allowImageFilter(SkImageFilter*);
+    virtual bool allowImageFilter(SkImageFilter*) = 0;
 
     /**
      *  Override and return true for filters that the device can handle
@@ -399,7 +353,7 @@
      *  Returning false means the SkCanvas will have apply the filter itself,
      *  and just pass the resulting image to the device.
      */
-    virtual bool canHandleImageFilter(SkImageFilter*);
+    virtual bool canHandleImageFilter(SkImageFilter*) = 0;
 
     /**
      *  Related (but not required) to canHandleImageFilter, this method returns
@@ -409,7 +363,7 @@
      *  it just returns false and leaves result and offset unchanged.
      */
     virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&,
-                             SkBitmap* result, SkIPoint* offset);
+                             SkBitmap* result, SkIPoint* offset) = 0;
 
     // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if
     // either is identical to kNative_Premul_Config8888. Otherwise, -1.
@@ -424,31 +378,31 @@
     friend class SkDeviceImageFilterProxy;
 
     friend class SkSurface_Raster;
+
     // used to change the backend's pixels (and possibly config/rowbytes)
     // but cannot change the width/height, so there should be no change to
     // any clip information.
-    void replaceBitmapBackendForRasterSurface(const SkBitmap&);
+    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0;
 
     // just called by SkCanvas when built as a layer
     void setOrigin(int x, int y) { fOrigin.set(x, y); }
     // just called by SkCanvas for saveLayer
-    SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
-                                                 int width, int height,
-                                                 bool isOpaque);
+    SkBaseDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
+                                                     int width, int height,
+                                                     bool isOpaque);
 
     /**
      * Subclasses should override this to implement createCompatibleDevice.
      */
-    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
-                                               int width, int height,
-                                               bool isOpaque,
-                                               Usage usage);
+    virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config,
+                                                   int width, int height,
+                                                   bool isOpaque,
+                                                   Usage usage) = 0;
 
     /** Causes any deferred drawing to the device to be completed.
      */
-    virtual void flush() {}
+    virtual void flush() = 0;
 
-    SkBitmap    fBitmap;
     SkIPoint    fOrigin;
     SkMetaData* fMetaData;
     /**
@@ -466,6 +420,4 @@
     typedef SkRefCnt INHERITED;
 };
 
-typedef SkDevice SkBaseDevice;
-
 #endif
diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h
index 8642f0a..1c2c66e 100644
--- a/include/core/SkDraw.h
+++ b/include/core/SkDraw.h
@@ -17,7 +17,7 @@
 class SkBitmap;
 class SkBounder;
 class SkClipStack;
-class SkDevice;
+class SkBaseDevice;
 class SkMatrix;
 class SkPath;
 class SkRegion;
@@ -127,7 +127,7 @@
     const SkRasterClip* fRC;        // required
 
     const SkClipStack* fClipStack;  // optional
-    SkDevice*       fDevice;        // optional
+    SkBaseDevice*   fDevice;        // optional
     SkBounder*      fBounder;       // optional
     SkDrawProcs*    fProcs;         // optional
 
diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h
index 7b9dd32..3dc145c 100644
--- a/include/core/SkImageFilter.h
+++ b/include/core/SkImageFilter.h
@@ -13,7 +13,7 @@
 
 class SkBitmap;
 class SkColorFilter;
-class SkDevice;
+class SkBaseDevice;
 class SkMatrix;
 struct SkIPoint;
 class SkShader;
@@ -35,7 +35,7 @@
     public:
         virtual ~Proxy() {};
 
-        virtual SkDevice* createDevice(int width, int height) = 0;
+        virtual SkBaseDevice* createDevice(int width, int height) = 0;
         // returns true if the proxy can handle this filter natively
         virtual bool canHandleImageFilter(SkImageFilter*) = 0;
         // returns true if the proxy handled the filter itself. if this returns
diff --git a/include/core/SkRRect.h b/include/core/SkRRect.h
index bce896a..32d6285 100644
--- a/include/core/SkRRect.h
+++ b/include/core/SkRRect.h
@@ -25,7 +25,7 @@
 //      use growToInclude to fit skp round rects & generate stats (RRs vs. real paths)
 //      check on # of rectorus's the RRs could handle
 //   rendering work
-//      add entry points (clipRRect, drawRRect) - plumb down to SkDevice
+//      add entry points (clipRRect, drawRRect) - plumb down to SkBaseDevice
 //      update SkPath.addRRect() to take an SkRRect - only use quads
 //          -- alternatively add addRRectToPath here
 //      add GM and bench