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