1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/utils/SkDeferredCanvas.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,258 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkDeferredCanvas_DEFINED 1.12 +#define SkDeferredCanvas_DEFINED 1.13 + 1.14 +#include "SkCanvas.h" 1.15 +#include "SkPixelRef.h" 1.16 + 1.17 +class SkDeferredDevice; 1.18 +class SkImage; 1.19 +class SkSurface; 1.20 + 1.21 +/** \class SkDeferredCanvas 1.22 + Subclass of SkCanvas that encapsulates an SkPicture or SkGPipe for deferred 1.23 + drawing. The main difference between this class and SkPictureRecord (the 1.24 + canvas provided by SkPicture) is that this is a full drop-in replacement 1.25 + for SkCanvas, while SkPictureRecord only supports draw operations. 1.26 + SkDeferredCanvas will transparently trigger the flushing of deferred 1.27 + draw operations when an attempt is made to access the pixel data. 1.28 +*/ 1.29 +class SK_API SkDeferredCanvas : public SkCanvas { 1.30 +public: 1.31 + class SK_API NotificationClient; 1.32 + 1.33 + /** Construct a canvas with the specified surface to draw into. 1.34 + This factory must be used for newImageSnapshot to work. 1.35 + @param surface Specifies a surface for the canvas to draw into. 1.36 + */ 1.37 + static SkDeferredCanvas* Create(SkSurface* surface); 1.38 + 1.39 +// static SkDeferredCanvas* Create(SkBaseDevice* device); 1.40 + 1.41 + virtual ~SkDeferredCanvas(); 1.42 + 1.43 + /** 1.44 + * Specify the surface to be used by this canvas. Calling setSurface will 1.45 + * release the previously set surface or device. Takes a reference on the 1.46 + * surface. 1.47 + * 1.48 + * @param surface The surface that the canvas will raw into 1.49 + * @return The surface argument, for convenience. 1.50 + */ 1.51 + SkSurface* setSurface(SkSurface* surface); 1.52 + 1.53 + /** 1.54 + * Specify a NotificationClient to be used by this canvas. Calling 1.55 + * setNotificationClient will release the previously set 1.56 + * NotificationClient, if any. SkDeferredCanvas does not take ownership 1.57 + * of the notification client. Therefore user code is resposible 1.58 + * for its destruction. The notification client must be unregistered 1.59 + * by calling setNotificationClient(NULL) if it is destroyed before 1.60 + * this canvas. 1.61 + * Note: Must be called after the device is set with setDevice. 1.62 + * 1.63 + * @param notificationClient interface for dispatching notifications 1.64 + * @return The notificationClient argument, for convenience. 1.65 + */ 1.66 + NotificationClient* setNotificationClient(NotificationClient* notificationClient); 1.67 + 1.68 + /** 1.69 + * Enable or disable deferred drawing. When deferral is disabled, 1.70 + * pending draw operations are immediately flushed and from then on, 1.71 + * the SkDeferredCanvas behaves just like a regular SkCanvas. 1.72 + * This method must not be called while the save/restore stack is in use. 1.73 + * @param deferred true/false 1.74 + */ 1.75 + void setDeferredDrawing(bool deferred); 1.76 + 1.77 + /** 1.78 + * Returns true if deferred drawing is currenlty enabled. 1.79 + */ 1.80 + bool isDeferredDrawing() const; 1.81 + 1.82 + /** 1.83 + * Returns true if the canvas contains a fresh frame. A frame is 1.84 + * considered fresh when its content do not depend on the contents 1.85 + * of the previous frame. For example, if a canvas is cleared before 1.86 + * drawing each frame, the frames will all be considered fresh. 1.87 + * A frame is defined as the graphics image produced by as a result 1.88 + * of all the canvas draws operation executed between two successive 1.89 + * calls to isFreshFrame. The result of isFreshFrame is computed 1.90 + * conservatively, so it may report false negatives. 1.91 + */ 1.92 + bool isFreshFrame() const; 1.93 + 1.94 + /** 1.95 + * Returns true if the canvas has recorded draw commands that have 1.96 + * not yet been played back. 1.97 + */ 1.98 + bool hasPendingCommands() const; 1.99 + 1.100 + /** 1.101 + * Flushes pending draw commands, if any, and returns an image of the 1.102 + * current state of the surface pixels up to this point. Subsequent 1.103 + * changes to the surface (by drawing into its canvas) will not be 1.104 + * reflected in this image. Will return NULL if the deferred canvas 1.105 + * was not constructed from an SkSurface. 1.106 + */ 1.107 + SkImage* newImageSnapshot(); 1.108 + 1.109 + /** 1.110 + * Specify the maximum number of bytes to be allocated for the purpose 1.111 + * of recording draw commands to this canvas. The default limit, is 1.112 + * 64MB. 1.113 + * @param maxStorage The maximum number of bytes to be allocated. 1.114 + */ 1.115 + void setMaxRecordingStorage(size_t maxStorage); 1.116 + 1.117 + /** 1.118 + * Returns the number of bytes currently allocated for the purpose of 1.119 + * recording draw commands. 1.120 + */ 1.121 + size_t storageAllocatedForRecording() const; 1.122 + 1.123 + /** 1.124 + * Attempt to reduce the storage allocated for recording by evicting 1.125 + * cache resources. 1.126 + * @param bytesToFree minimum number of bytes that should be attempted to 1.127 + * be freed. 1.128 + * @return number of bytes actually freed. 1.129 + */ 1.130 + size_t freeMemoryIfPossible(size_t bytesToFree); 1.131 + 1.132 + /** 1.133 + * Specifies the maximum size (in bytes) allowed for a given image to be 1.134 + * rendered using the deferred canvas. 1.135 + */ 1.136 + void setBitmapSizeThreshold(size_t sizeThreshold); 1.137 + 1.138 + /** 1.139 + * Executes all pending commands without drawing 1.140 + */ 1.141 + void silentFlush(); 1.142 + 1.143 + // Overrides of the SkCanvas interface 1.144 + virtual bool isDrawingToLayer() const SK_OVERRIDE; 1.145 + virtual void clear(SkColor) SK_OVERRIDE; 1.146 + virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; 1.147 + virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], 1.148 + const SkPaint& paint) SK_OVERRIDE; 1.149 + virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE; 1.150 + virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE; 1.151 + virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE; 1.152 + virtual void drawPath(const SkPath& path, const SkPaint& paint) 1.153 + SK_OVERRIDE; 1.154 + virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, 1.155 + SkScalar top, const SkPaint* paint) 1.156 + SK_OVERRIDE; 1.157 + virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 1.158 + const SkRect& dst, const SkPaint* paint, 1.159 + DrawBitmapRectFlags flags) SK_OVERRIDE; 1.160 + 1.161 + virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, 1.162 + const SkPaint* paint) SK_OVERRIDE; 1.163 + virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 1.164 + const SkRect& dst, const SkPaint* paint) 1.165 + SK_OVERRIDE; 1.166 + virtual void drawSprite(const SkBitmap& bitmap, int left, int top, 1.167 + const SkPaint* paint) SK_OVERRIDE; 1.168 + virtual void drawText(const void* text, size_t byteLength, SkScalar x, 1.169 + SkScalar y, const SkPaint& paint) SK_OVERRIDE; 1.170 + virtual void drawPosText(const void* text, size_t byteLength, 1.171 + const SkPoint pos[], const SkPaint& paint) 1.172 + SK_OVERRIDE; 1.173 + virtual void drawPosTextH(const void* text, size_t byteLength, 1.174 + const SkScalar xpos[], SkScalar constY, 1.175 + const SkPaint& paint) SK_OVERRIDE; 1.176 + virtual void drawTextOnPath(const void* text, size_t byteLength, 1.177 + const SkPath& path, const SkMatrix* matrix, 1.178 + const SkPaint& paint) SK_OVERRIDE; 1.179 + virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; 1.180 + virtual void drawVertices(VertexMode vmode, int vertexCount, 1.181 + const SkPoint vertices[], const SkPoint texs[], 1.182 + const SkColor colors[], SkXfermode* xmode, 1.183 + const uint16_t indices[], int indexCount, 1.184 + const SkPaint& paint) SK_OVERRIDE; 1.185 + virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE; 1.186 + virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; 1.187 + 1.188 +protected: 1.189 + virtual void willSave(SaveFlags) SK_OVERRIDE; 1.190 + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; 1.191 + virtual void willRestore() SK_OVERRIDE; 1.192 + 1.193 + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; 1.194 + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; 1.195 + virtual void didRotate(SkScalar) SK_OVERRIDE; 1.196 + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; 1.197 + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; 1.198 + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; 1.199 + 1.200 + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, 1.201 + const SkPaint&) SK_OVERRIDE; 1.202 + 1.203 + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.204 + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.205 + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.206 + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; 1.207 + 1.208 +public: 1.209 + class NotificationClient { 1.210 + public: 1.211 + virtual ~NotificationClient() {} 1.212 + 1.213 + /** 1.214 + * Called before executing one or several draw commands, which means 1.215 + * once per flush when deferred rendering is enabled. 1.216 + */ 1.217 + virtual void prepareForDraw() {} 1.218 + 1.219 + /** 1.220 + * Called after a recording a draw command if additional memory 1.221 + * had to be allocated for recording. 1.222 + * @param newAllocatedStorage same value as would be returned by 1.223 + * storageAllocatedForRecording(), for convenience. 1.224 + */ 1.225 + virtual void storageAllocatedForRecordingChanged( 1.226 + size_t newAllocatedStorage) {} 1.227 + 1.228 + /** 1.229 + * Called after pending draw commands have been flushed 1.230 + */ 1.231 + virtual void flushedDrawCommands() {} 1.232 + 1.233 + /** 1.234 + * Called after pending draw commands have been skipped, meaning 1.235 + * that they were optimized-out because the canvas is cleared 1.236 + * or completely overwritten by the command currently being recorded. 1.237 + */ 1.238 + virtual void skippedPendingDrawCommands() {} 1.239 + }; 1.240 + 1.241 +protected: 1.242 + virtual SkCanvas* canvasForDrawIter(); 1.243 + SkDeferredDevice* getDeferredDevice() const; 1.244 + 1.245 +private: 1.246 + SkDeferredCanvas(SkDeferredDevice*); 1.247 + 1.248 + void recordedDrawCommand(); 1.249 + SkCanvas* drawingCanvas() const; 1.250 + SkCanvas* immediateCanvas() const; 1.251 + bool isFullFrame(const SkRect*, const SkPaint*) const; 1.252 + void validate() const; 1.253 + void init(); 1.254 + bool fDeferredDrawing; 1.255 + 1.256 + friend class SkDeferredCanvasTester; // for unit testing 1.257 + typedef SkCanvas INHERITED; 1.258 +}; 1.259 + 1.260 + 1.261 +#endif