Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2007 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkPicture_DEFINED
     11 #define SkPicture_DEFINED
     12 
     13 #include "SkRefCnt.h"
     14 #include "SkSerializationHelpers.h"
     15 
     16 class SkBBoxHierarchy;
     17 class SkBitmap;
     18 class SkCanvas;
     19 class SkPicturePlayback;
     20 class SkPictureRecord;
     21 class SkStream;
     22 class SkWStream;
     23 
     24 /** \class SkPicture
     25 
     26     The SkPicture class records the drawing commands made to a canvas, to
     27     be played back at a later time.
     28 */
     29 class SK_API SkPicture : public SkRefCnt {
     30 public:
     31     SK_DECLARE_INST_COUNT(SkPicture)
     32 
     33     /** The constructor prepares the picture to record.
     34         @param width the width of the virtual device the picture records.
     35         @param height the height of the virtual device the picture records.
     36     */
     37     SkPicture();
     38     /** Make a copy of the contents of src. If src records more drawing after
     39         this call, those elements will not appear in this picture.
     40     */
     41     SkPicture(const SkPicture& src);
     42     /**
     43      *  Recreate a picture that was serialized into a stream. *success is set to
     44      *  true if the picture was deserialized successfully and false otherwise.
     45      *  decoder is used to decode any SkBitmaps that were encoded into the stream.
     46      */
     47     explicit SkPicture(SkStream*, bool* success = NULL,
     48                        SkSerializationHelpers::DecodeBitmap decoder = NULL);
     49     virtual ~SkPicture();
     50 
     51     /**
     52      *  Swap the contents of the two pictures. Guaranteed to succeed.
     53      */
     54     void swap(SkPicture& other);
     55 
     56     /**
     57      *  Creates a thread-safe clone of the picture that is ready for playback.
     58      */
     59     SkPicture* clone() const;
     60 
     61     /**
     62      * Creates multiple thread-safe clones of this picture that are ready for
     63      * playback. The resulting clones are stored in the provided array of
     64      * SkPictures.
     65      */
     66     void clone(SkPicture* pictures, int count) const;
     67 
     68     enum RecordingFlags {
     69         /*  This flag specifies that when clipPath() is called, the path will
     70             be faithfully recorded, but the recording canvas' current clip will
     71             only see the path's bounds. This speeds up the recording process
     72             without compromising the fidelity of the playback. The only side-
     73             effect for recording is that calling getTotalClip() or related
     74             clip-query calls will reflect the path's bounds, not the actual
     75             path.
     76          */
     77         kUsePathBoundsForClip_RecordingFlag = 0x01,
     78         /*  This flag causes the picture to compute bounding boxes and build
     79             up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas'
     80             usually stack-based clip/etc state. This requires an increase in
     81             recording time (often ~2x; likely more for very complex pictures),
     82             but allows us to perform much faster culling at playback time, and
     83             completely avoid some unnecessary clips and other operations. This
     84             is ideal for tiled rendering, or any other situation where you're
     85             drawing a fraction of a large scene into a smaller viewport.
     86 
     87             In most cases the record cost is offset by the playback improvement
     88             after a frame or two of tiled rendering (and complex pictures that
     89             induce the worst record times will generally get the largest
     90             speedups at playback time).
     91 
     92             Note: Currently this is not serializable, the bounding data will be
     93             discarded if you serialize into a stream and then deserialize.
     94         */
     95         kOptimizeForClippedPlayback_RecordingFlag = 0x02
     96     };
     97 
     98     /** Returns the canvas that records the drawing commands.
     99         @param width the base width for the picture, as if the recording
    100                      canvas' bitmap had this width.
    101         @param height the base width for the picture, as if the recording
    102                      canvas' bitmap had this height.
    103         @param recordFlags optional flags that control recording.
    104         @return the picture canvas.
    105     */
    106     SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0);
    107 
    108     /** Returns the recording canvas if one is active, or NULL if recording is
    109         not active. This does not alter the refcnt on the canvas (if present).
    110     */
    111     SkCanvas* getRecordingCanvas() const;
    112     /** Signal that the caller is done recording. This invalidates the canvas
    113         returned by beginRecording/getRecordingCanvas, and prepares the picture
    114         for drawing. Note: this happens implicitly the first time the picture
    115         is drawn.
    116     */
    117     void endRecording();
    118 
    119     /** Replays the drawing commands on the specified canvas. This internally
    120         calls endRecording() if that has not already been called.
    121         @param surface the canvas receiving the drawing commands.
    122     */
    123     void draw(SkCanvas* surface);
    124 
    125     /** Return the width of the picture's recording canvas. This
    126         value reflects what was passed to setSize(), and does not necessarily
    127         reflect the bounds of what has been recorded into the picture.
    128         @return the width of the picture's recording canvas
    129     */
    130     int width() const { return fWidth; }
    131 
    132     /** Return the height of the picture's recording canvas. This
    133         value reflects what was passed to setSize(), and does not necessarily
    134         reflect the bounds of what has been recorded into the picture.
    135         @return the height of the picture's recording canvas
    136     */
    137     int height() const { return fHeight; }
    138 
    139     /**
    140      *  Serialize to a stream. If non NULL, encoder will be used to encode
    141      *  any bitmaps in the picture.
    142      */
    143     void serialize(SkWStream*, SkSerializationHelpers::EncodeBitmap encoder = NULL) const;
    144 
    145 #ifdef SK_BUILD_FOR_ANDROID
    146     /** Signals that the caller is prematurely done replaying the drawing
    147         commands. This can be called from a canvas virtual while the picture
    148         is drawing. Has no effect if the picture is not drawing.
    149         @deprecated preserving for legacy purposes
    150     */
    151     void abortPlayback();
    152 #endif
    153 
    154 protected:
    155     // V2 : adds SkPixelRef's generation ID.
    156     // V3 : PictInfo tag at beginning, and EOF tag at the end
    157     // V4 : move SkPictInfo to be the header
    158     // V5 : don't read/write FunctionPtr on cross-process (we can detect that)
    159     // V6 : added serialization of SkPath's bounds (and packed its flags tighter)
    160     // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect)
    161     // V8 : Add an option for encoding bitmaps
    162     // V9 : Allow the reader and writer of an SKP disagree on whether to support
    163     //      SK_SUPPORT_HINTING_SCALE_FACTOR
    164     // V10: add drawRRect, drawOval, clipRRect
    165     static const uint32_t PICTURE_VERSION = 10;
    166 
    167     // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
    168     // install their own SkPicturePlayback-derived players,SkPictureRecord-derived
    169     // recorders and set the picture size
    170     SkPicturePlayback* fPlayback;
    171     SkPictureRecord* fRecord;
    172     int fWidth, fHeight;
    173 
    174     // For testing. Derived classes may instantiate an alternate
    175     // SkBBoxHierarchy implementation
    176     virtual SkBBoxHierarchy* createBBoxHierarchy() const;
    177 
    178 private:
    179 
    180     friend class SkFlatPicture;
    181     friend class SkPicturePlayback;
    182 
    183     typedef SkRefCnt INHERITED;
    184 };
    185 
    186 class SkAutoPictureRecord : SkNoncopyable {
    187 public:
    188     SkAutoPictureRecord(SkPicture* pict, int width, int height,
    189                         uint32_t recordingFlags = 0) {
    190         fPicture = pict;
    191         fCanvas = pict->beginRecording(width, height, recordingFlags);
    192     }
    193     ~SkAutoPictureRecord() {
    194         fPicture->endRecording();
    195     }
    196 
    197     /** Return the canvas to draw into for recording into the picture.
    198     */
    199     SkCanvas* getRecordingCanvas() const { return fCanvas; }
    200 
    201 private:
    202     SkPicture*  fPicture;
    203     SkCanvas*   fCanvas;
    204 };
    205 
    206 
    207 #endif
    208