Home | History | Annotate | Download | only in image
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkSurface_Base_DEFINED
      9 #define SkSurface_Base_DEFINED
     10 
     11 #include "SkSurface.h"
     12 #include "SkCanvas.h"
     13 
     14 class SkSurface_Base : public SkSurface {
     15 public:
     16     SkSurface_Base(int width, int height);
     17     virtual ~SkSurface_Base();
     18 
     19     /**
     20      *  Allocate a canvas that will draw into this surface. We will cache this
     21      *  canvas, to return the same object to the caller multiple times. We
     22      *  take ownership, and will call unref() on the canvas when we go out of
     23      *  scope.
     24      */
     25     virtual SkCanvas* onNewCanvas() = 0;
     26 
     27     virtual SkSurface* onNewSurface(const SkImageInfo&) = 0;
     28 
     29     /**
     30      *  Allocate an SkImage that represents the current contents of the surface.
     31      *  This needs to be able to outlive the surface itself (if need be), and
     32      *  must faithfully represent the current contents, even if the surface
     33      *  is chaged after this calle (e.g. it is drawn to via its canvas).
     34      */
     35     virtual SkImage* onNewImageSnapshot() = 0;
     36 
     37     /**
     38      *  Default implementation:
     39      *
     40      *  image = this->newImageSnapshot();
     41      *  if (image) {
     42      *      image->draw(canvas, ...);
     43      *      image->unref();
     44      *  }
     45      */
     46     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
     47 
     48     /**
     49      *  If the surface is about to change, we call this so that our subclass
     50      *  can optionally fork their backend (copy-on-write) in case it was
     51      *  being shared with the cachedImage.
     52      */
     53     virtual void onCopyOnWrite(ContentChangeMode) = 0;
     54 
     55     inline SkCanvas* getCachedCanvas();
     56     inline SkImage* getCachedImage();
     57 
     58     // called by SkSurface to compute a new genID
     59     uint32_t newGenerationID();
     60 
     61 private:
     62     SkCanvas*   fCachedCanvas;
     63     SkImage*    fCachedImage;
     64 
     65     void aboutToDraw(ContentChangeMode mode);
     66     friend class SkCanvas;
     67     friend class SkSurface;
     68 
     69     inline void installIntoCanvasForDirtyNotification();
     70 
     71     typedef SkSurface INHERITED;
     72 };
     73 
     74 SkCanvas* SkSurface_Base::getCachedCanvas() {
     75     if (NULL == fCachedCanvas) {
     76         fCachedCanvas = this->onNewCanvas();
     77         this->installIntoCanvasForDirtyNotification();
     78     }
     79     return fCachedCanvas;
     80 }
     81 
     82 SkImage* SkSurface_Base::getCachedImage() {
     83     if (NULL == fCachedImage) {
     84         fCachedImage = this->onNewImageSnapshot();
     85         this->installIntoCanvasForDirtyNotification();
     86     }
     87     return fCachedImage;
     88 }
     89 
     90 void SkSurface_Base::installIntoCanvasForDirtyNotification() {
     91     if (NULL != fCachedCanvas) {
     92         fCachedCanvas->setSurfaceBase(this);
     93     }
     94 }
     95 
     96 #endif
     97