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 
     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