OLD | NEW |
| (Empty) |
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 virtual ~SkDeferredCanvas(); | |
37 | |
38 /** | |
39 * Specify the surface to be used by this canvas. Calling setSurface will | |
40 * release the previously set surface or device. Takes a reference on the | |
41 * surface. | |
42 * | |
43 * @param surface The surface that the canvas will raw into | |
44 * @return The surface argument, for convenience. | |
45 */ | |
46 SkSurface* setSurface(SkSurface* surface); | |
47 | |
48 /** | |
49 * Specify a NotificationClient to be used by this canvas. Calling | |
50 * setNotificationClient will release the previously set | |
51 * NotificationClient, if any. SkDeferredCanvas does not take ownership | |
52 * of the notification client. Therefore user code is resposible | |
53 * for its destruction. The notification client must be unregistered | |
54 * by calling setNotificationClient(NULL) if it is destroyed before | |
55 * this canvas. | |
56 * Note: Must be called after the device is set with setDevice. | |
57 * | |
58 * @param notificationClient interface for dispatching notifications | |
59 * @return The notificationClient argument, for convenience. | |
60 */ | |
61 NotificationClient* setNotificationClient(NotificationClient* notificationCl
ient); | |
62 | |
63 /** | |
64 * Enable or disable deferred drawing. When deferral is disabled, | |
65 * pending draw operations are immediately flushed and from then on, | |
66 * the SkDeferredCanvas behaves just like a regular SkCanvas. | |
67 * This method must not be called while the save/restore stack is in use. | |
68 * @param deferred true/false | |
69 */ | |
70 void setDeferredDrawing(bool deferred); | |
71 | |
72 /** | |
73 * Returns true if deferred drawing is currenlty enabled. | |
74 */ | |
75 bool isDeferredDrawing() const; | |
76 | |
77 /** | |
78 * Returns true if the canvas contains a fresh frame. A frame is | |
79 * considered fresh when its content do not depend on the contents | |
80 * of the previous frame. For example, if a canvas is cleared before | |
81 * drawing each frame, the frames will all be considered fresh. | |
82 * A frame is defined as the graphics image produced by as a result | |
83 * of all the canvas draws operation executed between two successive | |
84 * calls to isFreshFrame. The result of isFreshFrame is computed | |
85 * conservatively, so it may report false negatives. | |
86 */ | |
87 bool isFreshFrame() const; | |
88 | |
89 /** | |
90 * Returns canvas's size. | |
91 */ | |
92 SkISize getCanvasSize() const; | |
93 | |
94 /** | |
95 * Returns true if the canvas has recorded draw commands that have | |
96 * not yet been played back. | |
97 */ | |
98 bool hasPendingCommands() const; | |
99 | |
100 /** | |
101 * Flushes pending draw commands, if any, and returns an image of the | |
102 * current state of the surface pixels up to this point. Subsequent | |
103 * changes to the surface (by drawing into its canvas) will not be | |
104 * reflected in this image. Will return NULL if the deferred canvas | |
105 * was not constructed from an SkSurface. | |
106 */ | |
107 SkImage* newImageSnapshot(); | |
108 | |
109 /** | |
110 * Specify the maximum number of bytes to be allocated for the purpose | |
111 * of recording draw commands to this canvas. The default limit, is | |
112 * 64MB. | |
113 * @param maxStorage The maximum number of bytes to be allocated. | |
114 */ | |
115 void setMaxRecordingStorage(size_t maxStorage); | |
116 | |
117 /** | |
118 * Returns the number of bytes currently allocated for the purpose of | |
119 * recording draw commands. | |
120 */ | |
121 size_t storageAllocatedForRecording() const; | |
122 | |
123 /** | |
124 * Attempt to reduce the storage allocated for recording by evicting | |
125 * cache resources. | |
126 * @param bytesToFree minimum number of bytes that should be attempted to | |
127 * be freed. | |
128 * @return number of bytes actually freed. | |
129 */ | |
130 size_t freeMemoryIfPossible(size_t bytesToFree); | |
131 | |
132 /** | |
133 * Specifies the maximum size (in bytes) allowed for a given image to be | |
134 * rendered using the deferred canvas. | |
135 */ | |
136 void setBitmapSizeThreshold(size_t sizeThreshold); | |
137 size_t getBitmapSizeThreshold() const { return fBitmapSizeThreshold; } | |
138 | |
139 /** | |
140 * Executes all pending commands without drawing | |
141 */ | |
142 void silentFlush(); | |
143 | |
144 SkDrawFilter* setDrawFilter(SkDrawFilter* filter) override; | |
145 | |
146 protected: | |
147 void willSave() override; | |
148 SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) ov
erride; | |
149 void willRestore() override; | |
150 | |
151 void didConcat(const SkMatrix&) override; | |
152 void didSetMatrix(const SkMatrix&) override; | |
153 | |
154 void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; | |
155 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkS
calar y, | |
156 const SkPaint&) override; | |
157 virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoin
t pos[], | |
158 const SkPaint&) override; | |
159 virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkSca
lar xpos[], | |
160 SkScalar constY, const SkPaint&) override; | |
161 virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkP
ath& path, | |
162 const SkMatrix* matrix, const SkPaint&) overri
de; | |
163 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, | |
164 const SkPaint& paint) override; | |
165 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], | |
166 const SkPoint texCoords[4], SkXfermode* xmode, | |
167 const SkPaint& paint) override; | |
168 | |
169 void onDrawPaint(const SkPaint&) override; | |
170 void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPain
t&) override; | |
171 void onDrawRect(const SkRect&, const SkPaint&) override; | |
172 void onDrawOval(const SkRect&, const SkPaint&) override; | |
173 void onDrawRRect(const SkRRect&, const SkPaint&) override; | |
174 void onDrawPath(const SkPath&, const SkPaint&) override; | |
175 void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPain
t*) override; | |
176 void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst,
const SkPaint*, | |
177 SrcRectConstraint) override; | |
178 void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*
) override; | |
179 void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, | |
180 const SkPaint*, SrcRectConstraint) override; | |
181 void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& ds
t, | |
182 const SkPaint*) override; | |
183 void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect&
dst, | |
184 const SkPaint*) override; | |
185 void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*) overri
de; | |
186 void onDrawVertices(VertexMode vmode, int vertexCount, | |
187 const SkPoint vertices[], const SkPoint texs[], | |
188 const SkColor colors[], SkXfermode* xmode, | |
189 const uint16_t indices[], int indexCount, | |
190 const SkPaint&) override; | |
191 void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const Sk
Color[], int count, | |
192 SkXfermode::Mode, const SkRect* cullRect, const SkPaint*) o
verride; | |
193 | |
194 void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override; | |
195 void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override; | |
196 void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override; | |
197 void onClipRegion(const SkRegion&, SkRegion::Op) override; | |
198 | |
199 void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) overri
de; | |
200 | |
201 public: | |
202 class NotificationClient { | |
203 public: | |
204 virtual ~NotificationClient() {} | |
205 | |
206 /** | |
207 * Called before executing one or several draw commands, which means | |
208 * once per flush when deferred rendering is enabled. | |
209 */ | |
210 virtual void prepareForDraw() {} | |
211 | |
212 /** | |
213 * Called after a recording a draw command if additional memory | |
214 * had to be allocated for recording. | |
215 * @param newAllocatedStorage same value as would be returned by | |
216 * storageAllocatedForRecording(), for convenience. | |
217 */ | |
218 virtual void storageAllocatedForRecordingChanged(size_t /*newAllocatedSt
orage*/) {} | |
219 | |
220 /** | |
221 * Called after pending draw commands have been flushed | |
222 */ | |
223 virtual void flushedDrawCommands() {} | |
224 | |
225 /** | |
226 * Called after pending draw commands have been skipped, meaning | |
227 * that they were optimized-out because the canvas is cleared | |
228 * or completely overwritten by the command currently being recorded. | |
229 */ | |
230 virtual void skippedPendingDrawCommands() {} | |
231 }; | |
232 | |
233 protected: | |
234 SkCanvas* canvasForDrawIter() override; | |
235 SkDeferredDevice* getDeferredDevice() const; | |
236 | |
237 private: | |
238 SkDeferredCanvas(SkDeferredDevice*); | |
239 | |
240 void recordedDrawCommand(); | |
241 SkCanvas* drawingCanvas() const; | |
242 SkCanvas* immediateCanvas() const; | |
243 bool isFullFrame(const SkRect*, const SkPaint*) const; | |
244 void validate() const; | |
245 void init(); | |
246 | |
247 | |
248 int fSaveLevel; | |
249 int fFirstSaveLayerIndex; | |
250 size_t fBitmapSizeThreshold; | |
251 bool fDeferredDrawing; | |
252 | |
253 mutable SkISize fCachedCanvasSize; | |
254 mutable bool fCachedCanvasSizeDirty; | |
255 | |
256 friend class SkDeferredCanvasTester; // for unit testing | |
257 typedef SkCanvas INHERITED; | |
258 }; | |
259 | |
260 | |
261 #endif | |
OLD | NEW |