blob: d1424f0fcf9fea05769f4e64e8be62417901f088 [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:
144 virtual void prepareForDraw() {}
junov@google.com4370aed2012-01-18 16:21:08 +0000145 };
146
147public:
148 class DeferredDevice : public SkDevice {
149 public:
150 /**
151 * Constructor
152 * @param immediateDevice device to be drawn to when flushing
153 * deferred operations
154 * @param deviceContext callback interface for managing graphics
155 * context state, can be NULL.
156 */
157 DeferredDevice(SkDevice* immediateDevice,
158 DeviceContext* deviceContext = NULL);
159 ~DeferredDevice();
160
161 /**
162 * Sets the device context to be use with the device.
163 * @param deviceContext callback interface for managing graphics
164 * context state, can be NULL.
165 */
166 void setDeviceContext(DeviceContext* deviceContext);
167
168 /**
169 * Returns the recording canvas.
170 */
171 SkCanvas* recordingCanvas() const {return fRecordingCanvas;}
172
173 /**
174 * Returns the immediate (non deferred) canvas.
175 */
176 SkCanvas* immediateCanvas() const {return fImmediateCanvas;}
177
178 /**
179 * Returns the immediate (non deferred) device.
180 */
181 SkDevice* immediateDevice() const {return fImmediateDevice;}
182
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000183 /**
184 * Returns true if an opaque draw operation covering the entire canvas
185 * was performed since the last call to isFreshFrame().
186 */
187 bool isFreshFrame();
188
junov@google.com4370aed2012-01-18 16:21:08 +0000189 void flushPending();
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000190 void contentsCleared();
junov@google.com4370aed2012-01-18 16:21:08 +0000191 void flushIfNeeded(const SkBitmap& bitmap);
192
193 virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
194 virtual int width() const SK_OVERRIDE;
195 virtual int height() const SK_OVERRIDE;
196 virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
197
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000198 virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
199 int width, int height,
junov@google.com4370aed2012-01-18 16:21:08 +0000200 bool isOpaque,
201 Usage usage) SK_OVERRIDE;
202
203 virtual void writePixels(const SkBitmap& bitmap, int x, int y,
204 SkCanvas::Config8888 config8888) SK_OVERRIDE;
205
206 protected:
junov@chromium.org1f9767c2012-02-07 16:27:57 +0000207 virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000208 virtual bool onReadPixels(const SkBitmap& bitmap,
209 int x, int y,
210 SkCanvas::Config8888 config8888) SK_OVERRIDE;
211
212 // The following methods are no-ops on a deferred device
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000213 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*)
junov@google.com4370aed2012-01-18 16:21:08 +0000214 SK_OVERRIDE
215 {return false;}
216 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
217 const SkClipStack&) SK_OVERRIDE
218 {}
219 virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
220 const SkClipStack&) SK_OVERRIDE
221 {}
222
223 // None of the following drawing methods should ever get called on the
224 // deferred device
225 virtual void clear(SkColor color)
226 {SkASSERT(0);}
227 virtual void drawPaint(const SkDraw&, const SkPaint& paint)
228 {SkASSERT(0);}
229 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
230 size_t count, const SkPoint[],
231 const SkPaint& paint)
232 {SkASSERT(0);}
233 virtual void drawRect(const SkDraw&, const SkRect& r,
234 const SkPaint& paint)
235 {SkASSERT(0);}
236 virtual void drawPath(const SkDraw&, const SkPath& path,
237 const SkPaint& paint,
238 const SkMatrix* prePathMatrix = NULL,
239 bool pathIsMutable = false)
240 {SkASSERT(0);}
241 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
242 const SkIRect* srcRectOrNull,
243 const SkMatrix& matrix, const SkPaint& paint)
244 {SkASSERT(0);}
245 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
246 int x, int y, const SkPaint& paint)
247 {SkASSERT(0);}
248 virtual void drawText(const SkDraw&, const void* text, size_t len,
249 SkScalar x, SkScalar y, const SkPaint& paint)
250 {SkASSERT(0);}
251 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
252 const SkScalar pos[], SkScalar constY,
253 int scalarsPerPos, const SkPaint& paint)
254 {SkASSERT(0);}
255 virtual void drawTextOnPath(const SkDraw&, const void* text,
256 size_t len, const SkPath& path,
257 const SkMatrix* matrix,
258 const SkPaint& paint)
259 {SkASSERT(0);}
260 virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
261 size_t len, const SkPoint pos[],
262 const SkPaint& paint,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000263 const SkPath& path,
junov@google.com4370aed2012-01-18 16:21:08 +0000264 const SkMatrix* matrix)
265 {SkASSERT(0);}
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000266 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
junov@google.com4370aed2012-01-18 16:21:08 +0000267 int vertexCount, const SkPoint verts[],
268 const SkPoint texs[], const SkColor colors[],
269 SkXfermode* xmode, const uint16_t indices[],
270 int indexCount, const SkPaint& paint)
271 {SkASSERT(0);}
272 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
273 const SkPaint&)
274 {SkASSERT(0);}
275 private:
276 virtual void flush();
277
278 SkPicture fPicture;
279 SkDevice* fImmediateDevice;
280 SkCanvas* fImmediateCanvas;
281 SkCanvas* fRecordingCanvas;
282 DeviceContext* fDeviceContext;
junov@chromium.org8f9ecbd2012-02-13 21:53:45 +0000283 bool fFreshFrame;
junov@google.com4370aed2012-01-18 16:21:08 +0000284 };
285
286 DeferredDevice* getDeferredDevice() const;
287
288protected:
289 virtual SkCanvas* canvasForDrawIter();
290
291private:
junov@google.com4370aed2012-01-18 16:21:08 +0000292 bool isFullFrame(const SkRect*, const SkPaint*) const;
293 void validate() const;
294 void init();
junov@chromium.orgfeba6892012-02-28 15:02:06 +0000295 SkCanvas* fDrawingCanvas; // This points to the recording or immediate
296 // canvas, based on fDeferredDrawing
297 bool fDeferredDrawing;
junov@google.com4370aed2012-01-18 16:21:08 +0000298
299 typedef SkCanvas INHERITED;
300};
301
302
303#endif