blob: 19d7141bc86ef73be27c5dfb122a6916b1fb4706 [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
184 void flushPending();
junov@google.com4370aed2012-01-18 16:21:08 +0000185 void purgePending();
186 void flushIfNeeded(const SkBitmap& bitmap);
187
188 virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
189 virtual int width() const SK_OVERRIDE;
190 virtual int height() const SK_OVERRIDE;
191 virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
192
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000193 virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
194 int width, int height,
junov@google.com4370aed2012-01-18 16:21:08 +0000195 bool isOpaque,
196 Usage usage) SK_OVERRIDE;
197
198 virtual void writePixels(const SkBitmap& bitmap, int x, int y,
199 SkCanvas::Config8888 config8888) SK_OVERRIDE;
200
201 protected:
junov@chromium.org1f9767c2012-02-07 16:27:57 +0000202 virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000203 virtual bool onReadPixels(const SkBitmap& bitmap,
204 int x, int y,
205 SkCanvas::Config8888 config8888) SK_OVERRIDE;
206
207 // The following methods are no-ops on a deferred device
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000208 virtual bool filterTextFlags(const SkPaint& paint, TextFlags*)
junov@google.com4370aed2012-01-18 16:21:08 +0000209 SK_OVERRIDE
210 {return false;}
211 virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
212 const SkClipStack&) SK_OVERRIDE
213 {}
214 virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
215 const SkClipStack&) SK_OVERRIDE
216 {}
217
218 // None of the following drawing methods should ever get called on the
219 // deferred device
220 virtual void clear(SkColor color)
221 {SkASSERT(0);}
222 virtual void drawPaint(const SkDraw&, const SkPaint& paint)
223 {SkASSERT(0);}
224 virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
225 size_t count, const SkPoint[],
226 const SkPaint& paint)
227 {SkASSERT(0);}
228 virtual void drawRect(const SkDraw&, const SkRect& r,
229 const SkPaint& paint)
230 {SkASSERT(0);}
231 virtual void drawPath(const SkDraw&, const SkPath& path,
232 const SkPaint& paint,
233 const SkMatrix* prePathMatrix = NULL,
234 bool pathIsMutable = false)
235 {SkASSERT(0);}
236 virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
237 const SkIRect* srcRectOrNull,
238 const SkMatrix& matrix, const SkPaint& paint)
239 {SkASSERT(0);}
240 virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
241 int x, int y, const SkPaint& paint)
242 {SkASSERT(0);}
243 virtual void drawText(const SkDraw&, const void* text, size_t len,
244 SkScalar x, SkScalar y, const SkPaint& paint)
245 {SkASSERT(0);}
246 virtual void drawPosText(const SkDraw&, const void* text, size_t len,
247 const SkScalar pos[], SkScalar constY,
248 int scalarsPerPos, const SkPaint& paint)
249 {SkASSERT(0);}
250 virtual void drawTextOnPath(const SkDraw&, const void* text,
251 size_t len, const SkPath& path,
252 const SkMatrix* matrix,
253 const SkPaint& paint)
254 {SkASSERT(0);}
255 virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
256 size_t len, const SkPoint pos[],
257 const SkPaint& paint,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000258 const SkPath& path,
junov@google.com4370aed2012-01-18 16:21:08 +0000259 const SkMatrix* matrix)
260 {SkASSERT(0);}
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000261 virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
junov@google.com4370aed2012-01-18 16:21:08 +0000262 int vertexCount, const SkPoint verts[],
263 const SkPoint texs[], const SkColor colors[],
264 SkXfermode* xmode, const uint16_t indices[],
265 int indexCount, const SkPaint& paint)
266 {SkASSERT(0);}
267 virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
268 const SkPaint&)
269 {SkASSERT(0);}
270 private:
271 virtual void flush();
272
273 SkPicture fPicture;
274 SkDevice* fImmediateDevice;
275 SkCanvas* fImmediateCanvas;
276 SkCanvas* fRecordingCanvas;
277 DeviceContext* fDeviceContext;
junov@chromium.org1f9767c2012-02-07 16:27:57 +0000278 bool fBitmapInitialized;
junov@google.com4370aed2012-01-18 16:21:08 +0000279 };
280
281 DeferredDevice* getDeferredDevice() const;
282
283protected:
284 virtual SkCanvas* canvasForDrawIter();
285
286private:
287 SkCanvas* drawingCanvas() const;
288 bool isFullFrame(const SkRect*, const SkPaint*) const;
289 void validate() const;
290 void init();
291 bool fDeferredDrawing;
292
293 typedef SkCanvas INHERITED;
294};
295
296
297#endif