blob: 9eabb7bfdbfad2a7aa193051fe0c13b7248ba694 [file] [log] [blame]
junov@google.com4370aed2012-01-18 16:21:08 +00001/*
2 * Copyright 2011 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 "SkDevice.h"
13#include "SkPicture.h"
14#include "SkPixelRef.h"
15
16/** \class SkDeferredCanvas
17 Subclass of SkCanvas that encapsulates an SkPicture for deferred drawing.
18 The main difference between this class and SkPictureRecord (the canvas
19 provided by SkPicture) is that this is a full drop-in replacement for
20 SkCanvas, while SkPictureRecord only supports draw operations.
21 SkDeferredCanvas will transparently trigger the flushing of deferred
vandebo@chromium.org74b46192012-01-28 01:45:11 +000022 draw operations when an attempt is made to access the pixel data.
junov@google.com4370aed2012-01-18 16:21:08 +000023*/
24class SK_API SkDeferredCanvas : public SkCanvas {
25public:
26 class DeviceContext;
27
28 SkDeferredCanvas();
29
30 /** Construct a canvas with the specified device to draw into.
31 Equivalent to calling default constructor, then setDevice.
32 @param device Specifies a device for the canvas to draw into.
33 */
34 explicit SkDeferredCanvas(SkDevice* device);
35
36 /** Construct a canvas with the specified device to draw into, and
37 * a device context. Equivalent to calling default constructor, then
38 * setDevice.
39 * @param device Specifies a device for the canvas to draw into.
40 * @param deviceContext interface for the device's the graphics context
41 */
42 explicit SkDeferredCanvas(SkDevice* device, DeviceContext* deviceContext);
43
44 virtual ~SkDeferredCanvas();
45
46 /**
47 * Specify a device to be used by this canvas. Calling setDevice will
48 * release the previously set device, if any.
49 *
50 * @param device The device that the canvas will raw into
51 * @return The device argument, for convenience.
52 */
53 virtual SkDevice* setDevice(SkDevice* device);
54
55 /**
vandebo@chromium.org74b46192012-01-28 01:45:11 +000056 * Specify a deviceContext to be used by this canvas. Calling
junov@google.com4370aed2012-01-18 16:21:08 +000057 * setDeviceContext will release the previously set deviceContext, if any.
58 * A deviceContext must be specified if the device uses a graphics context
vandebo@chromium.org74b46192012-01-28 01:45:11 +000059 * that requires some form of state initialization prior to drawing
junov@google.com4370aed2012-01-18 16:21:08 +000060 * and/or explicit flushing to synchronize the execution of rendering
vandebo@chromium.org74b46192012-01-28 01:45:11 +000061 * operations.
junov@google.com4370aed2012-01-18 16:21:08 +000062 * Note: Must be called after the device is set with setDevice.
63 *
64 * @deviceContext interface for the device's the graphics context
65 * @return The deviceContext argument, for convenience.
66 */
67 DeviceContext* setDeviceContext(DeviceContext* deviceContext);
68
69 /**
70 * Enable or disable deferred drawing. When deferral is disabled,
71 * pending draw operations are immediately flushed and from then on,
72 * the SkDeferredCanvas behaves just like a regular SkCanvas.
73 * This method must not be called while the save/restore stack is in use.
74 * @param deferred true/false
75 */
76 void setDeferredDrawing(bool deferred);
77
78 // Overrides of the SkCanvas interface
79 virtual int save(SaveFlags flags) SK_OVERRIDE;
80 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
81 SaveFlags flags) SK_OVERRIDE;
82 virtual void restore() SK_OVERRIDE;
83 virtual int getSaveCount() const SK_OVERRIDE;
84 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
85 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
86 virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
87 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
88 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
89 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
90 virtual const SkMatrix& getTotalMatrix() const SK_OVERRIDE;
91 virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
92 bool doAntiAlias) SK_OVERRIDE;
93 virtual bool clipPath(const SkPath& path, SkRegion::Op op,
94 bool doAntiAlias) SK_OVERRIDE;
95 virtual bool clipRegion(const SkRegion& deviceRgn,
96 SkRegion::Op op) SK_OVERRIDE;
97 virtual void clear(SkColor) SK_OVERRIDE;
98 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
99 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
100 const SkPaint& paint) SK_OVERRIDE;
101 virtual void drawRect(const SkRect& rect, const SkPaint& paint)
102 SK_OVERRIDE;
103 virtual void drawPath(const SkPath& path, const SkPaint& paint)
104 SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000105 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
junov@google.com4370aed2012-01-18 16:21:08 +0000106 SkScalar top, const SkPaint* paint)
107 SK_OVERRIDE;
108 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
109 const SkRect& dst, const SkPaint* paint)
110 SK_OVERRIDE;
111
112 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
113 const SkPaint* paint) SK_OVERRIDE;
114 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
115 const SkRect& dst, const SkPaint* paint)
116 SK_OVERRIDE;
117 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
118 const SkPaint* paint) SK_OVERRIDE;
119 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
120 SkScalar y, const SkPaint& paint) SK_OVERRIDE;
121 virtual void drawPosText(const void* text, size_t byteLength,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000122 const SkPoint pos[], const SkPaint& paint)
junov@google.com4370aed2012-01-18 16:21:08 +0000123 SK_OVERRIDE;
124 virtual void drawPosTextH(const void* text, size_t byteLength,
125 const SkScalar xpos[], SkScalar constY,
126 const SkPaint& paint) SK_OVERRIDE;
127 virtual void drawTextOnPath(const void* text, size_t byteLength,
128 const SkPath& path, const SkMatrix* matrix,
129 const SkPaint& paint) SK_OVERRIDE;
130 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
131 virtual void drawVertices(VertexMode vmode, int vertexCount,
132 const SkPoint vertices[], const SkPoint texs[],
133 const SkColor colors[], SkXfermode* xmode,
134 const uint16_t indices[], int indexCount,
135 const SkPaint& paint) SK_OVERRIDE;
136 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
137 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
138
139private:
140 void flushIfNeeded(const SkBitmap& bitmap);
141
142public:
143 class DeviceContext : public SkRefCnt {
144 public:
145 virtual void prepareForDraw() {}
146 virtual void flush() {}
147 };
148
149public:
150 class DeferredDevice : public SkDevice {
151 public:
152 /**
153 * Constructor
154 * @param immediateDevice device to be drawn to when flushing
155 * deferred operations
156 * @param deviceContext callback interface for managing graphics
157 * context state, can be NULL.
158 */
159 DeferredDevice(SkDevice* immediateDevice,
160 DeviceContext* deviceContext = NULL);
161 ~DeferredDevice();
162
163 /**
164 * Sets the device context to be use with the device.
165 * @param deviceContext callback interface for managing graphics
166 * context state, can be NULL.
167 */
168 void setDeviceContext(DeviceContext* deviceContext);
169
170 /**
171 * Returns the recording canvas.
172 */
173 SkCanvas* recordingCanvas() const {return fRecordingCanvas;}
174
175 /**
176 * Returns the immediate (non deferred) canvas.
177 */
178 SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
179
180 /**
181 * Returns the immediate (non deferred) device.
182 */
183 SkDevice* immediateDevice() const {return fImmediateDevice;}
184
185 void flushPending();
186 void flushContext();
187 void purgePending();
188 void flushIfNeeded(const SkBitmap& bitmap);
189
190 virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
191 virtual int width() const SK_OVERRIDE;
192 virtual int height() const SK_OVERRIDE;
193 virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
194
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000195 virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
196 int width, int height,
junov@google.com4370aed2012-01-18 16:21:08 +0000197 bool isOpaque,
198 Usage usage) SK_OVERRIDE;
199
200 virtual void writePixels(const SkBitmap& bitmap, int x, int y,
201 SkCanvas::Config8888 config8888) SK_OVERRIDE;
202
203 protected:
204 virtual void onAccessBitmap(SkBitmap*) SK_OVERRIDE;
205 virtual bool onReadPixels(const SkBitmap& bitmap,
206 int x, int y,
207 SkCanvas::Config8888 config8888) SK_OVERRIDE;
208
209 // The following methods are no-ops on a deferred device
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000210 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*)
junov@google.com4370aed2012-01-18 16:21:08 +0000211 SK_OVERRIDE
212 {return false;}
213 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
214 const SkClipStack&) SK_OVERRIDE
215 {}
216 virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
217 const SkClipStack&) SK_OVERRIDE
218 {}
219
220 // None of the following drawing methods should ever get called on the
221 // deferred device
222 virtual void clear(SkColor color)
223 {SkASSERT(0);}
224 virtual void drawPaint(const SkDraw&, const SkPaint& paint)
225 {SkASSERT(0);}
226 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
227 size_t count, const SkPoint[],
228 const SkPaint& paint)
229 {SkASSERT(0);}
230 virtual void drawRect(const SkDraw&, const SkRect& r,
231 const SkPaint& paint)
232 {SkASSERT(0);}
233 virtual void drawPath(const SkDraw&, const SkPath& path,
234 const SkPaint& paint,
235 const SkMatrix* prePathMatrix = NULL,
236 bool pathIsMutable = false)
237 {SkASSERT(0);}
238 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
239 const SkIRect* srcRectOrNull,
240 const SkMatrix& matrix, const SkPaint& paint)
241 {SkASSERT(0);}
242 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
243 int x, int y, const SkPaint& paint)
244 {SkASSERT(0);}
245 virtual void drawText(const SkDraw&, const void* text, size_t len,
246 SkScalar x, SkScalar y, const SkPaint& paint)
247 {SkASSERT(0);}
248 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
249 const SkScalar pos[], SkScalar constY,
250 int scalarsPerPos, const SkPaint& paint)
251 {SkASSERT(0);}
252 virtual void drawTextOnPath(const SkDraw&, const void* text,
253 size_t len, const SkPath& path,
254 const SkMatrix* matrix,
255 const SkPaint& paint)
256 {SkASSERT(0);}
257 virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
258 size_t len, const SkPoint pos[],
259 const SkPaint& paint,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000260 const SkPath& path,
junov@google.com4370aed2012-01-18 16:21:08 +0000261 const SkMatrix* matrix)
262 {SkASSERT(0);}
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000263 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
junov@google.com4370aed2012-01-18 16:21:08 +0000264 int vertexCount, const SkPoint verts[],
265 const SkPoint texs[], const SkColor colors[],
266 SkXfermode* xmode, const uint16_t indices[],
267 int indexCount, const SkPaint& paint)
268 {SkASSERT(0);}
269 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
270 const SkPaint&)
271 {SkASSERT(0);}
272 private:
273 virtual void flush();
274
275 SkPicture fPicture;
276 SkDevice* fImmediateDevice;
277 SkCanvas* fImmediateCanvas;
278 SkCanvas* fRecordingCanvas;
279 DeviceContext* fDeviceContext;
280 };
281
282 DeferredDevice* getDeferredDevice() const;
283
284protected:
285 virtual SkCanvas* canvasForDrawIter();
286
287private:
288 SkCanvas* drawingCanvas() const;
289 bool isFullFrame(const SkRect*, const SkPaint*) const;
290 void validate() const;
291 void init();
292 bool fDeferredDrawing;
293
294 typedef SkCanvas INHERITED;
295};
296
297
298#endif