blob: f5313713eccb06c27f08abba191ce8c93d3ea911 [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
50 * setNotificationClient will release the previously set
51 * NotificationClient, if any. Takes a reference on the notification
52 * client.
junov@google.com4370aed2012-01-18 16:21:08 +000053 * Note: Must be called after the device is set with setDevice.
54 *
junov@chromium.org9ed02b92012-08-14 13:36:26 +000055 * @param notificationClient interface for dispatching notifications
56 * @return The notificationClient argument, for convenience.
junov@google.com4370aed2012-01-18 16:21:08 +000057 */
junov@chromium.org9ed02b92012-08-14 13:36:26 +000058 NotificationClient* setNotificationClient(NotificationClient* notificationClient);
junov@google.com4370aed2012-01-18 16:21:08 +000059
60 /**
61 * Enable or disable deferred drawing. When deferral is disabled,
62 * pending draw operations are immediately flushed and from then on,
63 * the SkDeferredCanvas behaves just like a regular SkCanvas.
64 * This method must not be called while the save/restore stack is in use.
65 * @param deferred true/false
66 */
67 void setDeferredDrawing(bool deferred);
68
junov@chromium.orgbfeddae2012-07-23 13:35:14 +000069 /**
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000070 * Returns true if deferred drawing is currenlty enabled.
71 */
junov@chromium.org88e29142012-08-07 16:48:22 +000072 bool isDeferredDrawing() const;
73
74 /**
75 * Returns true if the canvas contains a fresh frame. A frame is
76 * considered fresh when its content do not depend on the contents
77 * of the previous frame. For example, if a canvas is cleared before
78 * drawing each frame, the frames will all be considered fresh.
79 * A frame is defined as the graphics image produced by as a result
80 * of all the canvas draws operation executed between two successive
81 * calls to isFreshFrame. The result of isFreshFrame is computed
82 * conservatively, so it may report false negatives.
83 */
84 bool isFreshFrame() const;
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000085
86 /**
junov@chromium.orgbfeddae2012-07-23 13:35:14 +000087 * Specify the maximum number of bytes to be allocated for the purpose
88 * of recording draw commands to this canvas. The default limit, is
89 * 64MB.
90 * @param maxStorage The maximum number of bytes to be allocated.
91 */
92 void setMaxRecordingStorage(size_t maxStorage);
93
junov@chromium.org2e14ba82012-08-07 14:26:57 +000094 /**
95 * Returns the number of bytes currently allocated for the purpose of
96 * recording draw commands.
97 */
98 size_t storageAllocatedForRecording() const;
99
100 /**
101 * Attempt to reduce the storage allocated for recording by evicting
102 * cache resources.
103 * @param bytesToFree minimum number of bytes that should be attempted to
104 * be freed.
105 * @return number of bytes actually freed.
106 */
107 size_t freeMemoryIfPossible(size_t bytesToFree);
108
junov@google.com4370aed2012-01-18 16:21:08 +0000109 // Overrides of the SkCanvas interface
110 virtual int save(SaveFlags flags) SK_OVERRIDE;
111 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
112 SaveFlags flags) SK_OVERRIDE;
113 virtual void restore() SK_OVERRIDE;
junov@chromium.orga907ac32012-02-24 21:54:07 +0000114 virtual bool isDrawingToLayer() const SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000115 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
116 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
117 virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
118 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
119 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
120 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000121 virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
122 bool doAntiAlias) SK_OVERRIDE;
123 virtual bool clipPath(const SkPath& path, SkRegion::Op op,
124 bool doAntiAlias) SK_OVERRIDE;
125 virtual bool clipRegion(const SkRegion& deviceRgn,
126 SkRegion::Op op) SK_OVERRIDE;
127 virtual void clear(SkColor) SK_OVERRIDE;
128 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
129 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
130 const SkPaint& paint) SK_OVERRIDE;
131 virtual void drawRect(const SkRect& rect, const SkPaint& paint)
132 SK_OVERRIDE;
133 virtual void drawPath(const SkPath& path, const SkPaint& paint)
134 SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000135 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
junov@google.com4370aed2012-01-18 16:21:08 +0000136 SkScalar top, const SkPaint* paint)
137 SK_OVERRIDE;
138 virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
139 const SkRect& dst, const SkPaint* paint)
140 SK_OVERRIDE;
141
142 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
143 const SkPaint* paint) SK_OVERRIDE;
144 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
145 const SkRect& dst, const SkPaint* paint)
146 SK_OVERRIDE;
147 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
148 const SkPaint* paint) SK_OVERRIDE;
149 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
150 SkScalar y, const SkPaint& paint) SK_OVERRIDE;
151 virtual void drawPosText(const void* text, size_t byteLength,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000152 const SkPoint pos[], const SkPaint& paint)
junov@google.com4370aed2012-01-18 16:21:08 +0000153 SK_OVERRIDE;
154 virtual void drawPosTextH(const void* text, size_t byteLength,
155 const SkScalar xpos[], SkScalar constY,
156 const SkPaint& paint) SK_OVERRIDE;
157 virtual void drawTextOnPath(const void* text, size_t byteLength,
158 const SkPath& path, const SkMatrix* matrix,
159 const SkPaint& paint) SK_OVERRIDE;
160 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
161 virtual void drawVertices(VertexMode vmode, int vertexCount,
162 const SkPoint vertices[], const SkPoint texs[],
163 const SkColor colors[], SkXfermode* xmode,
164 const uint16_t indices[], int indexCount,
165 const SkPaint& paint) SK_OVERRIDE;
166 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
167 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
168
junov@google.com4370aed2012-01-18 16:21:08 +0000169public:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000170 class NotificationClient : public SkRefCnt {
junov@google.com4370aed2012-01-18 16:21:08 +0000171 public:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000172 SK_DECLARE_INST_COUNT(NotificationClient)
reed@google.com563a3b42012-06-26 19:24:50 +0000173
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000174 /**
175 * Called before executing one or several draw commands, which means
176 * once per flush when deferred rendering is enabled.
177 */
junov@google.com4370aed2012-01-18 16:21:08 +0000178 virtual void prepareForDraw() {}
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000179
180 /**
181 * Called after a recording a draw command if additional memory
182 * had to be allocated for recording.
183 * @param newAllocatedStorage same value as would be returned by
184 * storageAllocatedForRecording(), for convenience.
185 */
186 virtual void storageAllocatedForRecordingChanged(
187 size_t newAllocatedStorage) {}
188
189 /**
190 * Called after pending draw commands have been flushed
191 */
192 virtual void flushedDrawCommands() {}
reed@google.com563a3b42012-06-26 19:24:50 +0000193
194 private:
195 typedef SkRefCnt INHERITED;
junov@google.com4370aed2012-01-18 16:21:08 +0000196 };
197
junov@chromium.org77eec242012-07-18 17:54:45 +0000198protected:
junov@google.com4370aed2012-01-18 16:21:08 +0000199 virtual SkCanvas* canvasForDrawIter();
junov@chromium.org88e29142012-08-07 16:48:22 +0000200 DeferredDevice* getDeferredDevice() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000201
202private:
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000203 void recordedDrawCommand();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000204 SkCanvas* drawingCanvas() const;
junov@chromium.org88e29142012-08-07 16:48:22 +0000205 SkCanvas* immediateCanvas() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000206 bool isFullFrame(const SkRect*, const SkPaint*) const;
207 void validate() const;
208 void init();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000209 bool fDeferredDrawing;
junov@google.com4370aed2012-01-18 16:21:08 +0000210
junov@chromium.org88e29142012-08-07 16:48:22 +0000211 friend class SkDeferredCanvasTester; // for unit testing
junov@google.com4370aed2012-01-18 16:21:08 +0000212 typedef SkCanvas INHERITED;
213};
214
215
216#endif