Home | History | Annotate | Download | only in utils
      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 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 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(SkDevice* 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 int save(SaveFlags flags) SK_OVERRIDE;
    142     virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
    143                           SaveFlags flags) SK_OVERRIDE;
    144     virtual void restore() SK_OVERRIDE;
    145     virtual bool isDrawingToLayer() const SK_OVERRIDE;
    146     virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
    147     virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE;
    148     virtual bool rotate(SkScalar degrees) SK_OVERRIDE;
    149     virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE;
    150     virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE;
    151     virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE;
    152     virtual bool clipRect(const SkRect& rect, SkRegion::Op op,
    153                           bool doAntiAlias) SK_OVERRIDE;
    154     virtual bool clipRRect(const SkRRect& rect, SkRegion::Op op,
    155                            bool doAntiAlias) SK_OVERRIDE;
    156     virtual bool clipPath(const SkPath& path, SkRegion::Op op,
    157                           bool doAntiAlias) SK_OVERRIDE;
    158     virtual bool clipRegion(const SkRegion& deviceRgn,
    159                             SkRegion::Op op) SK_OVERRIDE;
    160     virtual void clear(SkColor) SK_OVERRIDE;
    161     virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
    162     virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
    163                             const SkPaint& paint) SK_OVERRIDE;
    164     virtual void drawOval(const SkRect&, const SkPaint& paint) SK_OVERRIDE;
    165     virtual void drawRect(const SkRect& rect, const SkPaint& paint) SK_OVERRIDE;
    166     virtual void drawRRect(const SkRRect&, const SkPaint& paint) SK_OVERRIDE;
    167     virtual void drawPath(const SkPath& path, const SkPaint& paint)
    168                           SK_OVERRIDE;
    169     virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
    170                             SkScalar top, const SkPaint* paint)
    171                             SK_OVERRIDE;
    172     virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
    173                                 const SkRect& dst, const SkPaint* paint)
    174                                 SK_OVERRIDE;
    175 
    176     virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
    177                                   const SkPaint* paint) SK_OVERRIDE;
    178     virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
    179                                 const SkRect& dst, const SkPaint* paint)
    180                                 SK_OVERRIDE;
    181     virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
    182                             const SkPaint* paint) SK_OVERRIDE;
    183     virtual void drawText(const void* text, size_t byteLength, SkScalar x,
    184                           SkScalar y, const SkPaint& paint) SK_OVERRIDE;
    185     virtual void drawPosText(const void* text, size_t byteLength,
    186                              const SkPoint pos[], const SkPaint& paint)
    187                              SK_OVERRIDE;
    188     virtual void drawPosTextH(const void* text, size_t byteLength,
    189                               const SkScalar xpos[], SkScalar constY,
    190                               const SkPaint& paint) SK_OVERRIDE;
    191     virtual void drawTextOnPath(const void* text, size_t byteLength,
    192                                 const SkPath& path, const SkMatrix* matrix,
    193                                 const SkPaint& paint) SK_OVERRIDE;
    194     virtual void drawPicture(SkPicture& picture) SK_OVERRIDE;
    195     virtual void drawVertices(VertexMode vmode, int vertexCount,
    196                               const SkPoint vertices[], const SkPoint texs[],
    197                               const SkColor colors[], SkXfermode* xmode,
    198                               const uint16_t indices[], int indexCount,
    199                               const SkPaint& paint) SK_OVERRIDE;
    200     virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE;
    201     virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE;
    202 
    203 public:
    204     class NotificationClient {
    205     public:
    206         virtual ~NotificationClient() {}
    207 
    208         /**
    209          *  Called before executing one or several draw commands, which means
    210          *  once per flush when deferred rendering is enabled.
    211          */
    212         virtual void prepareForDraw() {}
    213 
    214         /**
    215          *  Called after a recording a draw command if additional memory
    216          *  had to be allocated for recording.
    217          *  @param newAllocatedStorage same value as would be returned by
    218          *      storageAllocatedForRecording(), for convenience.
    219          */
    220         virtual void storageAllocatedForRecordingChanged(
    221             size_t newAllocatedStorage) {}
    222 
    223         /**
    224          *  Called after pending draw commands have been flushed
    225          */
    226         virtual void flushedDrawCommands() {}
    227 
    228         /**
    229          *  Called after pending draw commands have been skipped, meaning
    230          *  that they were optimized-out because the canvas is cleared
    231          *  or completely overwritten by the command currently being recorded.
    232          */
    233         virtual void skippedPendingDrawCommands() {}
    234     };
    235 
    236 protected:
    237     virtual SkCanvas* canvasForDrawIter();
    238     DeferredDevice* getDeferredDevice() const;
    239 
    240 private:
    241     SkDeferredCanvas(DeferredDevice*);
    242 
    243     void recordedDrawCommand();
    244     SkCanvas* drawingCanvas() const;
    245     SkCanvas* immediateCanvas() const;
    246     bool isFullFrame(const SkRect*, const SkPaint*) const;
    247     void validate() const;
    248     void init();
    249     bool            fDeferredDrawing;
    250 
    251     friend class SkDeferredCanvasTester; // for unit testing
    252     typedef SkCanvas INHERITED;
    253 };
    254 
    255 
    256 #endif
    257