blob: ec5ea13b5959827b7245451ae9b40f99e58581b0 [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 /**
yunchao.he49005bf2014-09-15 22:30:38 -070092 * Returns canvas's size.
93 */
94 SkISize getCanvasSize() const;
95
96 /**
junov@chromium.orga38dfb62012-09-20 22:10:33 +000097 * Returns true if the canvas has recorded draw commands that have
98 * not yet been played back.
99 */
100 bool hasPendingCommands() const;
101
102 /**
junov@chromium.org67d74222013-04-12 13:33:01 +0000103 * Flushes pending draw commands, if any, and returns an image of the
104 * current state of the surface pixels up to this point. Subsequent
105 * changes to the surface (by drawing into its canvas) will not be
106 * reflected in this image. Will return NULL if the deferred canvas
107 * was not constructed from an SkSurface.
108 */
junov@chromium.org5ee449a2013-04-12 20:20:50 +0000109 SkImage* newImageSnapshot();
junov@chromium.org67d74222013-04-12 13:33:01 +0000110
111 /**
junov@chromium.orgbfeddae2012-07-23 13:35:14 +0000112 * Specify the maximum number of bytes to be allocated for the purpose
113 * of recording draw commands to this canvas. The default limit, is
114 * 64MB.
115 * @param maxStorage The maximum number of bytes to be allocated.
116 */
117 void setMaxRecordingStorage(size_t maxStorage);
118
junov@chromium.org2e14ba82012-08-07 14:26:57 +0000119 /**
120 * Returns the number of bytes currently allocated for the purpose of
121 * recording draw commands.
122 */
123 size_t storageAllocatedForRecording() const;
124
125 /**
126 * Attempt to reduce the storage allocated for recording by evicting
127 * cache resources.
128 * @param bytesToFree minimum number of bytes that should be attempted to
129 * be freed.
130 * @return number of bytes actually freed.
131 */
132 size_t freeMemoryIfPossible(size_t bytesToFree);
133
junov@chromium.orgfb103892012-09-20 19:35:43 +0000134 /**
sugoi@google.com7775fd52012-11-21 15:47:04 +0000135 * Specifies the maximum size (in bytes) allowed for a given image to be
136 * rendered using the deferred canvas.
137 */
138 void setBitmapSizeThreshold(size_t sizeThreshold);
reed52d9ac62014-06-30 09:05:34 -0700139 size_t getBitmapSizeThreshold() const { return fBitmapSizeThreshold; }
sugoi@google.com7775fd52012-11-21 15:47:04 +0000140
141 /**
junov@chromium.orgfb103892012-09-20 19:35:43 +0000142 * Executes all pending commands without drawing
143 */
144 void silentFlush();
145
junov@google.com4370aed2012-01-18 16:21:08 +0000146 // Overrides of the SkCanvas interface
junov@chromium.orga907ac32012-02-24 21:54:07 +0000147 virtual bool isDrawingToLayer() const SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000148 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
149 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
150 const SkPaint& paint) SK_OVERRIDE;
reed@google.com4ed0fb72012-12-12 20:48:18 +0000151 virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
bsalomon@google.com7ce564c2013-10-22 16:54:15 +0000152 virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
reed@google.com4ed0fb72012-12-12 20:48:18 +0000153 virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
bsalomon@google.com7ce564c2013-10-22 16:54:15 +0000154 virtual void drawPath(const SkPath& path, const SkPaint& paint)
155 SK_OVERRIDE;
vandebo@chromium.org74b46192012-01-28 01:45:11 +0000156 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
junov@google.com4370aed2012-01-18 16:21:08 +0000157 SkScalar top, const SkPaint* paint)
158 SK_OVERRIDE;
reed@google.com71121732012-09-18 15:14:33 +0000159 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +0000160 const SkRect& dst, const SkPaint* paint,
161 DrawBitmapRectFlags flags) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000162
163 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
164 const SkPaint* paint) SK_OVERRIDE;
165 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
piotaixr2bf8d092014-11-04 13:21:41 -0800166 const SkRect& dst, const SkPaint* paint)
167 SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000168 virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
169 const SkPaint* paint) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000170 virtual void drawVertices(VertexMode vmode, int vertexCount,
171 const SkPoint vertices[], const SkPoint texs[],
172 const SkColor colors[], SkXfermode* xmode,
173 const uint16_t indices[], int indexCount,
174 const SkPaint& paint) SK_OVERRIDE;
junov@google.com4370aed2012-01-18 16:21:08 +0000175 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
176
commit-bot@chromium.orgab582732014-02-21 12:20:45 +0000177protected:
Florin Malita5f6102d2014-06-30 10:13:28 -0400178 virtual void willSave() SK_OVERRIDE;
commit-bot@chromium.orge54a23f2014-03-12 20:21:48 +0000179 virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
180 virtual void willRestore() SK_OVERRIDE;
181
commit-bot@chromium.org44c48d02014-03-13 20:03:58 +0000182 virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
183 virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
184
reed@google.come0d9ce82014-04-23 04:00:17 +0000185 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
186 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
187 const SkPaint&) SK_OVERRIDE;
188 virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
189 const SkPaint&) SK_OVERRIDE;
190 virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
191 SkScalar constY, const SkPaint&) SK_OVERRIDE;
192 virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
193 const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
fmalitab7425172014-08-26 07:56:44 -0700194 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
195 const SkPaint& paint) SK_OVERRIDE;
dandovb3c9d1c2014-08-12 08:34:29 -0700196 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
197 const SkPoint texCoords[4], SkXfermode* xmode,
198 const SkPaint& paint) SK_OVERRIDE;
piotaixr2bf8d092014-11-04 13:21:41 -0800199
robertphillips@google.com8f90a892014-02-28 18:19:39 +0000200 virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
201 virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
202 virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
203 virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE;
204
reedd5fa1a42014-08-09 11:08:05 -0700205 virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
robertphillips9b14f262014-06-04 05:40:44 -0700206
junov@google.com4370aed2012-01-18 16:21:08 +0000207public:
junov@chromium.org52805482012-08-20 14:25:04 +0000208 class NotificationClient {
junov@google.com4370aed2012-01-18 16:21:08 +0000209 public:
robertphillips@google.com59903972013-02-07 21:02:23 +0000210 virtual ~NotificationClient() {}
211
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000212 /**
213 * Called before executing one or several draw commands, which means
214 * once per flush when deferred rendering is enabled.
215 */
junov@google.com4370aed2012-01-18 16:21:08 +0000216 virtual void prepareForDraw() {}
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000217
218 /**
219 * Called after a recording a draw command if additional memory
220 * had to be allocated for recording.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000221 * @param newAllocatedStorage same value as would be returned by
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000222 * storageAllocatedForRecording(), for convenience.
223 */
djsollenc87dd2c2014-11-14 11:11:46 -0800224 virtual void storageAllocatedForRecordingChanged(size_t /*newAllocatedStorage*/) {}
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000225
226 /**
227 * Called after pending draw commands have been flushed
228 */
229 virtual void flushedDrawCommands() {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000230
junov@google.com52a00ca2012-10-01 15:27:14 +0000231 /**
232 * Called after pending draw commands have been skipped, meaning
233 * that they were optimized-out because the canvas is cleared
234 * or completely overwritten by the command currently being recorded.
235 */
236 virtual void skippedPendingDrawCommands() {}
junov@google.com4370aed2012-01-18 16:21:08 +0000237 };
238
junov@chromium.org77eec242012-07-18 17:54:45 +0000239protected:
junov@google.com4370aed2012-01-18 16:21:08 +0000240 virtual SkCanvas* canvasForDrawIter();
reed@google.com9c135db2014-03-12 18:28:35 +0000241 SkDeferredDevice* getDeferredDevice() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000242
243private:
reed@google.com9c135db2014-03-12 18:28:35 +0000244 SkDeferredCanvas(SkDeferredDevice*);
junov@chromium.org66070a52013-05-28 17:39:08 +0000245
junov@chromium.org9ed02b92012-08-14 13:36:26 +0000246 void recordedDrawCommand();
junov@chromium.org5e5a0952012-02-28 15:27:59 +0000247 SkCanvas* drawingCanvas() const;
junov@chromium.org88e29142012-08-07 16:48:22 +0000248 SkCanvas* immediateCanvas() const;
junov@google.com4370aed2012-01-18 16:21:08 +0000249 bool isFullFrame(const SkRect*, const SkPaint*) const;
250 void validate() const;
251 void init();
reed52d9ac62014-06-30 09:05:34 -0700252
253 size_t fBitmapSizeThreshold;
254 bool fDeferredDrawing;
junov@google.com4370aed2012-01-18 16:21:08 +0000255
yunchao.he49005bf2014-09-15 22:30:38 -0700256 mutable SkISize fCachedCanvasSize;
257 mutable bool fCachedCanvasSizeDirty;
258
junov@chromium.org88e29142012-08-07 16:48:22 +0000259 friend class SkDeferredCanvasTester; // for unit testing
junov@google.com4370aed2012-01-18 16:21:08 +0000260 typedef SkCanvas INHERITED;
261};
262
263
264#endif