|
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 SkDeferredCanvas_DEFINED |
|
9 #define SkDeferredCanvas_DEFINED |
|
10 |
|
11 #include "SkCanvas.h" |
|
12 #include "SkPixelRef.h" |
|
13 |
|
14 class SkDeferredDevice; |
|
15 class SkImage; |
|
16 class SkSurface; |
|
17 |
|
18 /** \class SkDeferredCanvas |
|
19 Subclass of SkCanvas that encapsulates an SkPicture or SkGPipe for deferred |
|
20 drawing. The main difference between this class and SkPictureRecord (the |
|
21 canvas provided by SkPicture) is that this is a full drop-in replacement |
|
22 for SkCanvas, while SkPictureRecord only supports draw operations. |
|
23 SkDeferredCanvas will transparently trigger the flushing of deferred |
|
24 draw operations when an attempt is made to access the pixel data. |
|
25 */ |
|
26 class SK_API SkDeferredCanvas : public SkCanvas { |
|
27 public: |
|
28 class SK_API NotificationClient; |
|
29 |
|
30 /** Construct a canvas with the specified surface to draw into. |
|
31 This factory must be used for newImageSnapshot to work. |
|
32 @param surface Specifies a surface for the canvas to draw into. |
|
33 */ |
|
34 static SkDeferredCanvas* Create(SkSurface* surface); |
|
35 |
|
36 // static SkDeferredCanvas* Create(SkBaseDevice* device); |
|
37 |
|
38 virtual ~SkDeferredCanvas(); |
|
39 |
|
40 /** |
|
41 * Specify the surface to be used by this canvas. Calling setSurface will |
|
42 * release the previously set surface or device. Takes a reference on the |
|
43 * surface. |
|
44 * |
|
45 * @param surface The surface that the canvas will raw into |
|
46 * @return The surface argument, for convenience. |
|
47 */ |
|
48 SkSurface* setSurface(SkSurface* surface); |
|
49 |
|
50 /** |
|
51 * Specify a NotificationClient to be used by this canvas. Calling |
|
52 * setNotificationClient will release the previously set |
|
53 * NotificationClient, if any. SkDeferredCanvas does not take ownership |
|
54 * of the notification client. Therefore user code is resposible |
|
55 * for its destruction. The notification client must be unregistered |
|
56 * by calling setNotificationClient(NULL) if it is destroyed before |
|
57 * this canvas. |
|
58 * Note: Must be called after the device is set with setDevice. |
|
59 * |
|
60 * @param notificationClient interface for dispatching notifications |
|
61 * @return The notificationClient argument, for convenience. |
|
62 */ |
|
63 NotificationClient* setNotificationClient(NotificationClient* notificationClient); |
|
64 |
|
65 /** |
|
66 * Enable or disable deferred drawing. When deferral is disabled, |
|
67 * pending draw operations are immediately flushed and from then on, |
|
68 * the SkDeferredCanvas behaves just like a regular SkCanvas. |
|
69 * This method must not be called while the save/restore stack is in use. |
|
70 * @param deferred true/false |
|
71 */ |
|
72 void setDeferredDrawing(bool deferred); |
|
73 |
|
74 /** |
|
75 * Returns true if deferred drawing is currenlty enabled. |
|
76 */ |
|
77 bool isDeferredDrawing() const; |
|
78 |
|
79 /** |
|
80 * Returns true if the canvas contains a fresh frame. A frame is |
|
81 * considered fresh when its content do not depend on the contents |
|
82 * of the previous frame. For example, if a canvas is cleared before |
|
83 * drawing each frame, the frames will all be considered fresh. |
|
84 * A frame is defined as the graphics image produced by as a result |
|
85 * of all the canvas draws operation executed between two successive |
|
86 * calls to isFreshFrame. The result of isFreshFrame is computed |
|
87 * conservatively, so it may report false negatives. |
|
88 */ |
|
89 bool isFreshFrame() const; |
|
90 |
|
91 /** |
|
92 * Returns true if the canvas has recorded draw commands that have |
|
93 * not yet been played back. |
|
94 */ |
|
95 bool hasPendingCommands() const; |
|
96 |
|
97 /** |
|
98 * Flushes pending draw commands, if any, and returns an image of the |
|
99 * current state of the surface pixels up to this point. Subsequent |
|
100 * changes to the surface (by drawing into its canvas) will not be |
|
101 * reflected in this image. Will return NULL if the deferred canvas |
|
102 * was not constructed from an SkSurface. |
|
103 */ |
|
104 SkImage* newImageSnapshot(); |
|
105 |
|
106 /** |
|
107 * Specify the maximum number of bytes to be allocated for the purpose |
|
108 * of recording draw commands to this canvas. The default limit, is |
|
109 * 64MB. |
|
110 * @param maxStorage The maximum number of bytes to be allocated. |
|
111 */ |
|
112 void setMaxRecordingStorage(size_t maxStorage); |
|
113 |
|
114 /** |
|
115 * Returns the number of bytes currently allocated for the purpose of |
|
116 * recording draw commands. |
|
117 */ |
|
118 size_t storageAllocatedForRecording() const; |
|
119 |
|
120 /** |
|
121 * Attempt to reduce the storage allocated for recording by evicting |
|
122 * cache resources. |
|
123 * @param bytesToFree minimum number of bytes that should be attempted to |
|
124 * be freed. |
|
125 * @return number of bytes actually freed. |
|
126 */ |
|
127 size_t freeMemoryIfPossible(size_t bytesToFree); |
|
128 |
|
129 /** |
|
130 * Specifies the maximum size (in bytes) allowed for a given image to be |
|
131 * rendered using the deferred canvas. |
|
132 */ |
|
133 void setBitmapSizeThreshold(size_t sizeThreshold); |
|
134 |
|
135 /** |
|
136 * Executes all pending commands without drawing |
|
137 */ |
|
138 void silentFlush(); |
|
139 |
|
140 // Overrides of the SkCanvas interface |
|
141 virtual bool isDrawingToLayer() const SK_OVERRIDE; |
|
142 virtual void clear(SkColor) SK_OVERRIDE; |
|
143 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; |
|
144 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], |
|
145 const SkPaint& paint) SK_OVERRIDE; |
|
146 virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE; |
|
147 virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE; |
|
148 virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE; |
|
149 virtual void drawPath(const SkPath& path, const SkPaint& paint) |
|
150 SK_OVERRIDE; |
|
151 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, |
|
152 SkScalar top, const SkPaint* paint) |
|
153 SK_OVERRIDE; |
|
154 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, |
|
155 const SkRect& dst, const SkPaint* paint, |
|
156 DrawBitmapRectFlags flags) SK_OVERRIDE; |
|
157 |
|
158 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, |
|
159 const SkPaint* paint) SK_OVERRIDE; |
|
160 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, |
|
161 const SkRect& dst, const SkPaint* paint) |
|
162 SK_OVERRIDE; |
|
163 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, |
|
164 const SkPaint* paint) SK_OVERRIDE; |
|
165 virtual void drawText(const void* text, size_t byteLength, SkScalar x, |
|
166 SkScalar y, const SkPaint& paint) SK_OVERRIDE; |
|
167 virtual void drawPosText(const void* text, size_t byteLength, |
|
168 const SkPoint pos[], const SkPaint& paint) |
|
169 SK_OVERRIDE; |
|
170 virtual void drawPosTextH(const void* text, size_t byteLength, |
|
171 const SkScalar xpos[], SkScalar constY, |
|
172 const SkPaint& paint) SK_OVERRIDE; |
|
173 virtual void drawTextOnPath(const void* text, size_t byteLength, |
|
174 const SkPath& path, const SkMatrix* matrix, |
|
175 const SkPaint& paint) SK_OVERRIDE; |
|
176 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; |
|
177 virtual void drawVertices(VertexMode vmode, int vertexCount, |
|
178 const SkPoint vertices[], const SkPoint texs[], |
|
179 const SkColor colors[], SkXfermode* xmode, |
|
180 const uint16_t indices[], int indexCount, |
|
181 const SkPaint& paint) SK_OVERRIDE; |
|
182 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE; |
|
183 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; |
|
184 |
|
185 protected: |
|
186 virtual void willSave(SaveFlags) SK_OVERRIDE; |
|
187 virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; |
|
188 virtual void willRestore() SK_OVERRIDE; |
|
189 |
|
190 virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; |
|
191 virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; |
|
192 virtual void didRotate(SkScalar) SK_OVERRIDE; |
|
193 virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; |
|
194 virtual void didConcat(const SkMatrix&) SK_OVERRIDE; |
|
195 virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; |
|
196 |
|
197 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, |
|
198 const SkPaint&) SK_OVERRIDE; |
|
199 |
|
200 virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; |
|
201 virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; |
|
202 virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; |
|
203 virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; |
|
204 |
|
205 public: |
|
206 class NotificationClient { |
|
207 public: |
|
208 virtual ~NotificationClient() {} |
|
209 |
|
210 /** |
|
211 * Called before executing one or several draw commands, which means |
|
212 * once per flush when deferred rendering is enabled. |
|
213 */ |
|
214 virtual void prepareForDraw() {} |
|
215 |
|
216 /** |
|
217 * Called after a recording a draw command if additional memory |
|
218 * had to be allocated for recording. |
|
219 * @param newAllocatedStorage same value as would be returned by |
|
220 * storageAllocatedForRecording(), for convenience. |
|
221 */ |
|
222 virtual void storageAllocatedForRecordingChanged( |
|
223 size_t newAllocatedStorage) {} |
|
224 |
|
225 /** |
|
226 * Called after pending draw commands have been flushed |
|
227 */ |
|
228 virtual void flushedDrawCommands() {} |
|
229 |
|
230 /** |
|
231 * Called after pending draw commands have been skipped, meaning |
|
232 * that they were optimized-out because the canvas is cleared |
|
233 * or completely overwritten by the command currently being recorded. |
|
234 */ |
|
235 virtual void skippedPendingDrawCommands() {} |
|
236 }; |
|
237 |
|
238 protected: |
|
239 virtual SkCanvas* canvasForDrawIter(); |
|
240 SkDeferredDevice* getDeferredDevice() const; |
|
241 |
|
242 private: |
|
243 SkDeferredCanvas(SkDeferredDevice*); |
|
244 |
|
245 void recordedDrawCommand(); |
|
246 SkCanvas* drawingCanvas() const; |
|
247 SkCanvas* immediateCanvas() const; |
|
248 bool isFullFrame(const SkRect*, const SkPaint*) const; |
|
249 void validate() const; |
|
250 void init(); |
|
251 bool fDeferredDrawing; |
|
252 |
|
253 friend class SkDeferredCanvasTester; // for unit testing |
|
254 typedef SkCanvas INHERITED; |
|
255 }; |
|
256 |
|
257 |
|
258 #endif |