blob: f5674d1d45c0ca8c218068834191643d9c88678d [file] [log] [blame]
junov@google.com4370aed2012-01-18 16:21:08 +00001/*
junov@chromium.org9ed02b92012-08-14 13:36:26 +00002 * Copyright 2012 Google Inc.
junov@google.com4370aed2012-01-18 16:21:08 +00003 *
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"
junov@google.com4370aed2012-01-18 16:21:08 +000012#include "SkPixelRef.h"
13
junov@chromium.org88e29142012-08-07 16:48:22 +000014class DeferredDevice;
junov@chromium.org77eec242012-07-18 17:54:45 +000015
junov@google.com4370aed2012-01-18 16:21:08 +000016/** \class SkDeferredCanvas
junov@chromium.org77eec242012-07-18 17:54:45 +000017 Subclass of SkCanvas that encapsulates an SkPicture or SkGPipe for deferred
18 drawing. The main difference between this class and SkPictureRecord (the
19 canvas provided by SkPicture) is that this is a full drop-in replacement
20 for SkCanvas, while SkPictureRecord only supports draw operations.
junov@google.com4370aed2012-01-18 16:21:08 +000021 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:
junov@chromium.org9ed02b92012-08-14 13:36:26 +000026 class NotificationClient;
junov@google.com4370aed2012-01-18 16:21:08 +000027
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
junov@google.com4370aed2012-01-18 16:21:08 +000036 virtual ~SkDeferredCanvas();
37
38 /**
39 * Specify a device to be used by this canvas. Calling setDevice will
junov@chromium.org9ed02b92012-08-14 13:36:26 +000040 * release the previously set device, if any. Takes a reference on the
41 * device.
junov@google.com4370aed2012-01-18 16:21:08 +000042 *
43 * @param device The device that the canvas will raw into
44 * @return The device argument, for convenience.
45 */
46 virtual SkDevice* setDevice(SkDevice* device);
47
48 /**
junov@chromium.org9ed02b92012-08-14 13:36:26 +000049 * Specify a NotificationClient to be used by this canvas. Calling
rmistry@google.comfbfcd562012-08-23 18:09:54 +000050 * setNotificationClient will release the previously set
junov@chromium.org52805482012-08-20 14:25:04 +000051 * NotificationClient, if any. SkDeferredCanvas does not take ownership
52 * of the notification client. Therefore user code is resposible
53 * for its destruction. The notification client must be unregistered
54 * by calling setNotificationClient(NULL) if it is destroyed before
55 * this canvas.
junov@google.com4370aed2012-01-18 16:21:08 +000056 * Note: Must be called after the device is set with setDevice.
57 *
junov@chromium.org9ed02b92012-08-14 13:36:26 +000058 * @param notificationClient interface for dispatching notifications
59 * @return The notificationClient argument, for convenience.
junov@google.com4370aed2012-01-18 16:21:08 +000060 */
junov@chromium.org9ed02b92012-08-14 13:36:26 +000061 NotificationClient* setNotificationClient(NotificationClient* notificationClient);
junov@google.com4370aed2012-01-18 16:21:08 +000062
63 /**
64 * Enable or disable deferred drawing. When deferral is disabled,
65 * pending draw operations are immediately flushed and from then on,
66 * the SkDeferredCanvas behaves just like a regular SkCanvas.
67 * This method must not be called while the save/restore stack is in use.
68 * @param deferred true/false
69 */
70 void setDeferredDrawing(bool deferred);
71
junov@chromium.orgbfeddae2012-07-23 13:35:14 +000072 /**
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000073 * Returns true if deferred drawing is currenlty enabled.
74 */
junov@chromium.org88e29142012-08-07 16:48:22 +000075 bool isDeferredDrawing() const;
76
77 /**
rmistry@google.comfbfcd562012-08-23 18:09:54 +000078 * Returns true if the canvas contains a fresh frame. A frame is
junov@chromium.org88e29142012-08-07 16:48:22 +000079 * considered fresh when its content do not depend on the contents
80 * of the previous frame. For example, if a canvas is cleared before
81 * drawing each frame, the frames will all be considered fresh.
82 * A frame is defined as the graphics image produced by as a result
83 * of all the canvas draws operation executed between two successive
84 * calls to isFreshFrame. The result of isFreshFrame is computed
85 * conservatively, so it may report false negatives.
86 */
87 bool isFreshFrame() const;
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000088
89 /**
junov@chromium.orga38dfb62012-09-20 22:10:33 +000090 * Returns true if the canvas has recorded draw commands that have
91 * not yet been played back.
92 */
93 bool hasPendingCommands() const;
94
95 /**
junov@chromium.orgbfeddae2012-07-23 13:35:14 +000096 * Specify the maximum number of bytes to be allocated for the purpose
97 * of recording draw commands to this canvas. The default limit, is
98 * 64MB.
99 * @param maxStorage The maximum number of bytes to be allocated.
100 */
101 void setMaxRecordingStorage(size_t maxStorage);
102
junov@chromium.org2e14ba82012-08-07 14:26:57 +0000103 /**
104 * Returns the number of bytes currently allocated for the purpose of
105 * recording draw commands.
106 */
107 size_t storageAllocatedForRecording() const;
108
109 /**
110 * Attempt to reduce the storage allocated for recording by evicting
111 * cache resources.
112 * @param bytesToFree minimum number of bytes that should be attempted to
113 * be freed.
114 * @return number of bytes actually freed.
115 */
116 size_t freeMemoryIfPossible(size_t bytesToFree);
117
junov@chromium.orgfb103892012-09-20 19:35:43 +0000118 /**
119 * Executes all pending commands without drawing
120 */
121 void silentFlush();
122
junov@google.com4370aed2012-01-18 16:21:08 +0000123 // Overrides of the SkCanvas interface
124 virtual int save(SaveFlags flags) SK_OVERRIDE;
125 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
126 SaveFlags flags) SK_OVERRIDE;
127 virtual void restore() SK_OVERRIDE;
junov@chromium.orga907ac32012-02-24 21:54:07 +0000128 virtual bool isDrawingToLayer() const SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000129 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
130 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
131 virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
132 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
133 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
134 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000135 virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
136 bool doAntiAlias) SK_OVERRIDE;
137 virtual bool clipPath(const SkPath& path, SkRegion::Op op,
138 bool doAntiAlias) SK_OVERRIDE;
139 virtual bool clipRegion(const SkRegion& deviceRgn,
140 SkRegion::Op op) SK_OVERRIDE;
141 virtual void clear(SkColor) SK_OVERRIDE;
142 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
143 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
144 const SkPaint& paint) SK_OVERRIDE;
145 virtual void drawRect(const SkRect& rect, const SkPaint& paint)
146 SK_OVERRIDE;
147 virtual void drawPath(const SkPath& path, const SkPaint& paint)
148 SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000149 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
junov@google.com4370aed2012-01-18 16:21:08 +0000150 SkScalar top, const SkPaint* paint)
151 SK_OVERRIDE;
reed@google.com71121732012-09-18 15:14:33 +0000152 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
junov@google.com4370aed2012-01-18 16:21:08 +0000153 const SkRect& dst, const SkPaint* paint)
154 SK_OVERRIDE;
155
156 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
157 const SkPaint* paint) SK_OVERRIDE;
158 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
159 const SkRect& dst, const SkPaint* paint)
160 SK_OVERRIDE;
161 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
162 const SkPaint* paint) SK_OVERRIDE;
163 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
164 SkScalar y, const SkPaint& paint) SK_OVERRIDE;
165 virtual void drawPosText(const void* text, size_t byteLength,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000166 const SkPoint pos[], const SkPaint& paint)
junov@google.com4370aed2012-01-18 16:21:08 +0000167 SK_OVERRIDE;
168 virtual void drawPosTextH(const void* text, size_t byteLength,
169 const SkScalar xpos[], SkScalar constY,
170 const SkPaint& paint) SK_OVERRIDE;
171 virtual void drawTextOnPath(const void* text, size_t byteLength,
172 const SkPath& path, const SkMatrix* matrix,
173 const SkPaint& paint) SK_OVERRIDE;
174 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
175 virtual void drawVertices(VertexMode vmode, int vertexCount,
176 const SkPoint vertices[], const SkPoint texs[],
177 const SkColor colors[], SkXfermode* xmode,
178 const uint16_t indices[], int indexCount,
179 const SkPaint& paint) SK_OVERRIDE;
180 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
181 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
182
junov@google.com4370aed2012-01-18 16:21:08 +0000183public:
junov@chromium.org52805482012-08-20 14:25:04 +0000184 class NotificationClient {
junov@google.com4370aed2012-01-18 16:21:08 +0000185 public:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000186 /**
187 * Called before executing one or several draw commands, which means
188 * once per flush when deferred rendering is enabled.
189 */
junov@google.com4370aed2012-01-18 16:21:08 +0000190 virtual void prepareForDraw() {}
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000191
192 /**
193 * Called after a recording a draw command if additional memory
194 * had to be allocated for recording.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000195 * @param newAllocatedStorage same value as would be returned by
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000196 * storageAllocatedForRecording(), for convenience.
197 */
198 virtual void storageAllocatedForRecordingChanged(
199 size_t newAllocatedStorage) {}
200
201 /**
202 * Called after pending draw commands have been flushed
203 */
204 virtual void flushedDrawCommands() {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000205
reed@google.com563a3b42012-06-26 19:24:50 +0000206 private:
207 typedef SkRefCnt INHERITED;
junov@google.com4370aed2012-01-18 16:21:08 +0000208 };
209
junov@chromium.org77eec242012-07-18 17:54:45 +0000210protected:
junov@google.com4370aed2012-01-18 16:21:08 +0000211 virtual SkCanvas* canvasForDrawIter();
junov@chromium.org88e29142012-08-07 16:48:22 +0000212 DeferredDevice* getDeferredDevice() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000213
214private:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000215 void recordedDrawCommand();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000216 SkCanvas* drawingCanvas() const;
junov@chromium.org88e29142012-08-07 16:48:22 +0000217 SkCanvas* immediateCanvas() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000218 bool isFullFrame(const SkRect*, const SkPaint*) const;
219 void validate() const;
220 void init();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000221 bool fDeferredDrawing;
junov@google.com4370aed2012-01-18 16:21:08 +0000222
junov@chromium.org88e29142012-08-07 16:48:22 +0000223 friend class SkDeferredCanvasTester; // for unit testing
junov@google.com4370aed2012-01-18 16:21:08 +0000224 typedef SkCanvas INHERITED;
225};
226
227
228#endif