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 "SkCanvas.h"
12 #include "SkSurface.h"
13 #include "SkSurfacePriv.h"
14 
15 class SkSurface_Base : public SkSurface {
16 public:
17     SkSurface_Base(int width, int height, const SkSurfaceProps*);
18     SkSurface_Base(const SkImageInfo&, const SkSurfaceProps*);
19     virtual ~SkSurface_Base();
20 
21     /**
22      *  Allocate a canvas that will draw into this surface. We will cache this
23      *  canvas, to return the same object to the caller multiple times. We
24      *  take ownership, and will call unref() on the canvas when we go out of
25      *  scope.
26      */
27     virtual SkCanvas* onNewCanvas() = 0;
28 
29     virtual SkSurface* onNewSurface(const SkImageInfo&) = 0;
30 
31     /**
32      *  Allocate an SkImage that represents the current contents of the surface.
33      *  This needs to be able to outlive the surface itself (if need be), and
34      *  must faithfully represent the current contents, even if the surface
35      *  is changed after this called (e.g. it is drawn to via its canvas).
36      */
37     virtual SkImage* onNewImageSnapshot(Budgeted) = 0;
38 
39     /**
40      *  Default implementation:
41      *
42      *  image = this->newImageSnapshot();
43      *  if (image) {
44      *      image->draw(canvas, ...);
45      *      image->unref();
46      *  }
47      */
48     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
49 
50     /**
51      * Called as a performance hint when the Surface is allowed to make it's contents
52      * undefined.
53      */
onDiscard()54     virtual void onDiscard() {}
55 
56     /**
57      *  If the surface is about to change, we call this so that our subclass
58      *  can optionally fork their backend (copy-on-write) in case it was
59      *  being shared with the cachedImage.
60      */
61     virtual void onCopyOnWrite(ContentChangeMode) = 0;
62 
63     inline SkCanvas* getCachedCanvas();
64     inline SkImage* getCachedImage(Budgeted);
65 
66     // called by SkSurface to compute a new genID
67     uint32_t newGenerationID();
68 
69 private:
70     SkCanvas*   fCachedCanvas;
71     SkImage*    fCachedImage;
72 
73     void aboutToDraw(ContentChangeMode mode);
74     friend class SkCanvas;
75     friend class SkSurface;
76 
77     typedef SkSurface INHERITED;
78 };
79 
getCachedCanvas()80 SkCanvas* SkSurface_Base::getCachedCanvas() {
81     if (NULL == fCachedCanvas) {
82         fCachedCanvas = this->onNewCanvas();
83         if (fCachedCanvas) {
84             fCachedCanvas->setSurfaceBase(this);
85         }
86     }
87     return fCachedCanvas;
88 }
89 
getCachedImage(Budgeted budgeted)90 SkImage* SkSurface_Base::getCachedImage(Budgeted budgeted) {
91     if (NULL == fCachedImage) {
92         fCachedImage = this->onNewImageSnapshot(budgeted);
93         SkASSERT(!fCachedCanvas || fCachedCanvas->getSurfaceBase() == this);
94     }
95     return fCachedImage;
96 }
97 
98 #endif
99