blob: ed7ec00adc4233d6bbce045e0eef808893fae055 [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
36 /** Construct a canvas with the specified device to draw into, and
37 * a device context. Equivalent to calling default constructor, then
junov@chromium.org9ed02b92012-08-14 13:36:26 +000038 * setDevice. The canvas takes reference on the device and notification
39 * client.
junov@google.com4370aed2012-01-18 16:21:08 +000040 * @param device Specifies a device for the canvas to draw into.
junov@chromium.org9ed02b92012-08-14 13:36:26 +000041 * @param client Interface for dispatching notifications
junov@google.com4370aed2012-01-18 16:21:08 +000042 */
junov@chromium.org9ed02b92012-08-14 13:36:26 +000043 explicit SkDeferredCanvas(SkDevice* device, NotificationClient* client);
junov@google.com4370aed2012-01-18 16:21:08 +000044
45 virtual ~SkDeferredCanvas();
46
47 /**
48 * Specify a device to be used by this canvas. Calling setDevice will
junov@chromium.org9ed02b92012-08-14 13:36:26 +000049 * release the previously set device, if any. Takes a reference on the
50 * device.
junov@google.com4370aed2012-01-18 16:21:08 +000051 *
52 * @param device The device that the canvas will raw into
53 * @return The device argument, for convenience.
54 */
55 virtual SkDevice* setDevice(SkDevice* device);
56
57 /**
junov@chromium.org9ed02b92012-08-14 13:36:26 +000058 * Specify a NotificationClient to be used by this canvas. Calling
59 * setNotificationClient will release the previously set
60 * NotificationClient, if any. Takes a reference on the notification
61 * client.
junov@google.com4370aed2012-01-18 16:21:08 +000062 * Note: Must be called after the device is set with setDevice.
63 *
junov@chromium.org9ed02b92012-08-14 13:36:26 +000064 * @param notificationClient interface for dispatching notifications
65 * @return The notificationClient argument, for convenience.
junov@google.com4370aed2012-01-18 16:21:08 +000066 */
junov@chromium.org9ed02b92012-08-14 13:36:26 +000067 NotificationClient* setNotificationClient(NotificationClient* notificationClient);
68 // Temporarily bootstrapping the deprecated method name
69 NotificationClient* setDeviceContext(NotificationClient* notificationClient) {
70 return setNotificationClient(notificationClient);
71 }
junov@google.com4370aed2012-01-18 16:21:08 +000072
73 /**
74 * Enable or disable deferred drawing. When deferral is disabled,
75 * pending draw operations are immediately flushed and from then on,
76 * the SkDeferredCanvas behaves just like a regular SkCanvas.
77 * This method must not be called while the save/restore stack is in use.
78 * @param deferred true/false
79 */
80 void setDeferredDrawing(bool deferred);
81
junov@chromium.orgbfeddae2012-07-23 13:35:14 +000082 /**
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000083 * Returns true if deferred drawing is currenlty enabled.
84 */
junov@chromium.org88e29142012-08-07 16:48:22 +000085 bool isDeferredDrawing() const;
86
87 /**
88 * Returns true if the canvas contains a fresh frame. A frame is
89 * considered fresh when its content do not depend on the contents
90 * of the previous frame. For example, if a canvas is cleared before
91 * drawing each frame, the frames will all be considered fresh.
92 * A frame is defined as the graphics image produced by as a result
93 * of all the canvas draws operation executed between two successive
94 * calls to isFreshFrame. The result of isFreshFrame is computed
95 * conservatively, so it may report false negatives.
96 */
97 bool isFreshFrame() const;
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000098
99 /**
junov@chromium.orgbfeddae2012-07-23 13:35:14 +0000100 * Specify the maximum number of bytes to be allocated for the purpose
101 * of recording draw commands to this canvas. The default limit, is
102 * 64MB.
103 * @param maxStorage The maximum number of bytes to be allocated.
104 */
105 void setMaxRecordingStorage(size_t maxStorage);
106
junov@chromium.org2e14ba82012-08-07 14:26:57 +0000107 /**
108 * Returns the number of bytes currently allocated for the purpose of
109 * recording draw commands.
110 */
111 size_t storageAllocatedForRecording() const;
112
113 /**
114 * Attempt to reduce the storage allocated for recording by evicting
115 * cache resources.
116 * @param bytesToFree minimum number of bytes that should be attempted to
117 * be freed.
118 * @return number of bytes actually freed.
119 */
120 size_t freeMemoryIfPossible(size_t bytesToFree);
121
junov@google.com4370aed2012-01-18 16:21:08 +0000122 // Overrides of the SkCanvas interface
123 virtual int save(SaveFlags flags) SK_OVERRIDE;
124 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
125 SaveFlags flags) SK_OVERRIDE;
126 virtual void restore() SK_OVERRIDE;
junov@chromium.orga907ac32012-02-24 21:54:07 +0000127 virtual bool isDrawingToLayer() const SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000128 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
129 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
130 virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
131 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
132 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
133 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000134 virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
135 bool doAntiAlias) SK_OVERRIDE;
136 virtual bool clipPath(const SkPath& path, SkRegion::Op op,
137 bool doAntiAlias) SK_OVERRIDE;
138 virtual bool clipRegion(const SkRegion& deviceRgn,
139 SkRegion::Op op) SK_OVERRIDE;
140 virtual void clear(SkColor) SK_OVERRIDE;
141 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
142 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
143 const SkPaint& paint) SK_OVERRIDE;
144 virtual void drawRect(const SkRect& rect, const SkPaint& paint)
145 SK_OVERRIDE;
146 virtual void drawPath(const SkPath& path, const SkPaint& paint)
147 SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000148 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
junov@google.com4370aed2012-01-18 16:21:08 +0000149 SkScalar top, const SkPaint* paint)
150 SK_OVERRIDE;
151 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
152 const SkRect& dst, const SkPaint* paint)
153 SK_OVERRIDE;
154
155 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
156 const SkPaint* paint) SK_OVERRIDE;
157 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
158 const SkRect& dst, const SkPaint* paint)
159 SK_OVERRIDE;
160 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
161 const SkPaint* paint) SK_OVERRIDE;
162 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
163 SkScalar y, const SkPaint& paint) SK_OVERRIDE;
164 virtual void drawPosText(const void* text, size_t byteLength,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000165 const SkPoint pos[], const SkPaint& paint)
junov@google.com4370aed2012-01-18 16:21:08 +0000166 SK_OVERRIDE;
167 virtual void drawPosTextH(const void* text, size_t byteLength,
168 const SkScalar xpos[], SkScalar constY,
169 const SkPaint& paint) SK_OVERRIDE;
170 virtual void drawTextOnPath(const void* text, size_t byteLength,
171 const SkPath& path, const SkMatrix* matrix,
172 const SkPaint& paint) SK_OVERRIDE;
173 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
174 virtual void drawVertices(VertexMode vmode, int vertexCount,
175 const SkPoint vertices[], const SkPoint texs[],
176 const SkColor colors[], SkXfermode* xmode,
177 const uint16_t indices[], int indexCount,
178 const SkPaint& paint) SK_OVERRIDE;
179 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
180 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
181
junov@google.com4370aed2012-01-18 16:21:08 +0000182public:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000183 class NotificationClient : public SkRefCnt {
junov@google.com4370aed2012-01-18 16:21:08 +0000184 public:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000185 SK_DECLARE_INST_COUNT(NotificationClient)
reed@google.com563a3b42012-06-26 19:24:50 +0000186
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000187 /**
188 * Called before executing one or several draw commands, which means
189 * once per flush when deferred rendering is enabled.
190 */
junov@google.com4370aed2012-01-18 16:21:08 +0000191 virtual void prepareForDraw() {}
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000192
193 /**
194 * Called after a recording a draw command if additional memory
195 * had to be allocated for recording.
196 * @param newAllocatedStorage same value as would be returned by
197 * storageAllocatedForRecording(), for convenience.
198 */
199 virtual void storageAllocatedForRecordingChanged(
200 size_t newAllocatedStorage) {}
201
202 /**
203 * Called after pending draw commands have been flushed
204 */
205 virtual void flushedDrawCommands() {}
reed@google.com563a3b42012-06-26 19:24:50 +0000206
207 private:
208 typedef SkRefCnt INHERITED;
junov@google.com4370aed2012-01-18 16:21:08 +0000209 };
210
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000211 // Temporarily bootstrapping the deprecated name for a smooth chromium DEPS roll
212 typedef NotificationClient DeviceContext;
213
junov@chromium.org77eec242012-07-18 17:54:45 +0000214protected:
junov@google.com4370aed2012-01-18 16:21:08 +0000215 virtual SkCanvas* canvasForDrawIter();
junov@chromium.org88e29142012-08-07 16:48:22 +0000216 DeferredDevice* getDeferredDevice() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000217
218private:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000219 void recordedDrawCommand();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000220 SkCanvas* drawingCanvas() const;
junov@chromium.org88e29142012-08-07 16:48:22 +0000221 SkCanvas* immediateCanvas() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000222 bool isFullFrame(const SkRect*, const SkPaint*) const;
223 void validate() const;
224 void init();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000225 bool fDeferredDrawing;
junov@google.com4370aed2012-01-18 16:21:08 +0000226
junov@chromium.org88e29142012-08-07 16:48:22 +0000227 friend class SkDeferredCanvasTester; // for unit testing
junov@google.com4370aed2012-01-18 16:21:08 +0000228 typedef SkCanvas INHERITED;
229};
230
231
232#endif