blob: e82cad3ab1fe294910ae814135bb90fddb5e9f65 [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
reed@google.com9c135db2014-03-12 18:28:35 +000014class SkDeferredDevice;
junov@chromium.org67d74222013-04-12 13:33:01 +000015class SkImage;
16class SkSurface;
junov@chromium.org77eec242012-07-18 17:54:45 +000017
junov@google.com4370aed2012-01-18 16:21:08 +000018/** \class SkDeferredCanvas
junov@chromium.org77eec242012-07-18 17:54:45 +000019 Subclass of SkCanvas that encapsulates an SkPicture or SkGPipe for deferred
20 drawing. The main difference between this class and SkPictureRecord (the
21 canvas provided by SkPicture) is that this is a full drop-in replacement
22 for SkCanvas, while SkPictureRecord only supports draw operations.
junov@google.com4370aed2012-01-18 16:21:08 +000023 SkDeferredCanvas will transparently trigger the flushing of deferred
vandebo@chromium.org74b46192012-01-28 01:45:11 +000024 draw operations when an attempt is made to access the pixel data.
junov@google.com4370aed2012-01-18 16:21:08 +000025*/
26class SK_API SkDeferredCanvas : public SkCanvas {
27public:
commit-bot@chromium.orgeddb02c2013-11-25 15:44:37 +000028 class SK_API NotificationClient;
junov@google.com4370aed2012-01-18 16:21:08 +000029
junov@chromium.org66070a52013-05-28 17:39:08 +000030 /** Construct a canvas with the specified surface to draw into.
31 This factory must be used for newImageSnapshot to work.
32 @param surface Specifies a surface for the canvas to draw into.
33 */
34 static SkDeferredCanvas* Create(SkSurface* surface);
35
reed@google.com28183b42014-02-04 15:34:10 +000036// static SkDeferredCanvas* Create(SkBaseDevice* device);
junov@chromium.org67d74222013-04-12 13:33:01 +000037
junov@google.com4370aed2012-01-18 16:21:08 +000038 virtual ~SkDeferredCanvas();
39
junov@google.com4370aed2012-01-18 16:21:08 +000040 /**
junov@chromium.org7070f762013-05-24 17:13:00 +000041 * Specify the surface to be used by this canvas. Calling setSurface will
42 * release the previously set surface or device. Takes a reference on the
43 * surface.
44 *
45 * @param surface The surface that the canvas will raw into
46 * @return The surface argument, for convenience.
47 */
48 SkSurface* setSurface(SkSurface* surface);
49
50 /**
junov@chromium.org9ed02b92012-08-14 13:36:26 +000051 * Specify a NotificationClient to be used by this canvas. Calling
rmistry@google.comfbfcd562012-08-23 18:09:54 +000052 * setNotificationClient will release the previously set
junov@chromium.org52805482012-08-20 14:25:04 +000053 * NotificationClient, if any. SkDeferredCanvas does not take ownership
54 * of the notification client. Therefore user code is resposible
55 * for its destruction. The notification client must be unregistered
56 * by calling setNotificationClient(NULL) if it is destroyed before
57 * this canvas.
junov@google.com4370aed2012-01-18 16:21:08 +000058 * Note: Must be called after the device is set with setDevice.
59 *
junov@chromium.org9ed02b92012-08-14 13:36:26 +000060 * @param notificationClient interface for dispatching notifications
61 * @return The notificationClient argument, for convenience.
junov@google.com4370aed2012-01-18 16:21:08 +000062 */
junov@chromium.org9ed02b92012-08-14 13:36:26 +000063 NotificationClient* setNotificationClient(NotificationClient* notificationClient);
junov@google.com4370aed2012-01-18 16:21:08 +000064
65 /**
66 * Enable or disable deferred drawing. When deferral is disabled,
67 * pending draw operations are immediately flushed and from then on,
68 * the SkDeferredCanvas behaves just like a regular SkCanvas.
69 * This method must not be called while the save/restore stack is in use.
70 * @param deferred true/false
71 */
72 void setDeferredDrawing(bool deferred);
73
junov@chromium.orgbfeddae2012-07-23 13:35:14 +000074 /**
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000075 * Returns true if deferred drawing is currenlty enabled.
76 */
junov@chromium.org88e29142012-08-07 16:48:22 +000077 bool isDeferredDrawing() const;
78
79 /**
rmistry@google.comfbfcd562012-08-23 18:09:54 +000080 * Returns true if the canvas contains a fresh frame. A frame is
junov@chromium.org88e29142012-08-07 16:48:22 +000081 * considered fresh when its content do not depend on the contents
82 * of the previous frame. For example, if a canvas is cleared before
83 * drawing each frame, the frames will all be considered fresh.
84 * A frame is defined as the graphics image produced by as a result
85 * of all the canvas draws operation executed between two successive
86 * calls to isFreshFrame. The result of isFreshFrame is computed
87 * conservatively, so it may report false negatives.
88 */
89 bool isFreshFrame() const;
junov@chromium.orgb10a6bd2012-07-25 17:27:13 +000090
91 /**
junov@chromium.orga38dfb62012-09-20 22:10:33 +000092 * Returns true if the canvas has recorded draw commands that have
93 * not yet been played back.
94 */
95 bool hasPendingCommands() const;
96
97 /**
junov@chromium.org67d74222013-04-12 13:33:01 +000098 * Flushes pending draw commands, if any, and returns an image of the
99 * current state of the surface pixels up to this point. Subsequent
100 * changes to the surface (by drawing into its canvas) will not be
101 * reflected in this image. Will return NULL if the deferred canvas
102 * was not constructed from an SkSurface.
103 */
junov@chromium.org5ee449a2013-04-12 20:20:50 +0000104 SkImage* newImageSnapshot();
junov@chromium.org67d74222013-04-12 13:33:01 +0000105
106 /**
junov@chromium.orgbfeddae2012-07-23 13:35:14 +0000107 * Specify the maximum number of bytes to be allocated for the purpose
108 * of recording draw commands to this canvas. The default limit, is
109 * 64MB.
110 * @param maxStorage The maximum number of bytes to be allocated.
111 */
112 void setMaxRecordingStorage(size_t maxStorage);
113
junov@chromium.org2e14ba82012-08-07 14:26:57 +0000114 /**
115 * Returns the number of bytes currently allocated for the purpose of
116 * recording draw commands.
117 */
118 size_t storageAllocatedForRecording() const;
119
120 /**
121 * Attempt to reduce the storage allocated for recording by evicting
122 * cache resources.
123 * @param bytesToFree minimum number of bytes that should be attempted to
124 * be freed.
125 * @return number of bytes actually freed.
126 */
127 size_t freeMemoryIfPossible(size_t bytesToFree);
128
junov@chromium.orgfb103892012-09-20 19:35:43 +0000129 /**
sugoi@google.com7775fd52012-11-21 15:47:04 +0000130 * Specifies the maximum size (in bytes) allowed for a given image to be
131 * rendered using the deferred canvas.
132 */
133 void setBitmapSizeThreshold(size_t sizeThreshold);
134
135 /**
junov@chromium.orgfb103892012-09-20 19:35:43 +0000136 * Executes all pending commands without drawing
137 */
138 void silentFlush();
139
junov@google.com4370aed2012-01-18 16:21:08 +0000140 // Overrides of the SkCanvas interface
commit-bot@chromium.org069a55a2014-03-12 15:08:22 +0000141 virtual int save(SaveFlags flags) SK_OVERRIDE;
142 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
143 SaveFlags flags) SK_OVERRIDE;
144 virtual void restore() SK_OVERRIDE;
junov@chromium.orga907ac32012-02-24 21:54:07 +0000145 virtual bool isDrawingToLayer() const SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000146 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
147 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
148 virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
149 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
150 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
151 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000152 virtual void clear(SkColor) SK_OVERRIDE;
153 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
154 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
155 const SkPaint& paint) SK_OVERRIDE;
reed@google.com4ed0fb72012-12-12 20:48:18 +0000156 virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
bsalomon@google.com7ce564c2013-10-22 16:54:15 +0000157 virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
reed@google.com4ed0fb72012-12-12 20:48:18 +0000158 virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
bsalomon@google.com7ce564c2013-10-22 16:54:15 +0000159 virtual void drawPath(const SkPath& path, const SkPaint& paint)
160 SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000161 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
junov@google.com4370aed2012-01-18 16:21:08 +0000162 SkScalar top, const SkPaint* paint)
163 SK_OVERRIDE;
reed@google.com71121732012-09-18 15:14:33 +0000164 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +0000165 const SkRect& dst, const SkPaint* paint,
166 DrawBitmapRectFlags flags) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000167
168 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
169 const SkPaint* paint) SK_OVERRIDE;
170 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
171 const SkRect& dst, const SkPaint* paint)
172 SK_OVERRIDE;
173 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
174 const SkPaint* paint) SK_OVERRIDE;
175 virtual void drawText(const void* text, size_t byteLength, SkScalar x,
176 SkScalar y, const SkPaint& paint) SK_OVERRIDE;
177 virtual void drawPosText(const void* text, size_t byteLength,
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000178 const SkPoint pos[], const SkPaint& paint)
junov@google.com4370aed2012-01-18 16:21:08 +0000179 SK_OVERRIDE;
180 virtual void drawPosTextH(const void* text, size_t byteLength,
181 const SkScalar xpos[], SkScalar constY,
182 const SkPaint& paint) SK_OVERRIDE;
183 virtual void drawTextOnPath(const void* text, size_t byteLength,
184 const SkPath& path, const SkMatrix* matrix,
185 const SkPaint& paint) SK_OVERRIDE;
186 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
187 virtual void drawVertices(VertexMode vmode, int vertexCount,
188 const SkPoint vertices[], const SkPoint texs[],
189 const SkColor colors[], SkXfermode* xmode,
190 const uint16_t indices[], int indexCount,
191 const SkPaint& paint) SK_OVERRIDE;
192 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
193 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
194
commit-bot@chromium.orgab582732014-02-21 12:20:45 +0000195protected:
196 virtual void onDrawDRRect(const SkRRect&, const SkRRect&,
197 const SkPaint&) SK_OVERRIDE;
198
robertphillips@google.com8f90a892014-02-28 18:19:39 +0000199 virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
200 virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
201 virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
202 virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
203
junov@google.com4370aed2012-01-18 16:21:08 +0000204public:
junov@chromium.org52805482012-08-20 14:25:04 +0000205 class NotificationClient {
junov@google.com4370aed2012-01-18 16:21:08 +0000206 public:
robertphillips@google.com59903972013-02-07 21:02:23 +0000207 virtual ~NotificationClient() {}
208
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000209 /**
210 * Called before executing one or several draw commands, which means
211 * once per flush when deferred rendering is enabled.
212 */
junov@google.com4370aed2012-01-18 16:21:08 +0000213 virtual void prepareForDraw() {}
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000214
215 /**
216 * Called after a recording a draw command if additional memory
217 * had to be allocated for recording.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000218 * @param newAllocatedStorage same value as would be returned by
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000219 * storageAllocatedForRecording(), for convenience.
220 */
221 virtual void storageAllocatedForRecordingChanged(
222 size_t newAllocatedStorage) {}
223
224 /**
225 * Called after pending draw commands have been flushed
226 */
227 virtual void flushedDrawCommands() {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000228
junov@google.com52a00ca2012-10-01 15:27:14 +0000229 /**
230 * Called after pending draw commands have been skipped, meaning
231 * that they were optimized-out because the canvas is cleared
232 * or completely overwritten by the command currently being recorded.
233 */
234 virtual void skippedPendingDrawCommands() {}
junov@google.com4370aed2012-01-18 16:21:08 +0000235 };
236
junov@chromium.org77eec242012-07-18 17:54:45 +0000237protected:
junov@google.com4370aed2012-01-18 16:21:08 +0000238 virtual SkCanvas* canvasForDrawIter();
reed@google.com9c135db2014-03-12 18:28:35 +0000239 SkDeferredDevice* getDeferredDevice() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000240
241private:
reed@google.com9c135db2014-03-12 18:28:35 +0000242 SkDeferredCanvas(SkDeferredDevice*);
junov@chromium.org66070a52013-05-28 17:39:08 +0000243
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000244 void recordedDrawCommand();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000245 SkCanvas* drawingCanvas() const;
junov@chromium.org88e29142012-08-07 16:48:22 +0000246 SkCanvas* immediateCanvas() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000247 bool isFullFrame(const SkRect*, const SkPaint*) const;
248 void validate() const;
249 void init();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000250 bool fDeferredDrawing;
junov@google.com4370aed2012-01-18 16:21:08 +0000251
junov@chromium.org88e29142012-08-07 16:48:22 +0000252 friend class SkDeferredCanvasTester; // for unit testing
junov@google.com4370aed2012-01-18 16:21:08 +0000253 typedef SkCanvas INHERITED;
254};
255
256
257#endif