| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2012 Google Inc. | |
| 3 * | |
| 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" | |
| 12 #include "SkPixelRef.h" | |
| 13 | |
| 14 class SkDeferredDevice; | |
| 15 class SkImage; | |
| 16 class SkSurface; | |
| 17 | |
| 18 /** \class SkDeferredCanvas | |
| 19 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. | |
| 23 SkDeferredCanvas will transparently trigger the flushing of deferred | |
| 24 draw operations when an attempt is made to access the pixel data. | |
| 25 */ | |
| 26 class SK_API SkDeferredCanvas : public SkCanvas { | |
| 27 public: | |
| 28 class SK_API NotificationClient; | |
| 29 | |
| 30 /** 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 | |
| 36 virtual ~SkDeferredCanvas(); | |
| 37 | |
| 38 /** | |
| 39 * Specify the surface to be used by this canvas. Calling setSurface will | |
| 40 * release the previously set surface or device. Takes a reference on the | |
| 41 * surface. | |
| 42 * | |
| 43 * @param surface The surface that the canvas will raw into | |
| 44 * @return The surface argument, for convenience. | |
| 45 */ | |
| 46 SkSurface* setSurface(SkSurface* surface); | |
| 47 | |
| 48 /** | |
| 49 * Specify a NotificationClient to be used by this canvas. Calling | |
| 50 * setNotificationClient will release the previously set | |
| 51 * 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. | |
| 56 * Note: Must be called after the device is set with setDevice. | |
| 57 * | |
| 58 * @param notificationClient interface for dispatching notifications | |
| 59 * @return The notificationClient argument, for convenience. | |
| 60 */ | |
| 61 NotificationClient* setNotificationClient(NotificationClient* notificationCl
ient); | |
| 62 | |
| 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 | |
| 72 /** | |
| 73 * Returns true if deferred drawing is currenlty enabled. | |
| 74 */ | |
| 75 bool isDeferredDrawing() const; | |
| 76 | |
| 77 /** | |
| 78 * Returns true if the canvas contains a fresh frame. A frame is | |
| 79 * 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; | |
| 88 | |
| 89 /** | |
| 90 * Returns canvas's size. | |
| 91 */ | |
| 92 SkISize getCanvasSize() const; | |
| 93 | |
| 94 /** | |
| 95 * Returns true if the canvas has recorded draw commands that have | |
| 96 * not yet been played back. | |
| 97 */ | |
| 98 bool hasPendingCommands() const; | |
| 99 | |
| 100 /** | |
| 101 * Flushes pending draw commands, if any, and returns an image of the | |
| 102 * current state of the surface pixels up to this point. Subsequent | |
| 103 * changes to the surface (by drawing into its canvas) will not be | |
| 104 * reflected in this image. Will return NULL if the deferred canvas | |
| 105 * was not constructed from an SkSurface. | |
| 106 */ | |
| 107 SkImage* newImageSnapshot(); | |
| 108 | |
| 109 /** | |
| 110 * Specify the maximum number of bytes to be allocated for the purpose | |
| 111 * of recording draw commands to this canvas. The default limit, is | |
| 112 * 64MB. | |
| 113 * @param maxStorage The maximum number of bytes to be allocated. | |
| 114 */ | |
| 115 void setMaxRecordingStorage(size_t maxStorage); | |
| 116 | |
| 117 /** | |
| 118 * Returns the number of bytes currently allocated for the purpose of | |
| 119 * recording draw commands. | |
| 120 */ | |
| 121 size_t storageAllocatedForRecording() const; | |
| 122 | |
| 123 /** | |
| 124 * Attempt to reduce the storage allocated for recording by evicting | |
| 125 * cache resources. | |
| 126 * @param bytesToFree minimum number of bytes that should be attempted to | |
| 127 * be freed. | |
| 128 * @return number of bytes actually freed. | |
| 129 */ | |
| 130 size_t freeMemoryIfPossible(size_t bytesToFree); | |
| 131 | |
| 132 /** | |
| 133 * Specifies the maximum size (in bytes) allowed for a given image to be | |
| 134 * rendered using the deferred canvas. | |
| 135 */ | |
| 136 void setBitmapSizeThreshold(size_t sizeThreshold); | |
| 137 size_t getBitmapSizeThreshold() const { return fBitmapSizeThreshold; } | |
| 138 | |
| 139 /** | |
| 140 * Executes all pending commands without drawing | |
| 141 */ | |
| 142 void silentFlush(); | |
| 143 | |
| 144 SkDrawFilter* setDrawFilter(SkDrawFilter* filter) override; | |
| 145 | |
| 146 protected: | |
| 147 void willSave() override; | |
| 148 SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) ov
erride; | |
| 149 void willRestore() override; | |
| 150 | |
| 151 void didConcat(const SkMatrix&) override; | |
| 152 void didSetMatrix(const SkMatrix&) override; | |
| 153 | |
| 154 void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; | |
| 155 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkS
calar y, | |
| 156 const SkPaint&) override; | |
| 157 virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoin
t pos[], | |
| 158 const SkPaint&) override; | |
| 159 virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkSca
lar xpos[], | |
| 160 SkScalar constY, const SkPaint&) override; | |
| 161 virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkP
ath& path, | |
| 162 const SkMatrix* matrix, const SkPaint&) overri
de; | |
| 163 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, | |
| 164 const SkPaint& paint) override; | |
| 165 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], | |
| 166 const SkPoint texCoords[4], SkXfermode* xmode, | |
| 167 const SkPaint& paint) override; | |
| 168 | |
| 169 void onDrawPaint(const SkPaint&) override; | |
| 170 void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPain
t&) override; | |
| 171 void onDrawRect(const SkRect&, const SkPaint&) override; | |
| 172 void onDrawOval(const SkRect&, const SkPaint&) override; | |
| 173 void onDrawRRect(const SkRRect&, const SkPaint&) override; | |
| 174 void onDrawPath(const SkPath&, const SkPaint&) override; | |
| 175 void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPain
t*) override; | |
| 176 void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst,
const SkPaint*, | |
| 177 SrcRectConstraint) override; | |
| 178 void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*
) override; | |
| 179 void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, | |
| 180 const SkPaint*, SrcRectConstraint) override; | |
| 181 void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& ds
t, | |
| 182 const SkPaint*) override; | |
| 183 void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect&
dst, | |
| 184 const SkPaint*) override; | |
| 185 void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*) overri
de; | |
| 186 void onDrawVertices(VertexMode vmode, int vertexCount, | |
| 187 const SkPoint vertices[], const SkPoint texs[], | |
| 188 const SkColor colors[], SkXfermode* xmode, | |
| 189 const uint16_t indices[], int indexCount, | |
| 190 const SkPaint&) override; | |
| 191 void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const Sk
Color[], int count, | |
| 192 SkXfermode::Mode, const SkRect* cullRect, const SkPaint*) o
verride; | |
| 193 | |
| 194 void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override; | |
| 195 void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override; | |
| 196 void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override; | |
| 197 void onClipRegion(const SkRegion&, SkRegion::Op) override; | |
| 198 | |
| 199 void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) overri
de; | |
| 200 | |
| 201 public: | |
| 202 class NotificationClient { | |
| 203 public: | |
| 204 virtual ~NotificationClient() {} | |
| 205 | |
| 206 /** | |
| 207 * Called before executing one or several draw commands, which means | |
| 208 * once per flush when deferred rendering is enabled. | |
| 209 */ | |
| 210 virtual void prepareForDraw() {} | |
| 211 | |
| 212 /** | |
| 213 * Called after a recording a draw command if additional memory | |
| 214 * had to be allocated for recording. | |
| 215 * @param newAllocatedStorage same value as would be returned by | |
| 216 * storageAllocatedForRecording(), for convenience. | |
| 217 */ | |
| 218 virtual void storageAllocatedForRecordingChanged(size_t /*newAllocatedSt
orage*/) {} | |
| 219 | |
| 220 /** | |
| 221 * Called after pending draw commands have been flushed | |
| 222 */ | |
| 223 virtual void flushedDrawCommands() {} | |
| 224 | |
| 225 /** | |
| 226 * Called after pending draw commands have been skipped, meaning | |
| 227 * that they were optimized-out because the canvas is cleared | |
| 228 * or completely overwritten by the command currently being recorded. | |
| 229 */ | |
| 230 virtual void skippedPendingDrawCommands() {} | |
| 231 }; | |
| 232 | |
| 233 protected: | |
| 234 SkCanvas* canvasForDrawIter() override; | |
| 235 SkDeferredDevice* getDeferredDevice() const; | |
| 236 | |
| 237 private: | |
| 238 SkDeferredCanvas(SkDeferredDevice*); | |
| 239 | |
| 240 void recordedDrawCommand(); | |
| 241 SkCanvas* drawingCanvas() const; | |
| 242 SkCanvas* immediateCanvas() const; | |
| 243 bool isFullFrame(const SkRect*, const SkPaint*) const; | |
| 244 void validate() const; | |
| 245 void init(); | |
| 246 | |
| 247 | |
| 248 int fSaveLevel; | |
| 249 int fFirstSaveLayerIndex; | |
| 250 size_t fBitmapSizeThreshold; | |
| 251 bool fDeferredDrawing; | |
| 252 | |
| 253 mutable SkISize fCachedCanvasSize; | |
| 254 mutable bool fCachedCanvasSizeDirty; | |
| 255 | |
| 256 friend class SkDeferredCanvasTester; // for unit testing | |
| 257 typedef SkCanvas INHERITED; | |
| 258 }; | |
| 259 | |
| 260 | |
| 261 #endif | |
| OLD | NEW |