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