Add createNewCompatibleDevice. Allow devices to have a NULL factory and saveLayer will fall back on createNewCompatibleDevice.

Review URL: http://codereview.appspot.com/4633044/



git-svn-id: http://skia.googlecode.com/svn/trunk@1625 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index d5032a7..9b96790 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -53,15 +53,19 @@
 */
 class SK_API SkCanvas : public SkRefCnt {
 public:
-    /** Construct a canvas with the given device factory.
+    /**
+        DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+
+        Construct a canvas with the given device factory.
         @param factory  Specify the factory for generating additional devices.
                         The factory may be null, in which case
                         SkRasterDeviceFactory will be used.
     */
     explicit SkCanvas(SkDeviceFactory* factory = NULL);
 
-    /** Construct a canvas with the specified device to draw into.  The device
+    /** Construct a canvas with the specified device to draw into.  The device

         factory will be retrieved from the passed device.
+
         @param device   Specifies a device for the canvas to draw into.
     */
     explicit SkCanvas(SkDevice* device);
@@ -96,13 +100,6 @@
      */
     SkDevice* getTopDevice() const;
 
-    /** May be overridden by subclasses. This returns a compatible device
-        for this canvas, with the specified config/width/height. If the device
-        is raster, the pixels will be allocated automatically.
-     */
-    virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
-                                   bool isOpaque);
-
     /**
      *  Create a new raster device and make it current. This also returns
      *  the new device.
@@ -110,18 +107,29 @@
     SkDevice* setBitmapDevice(const SkBitmap& bitmap);
 
     /**
+     * DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+     *
      *  Return the current device factory, or NULL. The reference count of
      *  the returned factory is not changed.
      */
     SkDeviceFactory* getDeviceFactory() const { return fDeviceFactory; }
 
     /**
+     *  DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+     *
      *  Replace any existing factory with the specified factory, unrefing the
      *  previous (if any), and refing the new one (if any). For convenience,
      *  the factory parameter is also returned.
      */
     SkDeviceFactory* setDeviceFactory(SkDeviceFactory*);
 
+    /**
+     * Shortcut for getDevice()->createCompatibleDevice(...)
+     */
+    SkDevice* createCompatibleDevice(SkBitmap::Config config, 
+                                    int width, int height,
+                                    bool isOpaque);
+
     ///////////////////////////////////////////////////////////////////////////
 
     /**
@@ -834,6 +842,9 @@
 
     friend class SkDrawIter;    // needs setupDrawForLayerDevice()
 
+    SkDevice* createLayerDevice(SkBitmap::Config, int width, int height, 
+                                bool isOpaque);
+
     SkDevice* init(SkDevice*);
     void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
                                   const SkPaint* paint);
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index ff9c4d1..59e95e7 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -32,6 +32,8 @@
 
 /** \class SkDeviceFactory
 
+    DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+
     Devices that extend SkDevice should also provide a SkDeviceFactory class
     to pass into SkCanvas.  Doing so will eliminate the need to extend
     SkCanvas as well.
@@ -79,12 +81,27 @@
     virtual ~SkDevice();
 
     /**
+     *  DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+     *
      *  Return the factory that will create this subclass of SkDevice.
      *  The returned factory is cached by the device, and so its reference count
      *  is not changed by this call.
      */
     SkDeviceFactory* getDeviceFactory();
 
+    /**
+     * Creates a device that is of the same type as this device (e.g. SW-raster,
+     * GPU, or PDF).
+     *
+     * @param width     width of the device to create
+     * @param height    height of the device to create
+     * @param isOpaque  
+     * @param usage     clients should always use the default, kGeneral_Usage.
+     */
+    SkDevice* createCompatibleDevice(SkBitmap::Config config, 
+                                     int width, int height,
+                                     bool isOpaque);
+
     enum Capabilities {
         kGL_Capability     = 0x1,  //!< mask indicating GL support
         kVector_Capability = 0x2,  //!< mask indicating a vector representation
@@ -264,9 +281,13 @@
 
 protected:
     /**
-     *  subclasses must override this to return a new (or ref'd) instance of
+     *  DEPRECATED: Will be replaced by SkDevice::createCompatibleDevice
+     *
+     *  subclasses can override this to return a new (or ref'd) instance of
      *  a device factory that will create this subclass of device. This value
      *  is cached, so it should get called at most once for a given instance.
+     *
+     *  If not overriden then createCompatibleDevice will be used by canvas.
      */
     virtual SkDeviceFactory* onNewDeviceFactory();
 
@@ -276,6 +297,18 @@
     */
     virtual void onAccessBitmap(SkBitmap*);
 
+    enum Usage {
+       kGeneral_Usage,
+       kSaveLayer_Usage, // <! internal use only
+    };
+    /**
+     * subclasses should override this to implement createCompatibleDevice.
+     */
+    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, 
+                                               int width, int height, 
+                                               bool isOpaque,
+                                               Usage usage);
+
     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
     // just for subclasses, to assign a custom pixelref
     SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
@@ -287,6 +320,10 @@
     friend class SkCanvas;
     // 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);
 
     SkBitmap    fBitmap;
     SkIPoint    fOrigin;
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 4d0efeb..3a675be 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -37,11 +37,12 @@
      *  New device that will create an offscreen renderTarget based on the
      *  config, width, height.
      *
-     *  isForSaveLayer is a special flag that should only be set by SkCanvas
+     *  usage is a special flag that should only be set by SkCanvas
      *  internally.
      */
-    SkGpuDevice(GrContext*, SkBitmap::Config, int width, int height,
-                bool isForSaveLayer = false);
+    SkGpuDevice(GrContext*, SkBitmap::Config,
+                int width, int height, 
+                SkDevice::Usage usage = SkDevice::kGeneral_Usage);
 
     /**
      *  New device that will render to the specified renderTarget.
@@ -132,11 +133,15 @@
     virtual SkDeviceFactory* onNewDeviceFactory();
 
     class TexCache;
+    enum TexType {
+        kBitmap_TexType,
+        kDeviceRenderTarget_TexType,
+        kSaveLayerDeviceRenderTarget_TexType
+    };
     TexCache* lockCachedTexture(const SkBitmap& bitmap,
                                 const GrSamplerState& sampler,
                                 GrTexture** texture,
-                                bool forDeviceRenderTarget = false,
-                                bool isSaveLayer = false);
+                                TexType type = kBitmap_TexType);
     void unlockCachedTexture(TexCache*);
 
     class SkAutoCachedTexture {
@@ -192,6 +197,12 @@
                                GrPaint* grPaint,
                                bool constantColor);
 
+    // override from SkDevice
+    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, 
+                                               int width, int height, 
+                                               bool isOpaque,
+                                               Usage usage);
+
     SkDrawProcs* initDrawForText(GrTextContext*);
     bool bindDeviceAsTexture(GrPaint* paint);
 
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 6e4d8db..2205f6c 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -173,6 +173,12 @@
     SkPDFDevice(const SkISize& layerSize, const SkClipStack& existingClipStack,
                 const SkRegion& existingClipRegion);
 
+    // override from SkDevice
+    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, 
+                                               int width, int height, 
+                                               bool isOpaque,
+                                               Usage usage);
+
     void init();
     void cleanUp();
     void createFormXObjectFromDevice(SkRefPtr<SkPDFFormXObject>* xobject);