SkDeferredCanvas.h revision 868074b50b0fc3e460d2aa97c1096827fe0a1935
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 14class SkDeferredDevice; 15class SkImage; 16class 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*/ 26class SK_API SkDeferredCanvas : public SkCanvas { 27public: 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// static SkDeferredCanvas* Create(SkBaseDevice* device); 37 38 virtual ~SkDeferredCanvas(); 39 40 /** 41 * 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 /** 51 * Specify a NotificationClient to be used by this canvas. Calling 52 * setNotificationClient will release the previously set 53 * 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. 58 * Note: Must be called after the device is set with setDevice. 59 * 60 * @param notificationClient interface for dispatching notifications 61 * @return The notificationClient argument, for convenience. 62 */ 63 NotificationClient* setNotificationClient(NotificationClient* notificationClient); 64 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 74 /** 75 * Returns true if deferred drawing is currenlty enabled. 76 */ 77 bool isDeferredDrawing() const; 78 79 /** 80 * Returns true if the canvas contains a fresh frame. A frame is 81 * 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; 90 91 /** 92 * Returns true if the canvas has recorded draw commands that have 93 * not yet been played back. 94 */ 95 bool hasPendingCommands() const; 96 97 /** 98 * 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 */ 104 SkImage* newImageSnapshot(); 105 106 /** 107 * 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 114 /** 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 129 /** 130 * 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 /** 136 * Executes all pending commands without drawing 137 */ 138 void silentFlush(); 139 140 // Overrides of the SkCanvas interface 141 virtual bool isDrawingToLayer() const SK_OVERRIDE; 142 virtual void clear(SkColor) SK_OVERRIDE; 143 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; 144 virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], 145 const SkPaint& paint) SK_OVERRIDE; 146 virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE; 147 virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE; 148 virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE; 149 virtual void drawPath(const SkPath& path, const SkPaint& paint) 150 SK_OVERRIDE; 151 virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, 152 SkScalar top, const SkPaint* paint) 153 SK_OVERRIDE; 154 virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 155 const SkRect& dst, const SkPaint* paint, 156 DrawBitmapRectFlags flags) SK_OVERRIDE; 157 158 virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, 159 const SkPaint* paint) SK_OVERRIDE; 160 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 161 const SkRect& dst, const SkPaint* paint) 162 SK_OVERRIDE; 163 virtual void drawSprite(const SkBitmap& bitmap, int left, int top, 164 const SkPaint* paint) SK_OVERRIDE; 165 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; 166 virtual void drawVertices(VertexMode vmode, int vertexCount, 167 const SkPoint vertices[], const SkPoint texs[], 168 const SkColor colors[], SkXfermode* xmode, 169 const uint16_t indices[], int indexCount, 170 const SkPaint& paint) SK_OVERRIDE; 171 virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; 172 173protected: 174 virtual void willSave(SaveFlags) SK_OVERRIDE; 175 virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; 176 virtual void willRestore() SK_OVERRIDE; 177 178 virtual void didConcat(const SkMatrix&) SK_OVERRIDE; 179 virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; 180 181 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; 182 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 183 const SkPaint&) SK_OVERRIDE; 184 virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 185 const SkPaint&) SK_OVERRIDE; 186 virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 187 SkScalar constY, const SkPaint&) SK_OVERRIDE; 188 virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 189 const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE; 190 191 virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 192 virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 193 virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 194 virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; 195 196public: 197 class NotificationClient { 198 public: 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 229protected: 230 virtual SkCanvas* canvasForDrawIter(); 231 SkDeferredDevice* getDeferredDevice() const; 232 233private: 234 SkDeferredCanvas(SkDeferredDevice*); 235 236 void recordedDrawCommand(); 237 SkCanvas* drawingCanvas() const; 238 SkCanvas* immediateCanvas() const; 239 bool isFullFrame(const SkRect*, const SkPaint*) const; 240 void validate() const; 241 void init(); 242 bool fDeferredDrawing; 243 244 friend class SkDeferredCanvasTester; // for unit testing 245 typedef SkCanvas INHERITED; 246}; 247 248 249#endif 250