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 DeferredDevice; 15 16 /** \class SkDeferredCanvas 17 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. 21 SkDeferredCanvas will transparently trigger the flushing of deferred 22 draw operations when an attempt is made to access the pixel data. 23 */ 24 class SK_API SkDeferredCanvas : public SkCanvas { 25 public: 26 class NotificationClient; 27 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 virtual ~SkDeferredCanvas(); 37 38 /** 39 * Specify a device to be used by this canvas. Calling setDevice will 40 * release the previously set device, if any. Takes a reference on the 41 * device. 42 * 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 /** 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* notificationClient); 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 true if the canvas has recorded draw commands that have 91 * not yet been played back. 92 */ 93 bool hasPendingCommands() const; 94 95 /** 96 * Specify the maximum number of bytes to be allocated for the purpose 97 * of recording draw commands to this canvas. The default limit, is 98 * 64MB. 99 * @param maxStorage The maximum number of bytes to be allocated. 100 */ 101 void setMaxRecordingStorage(size_t maxStorage); 102 103 /** 104 * Returns the number of bytes currently allocated for the purpose of 105 * recording draw commands. 106 */ 107 size_t storageAllocatedForRecording() const; 108 109 /** 110 * Attempt to reduce the storage allocated for recording by evicting 111 * cache resources. 112 * @param bytesToFree minimum number of bytes that should be attempted to 113 * be freed. 114 * @return number of bytes actually freed. 115 */ 116 size_t freeMemoryIfPossible(size_t bytesToFree); 117 118 /** 119 * Specifies the maximum size (in bytes) allowed for a given image to be 120 * rendered using the deferred canvas. 121 */ 122 void setBitmapSizeThreshold(size_t sizeThreshold); 123 124 /** 125 * Executes all pending commands without drawing 126 */ 127 void silentFlush(); 128 129 // Overrides of the SkCanvas interface 130 virtual int save(SaveFlags flags) SK_OVERRIDE; 131 virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, 132 SaveFlags flags) SK_OVERRIDE; 133 virtual void restore() SK_OVERRIDE; 134 virtual bool isDrawingToLayer() const SK_OVERRIDE; 135 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; 136 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; 137 virtual bool rotate(SkScalar degrees) SK_OVERRIDE; 138 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; 139 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; 140 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; 141 virtual bool clipRect(const SkRect& rect, SkRegion::Op op, 142 bool doAntiAlias) SK_OVERRIDE; 143 virtual bool clipRRect(const SkRRect& rect, SkRegion::Op op, 144 bool doAntiAlias) SK_OVERRIDE; 145 virtual bool clipPath(const SkPath& path, SkRegion::Op op, 146 bool doAntiAlias) SK_OVERRIDE; 147 virtual bool clipRegion(const SkRegion& deviceRgn, 148 SkRegion::Op op) SK_OVERRIDE; 149 virtual void clear(SkColor) SK_OVERRIDE; 150 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; 151 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], 152 const SkPaint& paint) SK_OVERRIDE; 153 virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE; 154 virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE; 155 virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE; 156 virtual void drawPath(const SkPath& path, const SkPaint& paint) 157 SK_OVERRIDE; 158 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, 159 SkScalar top, const SkPaint* paint) 160 SK_OVERRIDE; 161 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 162 const SkRect& dst, const SkPaint* paint) 163 SK_OVERRIDE; 164 165 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, 166 const SkPaint* paint) SK_OVERRIDE; 167 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 168 const SkRect& dst, const SkPaint* paint) 169 SK_OVERRIDE; 170 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, 171 const SkPaint* paint) SK_OVERRIDE; 172 virtual void drawText(const void* text, size_t byteLength, SkScalar x, 173 SkScalar y, const SkPaint& paint) SK_OVERRIDE; 174 virtual void drawPosText(const void* text, size_t byteLength, 175 const SkPoint pos[], const SkPaint& paint) 176 SK_OVERRIDE; 177 virtual void drawPosTextH(const void* text, size_t byteLength, 178 const SkScalar xpos[], SkScalar constY, 179 const SkPaint& paint) SK_OVERRIDE; 180 virtual void drawTextOnPath(const void* text, size_t byteLength, 181 const SkPath& path, const SkMatrix* matrix, 182 const SkPaint& paint) SK_OVERRIDE; 183 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; 184 virtual void drawVertices(VertexMode vmode, int vertexCount, 185 const SkPoint vertices[], const SkPoint texs[], 186 const SkColor colors[], SkXfermode* xmode, 187 const uint16_t indices[], int indexCount, 188 const SkPaint& paint) SK_OVERRIDE; 189 virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE; 190 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; 191 192 public: 193 class NotificationClient { 194 public: 195 /** 196 * All classes with virtual methods should have a virtual destructor 197 * to avoid compiler warnings. 198 */ 199 virtual ~NotificationClient() {} 200 201 /** 202 * Called before executing one or several draw commands, which means 203 * once per flush when deferred rendering is enabled. 204 */ 205 virtual void prepareForDraw() {} 206 207 /** 208 * Called after a recording a draw command if additional memory 209 * had to be allocated for recording. 210 * @param newAllocatedStorage same value as would be returned by 211 * storageAllocatedForRecording(), for convenience. 212 */ 213 virtual void storageAllocatedForRecordingChanged( 214 size_t newAllocatedStorage) {} 215 216 /** 217 * Called after pending draw commands have been flushed 218 */ 219 virtual void flushedDrawCommands() {} 220 221 /** 222 * Called after pending draw commands have been skipped, meaning 223 * that they were optimized-out because the canvas is cleared 224 * or completely overwritten by the command currently being recorded. 225 */ 226 virtual void skippedPendingDrawCommands() {} 227 228 private: 229 typedef SkRefCnt INHERITED; 230 }; 231 232 protected: 233 virtual SkCanvas* canvasForDrawIter(); 234 DeferredDevice* getDeferredDevice() const; 235 236 private: 237 void recordedDrawCommand(); 238 SkCanvas* drawingCanvas() const; 239 SkCanvas* immediateCanvas() const; 240 bool isFullFrame(const SkRect*, const SkPaint*) const; 241 void validate() const; 242 void init(); 243 bool fDeferredDrawing; 244 245 friend class SkDeferredCanvasTester; // for unit testing 246 typedef SkCanvas INHERITED; 247 }; 248 249 250 #endif 251