Added SkDevice onAttachToCanvas & onDetachFromCanvas methods

http://codereview.appspot.com/6348100/



git-svn-id: http://skia.googlecode.com/svn/trunk@4598 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index fc95f9a..8fa73f6 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -888,6 +888,15 @@
      */
     const SkRegion& getTotalClip() const;
 
+    /** Return the clip stack. The clip stack stores all the individual
+     *  clips organized by the save/restore frame in which they were
+     *  added.
+     *  @return the current clip stack ("list" of individual clip elements)
+     */
+    const SkClipStack* getClipStack() const {
+        return &fClipStack;
+    }
+
     void setExternalMatrix(const SkMatrix* = NULL);
 
     class ClipVisitor {
@@ -973,8 +982,7 @@
     SkDevice*   fLastDeviceToGainFocus;
     int         fSaveLayerCount;    // number of successful saveLayer calls
 
-    void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
-                              const SkClipStack& clipStack);
+    void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&);
 
     bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
     void updateDeviceCMCache();
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 184fb6f..5cf5c50 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -138,6 +138,32 @@
      */
     const SkIPoint& getOrigin() const { return fOrigin; }
 
+    /** 
+     * 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 
+     * devices to prepare for drawing (e.g., locking their pixels, etc.)
+     */
+    virtual void onAttachToCanvas(SkCanvas* canvas) {
+        this->lockPixels();
+#ifdef SK_DEBUG
+        fAttachedToCanvas = true;
+#endif
+    };
+
+    /**
+     * onDetachFromCanvas notifies a device that it will no longer be drawn to.
+     * It gives the device a chance to clean up (e.g., unlock its pixels). It
+     * is invoked from setDevice (for the displaced device), restore and 
+     * possibly from SkCanvas' dtor.
+     */
+    virtual void onDetachFromCanvas() {
+        this->unlockPixels();
+#ifdef SK_DEBUG
+        fAttachedToCanvas = false;
+#endif
+    };
+
 protected:
     enum Usage {
        kGeneral_Usage,
@@ -177,8 +203,9 @@
     /** Called when this device gains focus (i.e becomes the current device
         for drawing).
     */
-    virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
-                           const SkClipStack&) {}
+    virtual void gainFocus(const SkMatrix&, const SkRegion&) {
+        SkASSERT(fAttachedToCanvas);
+    }
 
     /** Clears the entire device to the specified color (including alpha).
      *  Ignores the clip.
@@ -376,6 +403,10 @@
     SkIPoint    fOrigin;
     SkMetaData* fMetaData;
 
+#ifdef SK_DEBUG
+    bool        fAttachedToCanvas;
+#endif
+
     typedef SkRefCnt INHERITED;
 };
 
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 40444a9..2390cdb 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -55,8 +55,7 @@
      *  Override from SkGpuDevice, so we can set our FBO to be the render target
      *  The canvas parameter must be a SkGpuCanvas
      */
-    virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
-                           const SkClipStack& clipStack) SK_OVERRIDE;
+    virtual void gainFocus(const SkMatrix&, const SkRegion&) SK_OVERRIDE;
 
     virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
 
@@ -101,6 +100,9 @@
 
     virtual void flush();
 
+    virtual void onAttachToCanvas(SkCanvas* canvas) SK_OVERRIDE;
+    virtual void onDetachFromCanvas() SK_OVERRIDE;
+
     /**
      * Make's this device's rendertarget current in the underlying 3D API.
      * Also implicitly flushes.
@@ -131,6 +133,9 @@
 
     GrSkDrawProcs*  fDrawProcs;
 
+    // the clip stack - on loan to us from SkCanvas so it can be NULL.
+    const SkClipStack*  fClipStack;
+
     // state for our offscreen render-target
     TexCache            fCache;
     GrTexture*          fTexture;
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 354729d..589cde9 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -100,6 +100,9 @@
     virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
                             const SkPaint&) SK_OVERRIDE;
 
+    virtual void onAttachToCanvas(SkCanvas* canvas) SK_OVERRIDE;
+    virtual void onDetachFromCanvas() SK_OVERRIDE;
+
     enum DrawingArea {
         kContent_DrawingArea,  // Drawing area for the page content.
         kMargin_DrawingArea,   // Drawing area for the margin content.
@@ -190,6 +193,8 @@
     ContentEntry* fLastMarginContentEntry;
     DrawingArea fDrawingArea;
 
+    const SkClipStack* fClipStack;
+
     // Accessor and setter functions based on the current DrawingArea.
     SkTScopedPtr<ContentEntry>* getContentEntries();
     ContentEntry* getLastContentEntry();
@@ -258,9 +263,7 @@
      */
     void copyContentEntriesToData(ContentEntry* entry, SkWStream* data) const;
 
-    // Disable the default copy and assign implementation.
-    SkPDFDevice(const SkPDFDevice&);
-    void operator=(const SkPDFDevice&);
+    typedef SkDevice INHERITED;
 };
 
 #endif
diff --git a/include/utils/SkDeferredCanvas.h b/include/utils/SkDeferredCanvas.h
index dd2c1f0..8964e9e 100644
--- a/include/utils/SkDeferredCanvas.h
+++ b/include/utils/SkDeferredCanvas.h
@@ -221,9 +221,6 @@
         virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
                                    const SkClipStack&) SK_OVERRIDE
             {}
-        virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
-                               const SkClipStack&) SK_OVERRIDE
-            {}
 
         // None of the following drawing methods should ever get called on the
         // deferred device