blob: dd2c1f0c4a4f12a73d9b0001ea024443340c5a82 [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;
junov@chromium.orga907ac32012-02-24 21:54:07 +000083 virtual bool isDrawingToLayer() const SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +000084 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;
junov@google.com4370aed2012-01-18 16:21:08 +000090 virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
91 bool doAntiAlias) SK_OVERRIDE;
92 virtual bool clipPath(const SkPath& path, SkRegion::Op op,
93 bool doAntiAlias) SK_OVERRIDE;
94 virtual bool clipRegion(const SkRegion& deviceRgn,
95 SkRegion::Op op) SK_OVERRIDE;
96 virtual void clear(SkColor) SK_OVERRIDE;
97 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
98 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
99 const SkPaint& paint) SK_OVERRIDE;
100 virtual void drawRect(const SkRect& rect, const SkPaint& paint)
101 SK_OVERRIDE;
102 virtual void drawPath(const SkPath& path, const SkPaint& paint)
103 SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000104 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
junov@google.com4370aed2012-01-18 16:21:08 +0000105 SkScalar top, const SkPaint* paint)
106 SK_OVERRIDE;
107 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
108 const SkRect& dst, const SkPaint* paint)
109 SK_OVERRIDE;
110
111 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
112 const SkPaint* paint) SK_OVERRIDE;
113 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
114 const SkRect& dst, const SkPaint* paint)
115 SK_OVERRIDE;
116 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
117 const SkPaint* paint) SK_OVERRIDE;
118 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
119 SkScalar y, const SkPaint& paint) SK_OVERRIDE;
120 virtual void drawPosText(const void* text, size_t byteLength,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000121 const SkPoint pos[], const SkPaint& paint)
junov@google.com4370aed2012-01-18 16:21:08 +0000122 SK_OVERRIDE;
123 virtual void drawPosTextH(const void* text, size_t byteLength,
124 const SkScalar xpos[], SkScalar constY,
125 const SkPaint& paint) SK_OVERRIDE;
126 virtual void drawTextOnPath(const void* text, size_t byteLength,
127 const SkPath& path, const SkMatrix* matrix,
128 const SkPaint& paint) SK_OVERRIDE;
129 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
130 virtual void drawVertices(VertexMode vmode, int vertexCount,
131 const SkPoint vertices[], const SkPoint texs[],
132 const SkColor colors[], SkXfermode* xmode,
133 const uint16_t indices[], int indexCount,
134 const SkPaint& paint) SK_OVERRIDE;
135 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
136 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
137
138private:
139 void flushIfNeeded(const SkBitmap& bitmap);
140
141public:
142 class DeviceContext : public SkRefCnt {
143 public:
reed@google.com563a3b42012-06-26 19:24:50 +0000144 SK_DECLARE_INST_COUNT(DeviceContext)
145
junov@google.com4370aed2012-01-18 16:21:08 +0000146 virtual void prepareForDraw() {}
reed@google.com563a3b42012-06-26 19:24:50 +0000147
148 private:
149 typedef SkRefCnt INHERITED;
junov@google.com4370aed2012-01-18 16:21:08 +0000150 };
151
152public:
153 class DeferredDevice : public SkDevice {
154 public:
155 /**
156 * Constructor
157 * @param immediateDevice device to be drawn to when flushing
158 * deferred operations
159 * @param deviceContext callback interface for managing graphics
160 * context state, can be NULL.
161 */
162 DeferredDevice(SkDevice* immediateDevice,
163 DeviceContext* deviceContext = NULL);
164 ~DeferredDevice();
165
166 /**
167 * Sets the device context to be use with the device.
168 * @param deviceContext callback interface for managing graphics
169 * context state, can be NULL.
170 */
171 void setDeviceContext(DeviceContext* deviceContext);
172
173 /**
174 * Returns the recording canvas.
175 */
176 SkCanvas* recordingCanvas() const {return fRecordingCanvas;}
177
178 /**
179 * Returns the immediate (non deferred) canvas.
180 */
181 SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
182
183 /**
184 * Returns the immediate (non deferred) device.
185 */
186 SkDevice* immediateDevice() const {return fImmediateDevice;}
187
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000188 /**
189 * Returns true if an opaque draw operation covering the entire canvas
190 * was performed since the last call to isFreshFrame().
191 */
192 bool isFreshFrame();
193
junov@google.com4370aed2012-01-18 16:21:08 +0000194 void flushPending();
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000195 void contentsCleared();
junov@google.com4370aed2012-01-18 16:21:08 +0000196 void flushIfNeeded(const SkBitmap& bitmap);
197
198 virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
199 virtual int width() const SK_OVERRIDE;
200 virtual int height() const SK_OVERRIDE;
201 virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
202
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000203 virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
204 int width, int height,
junov@google.com4370aed2012-01-18 16:21:08 +0000205 bool isOpaque,
206 Usage usage) SK_OVERRIDE;
207
208 virtual void writePixels(const SkBitmap& bitmap, int x, int y,
209 SkCanvas::Config8888 config8888) SK_OVERRIDE;
210
211 protected:
junov@chromium.org1f9767c2012-02-07 16:27:57 +0000212 virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000213 virtual bool onReadPixels(const SkBitmap& bitmap,
214 int x, int y,
215 SkCanvas::Config8888 config8888) SK_OVERRIDE;
216
217 // The following methods are no-ops on a deferred device
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000218 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*)
junov@google.com4370aed2012-01-18 16:21:08 +0000219 SK_OVERRIDE
220 {return false;}
221 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
222 const SkClipStack&) SK_OVERRIDE
223 {}
224 virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
225 const SkClipStack&) SK_OVERRIDE
226 {}
227
228 // None of the following drawing methods should ever get called on the
229 // deferred device
230 virtual void clear(SkColor color)
231 {SkASSERT(0);}
232 virtual void drawPaint(const SkDraw&, const SkPaint& paint)
233 {SkASSERT(0);}
234 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
235 size_t count, const SkPoint[],
236 const SkPaint& paint)
237 {SkASSERT(0);}
238 virtual void drawRect(const SkDraw&, const SkRect& r,
239 const SkPaint& paint)
240 {SkASSERT(0);}
241 virtual void drawPath(const SkDraw&, const SkPath& path,
242 const SkPaint& paint,
243 const SkMatrix* prePathMatrix = NULL,
244 bool pathIsMutable = false)
245 {SkASSERT(0);}
246 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
247 const SkIRect* srcRectOrNull,
248 const SkMatrix& matrix, const SkPaint& paint)
249 {SkASSERT(0);}
250 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
251 int x, int y, const SkPaint& paint)
252 {SkASSERT(0);}
253 virtual void drawText(const SkDraw&, const void* text, size_t len,
254 SkScalar x, SkScalar y, const SkPaint& paint)
255 {SkASSERT(0);}
256 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
257 const SkScalar pos[], SkScalar constY,
258 int scalarsPerPos, const SkPaint& paint)
259 {SkASSERT(0);}
260 virtual void drawTextOnPath(const SkDraw&, const void* text,
261 size_t len, const SkPath& path,
262 const SkMatrix* matrix,
263 const SkPaint& paint)
264 {SkASSERT(0);}
265 virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
266 size_t len, const SkPoint pos[],
267 const SkPaint& paint,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000268 const SkPath& path,
junov@google.com4370aed2012-01-18 16:21:08 +0000269 const SkMatrix* matrix)
270 {SkASSERT(0);}
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000271 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
junov@google.com4370aed2012-01-18 16:21:08 +0000272 int vertexCount, const SkPoint verts[],
273 const SkPoint texs[], const SkColor colors[],
274 SkXfermode* xmode, const uint16_t indices[],
275 int indexCount, const SkPaint& paint)
276 {SkASSERT(0);}
277 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
278 const SkPaint&)
279 {SkASSERT(0);}
280 private:
281 virtual void flush();
282
283 SkPicture fPicture;
284 SkDevice* fImmediateDevice;
285 SkCanvas* fImmediateCanvas;
286 SkCanvas* fRecordingCanvas;
287 DeviceContext* fDeviceContext;
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000288 bool fFreshFrame;
junov@google.com4370aed2012-01-18 16:21:08 +0000289 };
290
291 DeferredDevice* getDeferredDevice() const;
292
293protected:
294 virtual SkCanvas* canvasForDrawIter();
295
296private:
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000297 SkCanvas* drawingCanvas() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000298 bool isFullFrame(const SkRect*, const SkPaint*) const;
299 void validate() const;
300 void init();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000301 bool fDeferredDrawing;
junov@google.com4370aed2012-01-18 16:21:08 +0000302
303 typedef SkCanvas INHERITED;
304};
305
306
307#endif