Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2014 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 SkPictureRecorder_DEFINED
      9 #define SkPictureRecorder_DEFINED
     10 
     11 #include "../private/SkMiniRecorder.h"
     12 #include "SkBBHFactory.h"
     13 #include "SkPicture.h"
     14 #include "SkRefCnt.h"
     15 
     16 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
     17 namespace android {
     18     class Picture;
     19 };
     20 #endif
     21 
     22 class GrContext;
     23 class SkCanvas;
     24 class SkDrawable;
     25 class SkPictureRecord;
     26 class SkRecord;
     27 class SkRecorder;
     28 
     29 class SK_API SkPictureRecorder : SkNoncopyable {
     30 public:
     31     SkPictureRecorder();
     32     ~SkPictureRecorder();
     33 
     34     enum RecordFlags {
     35         // If you call drawPicture() or drawDrawable() on the recording canvas, this flag forces
     36         // that object to playback its contents immediately rather than reffing the object.
     37         kPlaybackDrawPicture_RecordFlag     = 1 << 0,
     38     };
     39 
     40     enum FinishFlags {
     41         kReturnNullForEmpty_FinishFlag  = 1 << 0,   // no draw-ops will return nullptr
     42     };
     43 
     44     /** Returns the canvas that records the drawing commands.
     45         @param bounds the cull rect used when recording this picture. Any drawing the falls outside
     46                       of this rect is undefined, and may be drawn or it may not.
     47         @param bbhFactory factory to create desired acceleration structure
     48         @param recordFlags optional flags that control recording.
     49         @return the canvas.
     50     */
     51     SkCanvas* beginRecording(const SkRect& bounds,
     52                              SkBBHFactory* bbhFactory = NULL,
     53                              uint32_t recordFlags = 0);
     54 
     55     SkCanvas* beginRecording(SkScalar width, SkScalar height,
     56                              SkBBHFactory* bbhFactory = NULL,
     57                              uint32_t recordFlags = 0) {
     58         return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory, recordFlags);
     59     }
     60 
     61     /** Returns the recording canvas if one is active, or NULL if recording is
     62         not active. This does not alter the refcnt on the canvas (if present).
     63     */
     64     SkCanvas* getRecordingCanvas();
     65 
     66     /**
     67      *  Signal that the caller is done recording. This invalidates the canvas returned by
     68      *  beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who
     69      *  must call unref() when they are done using it.
     70      *
     71      *  The returned picture is immutable. If during recording drawables were added to the canvas,
     72      *  these will have been "drawn" into a recording canvas, so that this resulting picture will
     73      *  reflect their current state, but will not contain a live reference to the drawables
     74      *  themselves.
     75      */
     76     sk_sp<SkPicture> finishRecordingAsPicture(uint32_t endFlags = 0);
     77 
     78     /**
     79      *  Signal that the caller is done recording, and update the cull rect to use for bounding
     80      *  box hierarchy (BBH) generation. The behavior is the same as calling
     81      *  finishRecordingAsPicture(), except that this method updates the cull rect initially passed
     82      *  into beginRecording.
     83      *  @param cullRect the new culling rectangle to use as the overall bound for BBH generation
     84      *                  and subsequent culling operations.
     85      *  @return the picture containing the recorded content.
     86      */
     87     sk_sp<SkPicture> finishRecordingAsPictureWithCull(const SkRect& cullRect,
     88                                                       uint32_t endFlags = 0);
     89 
     90     /**
     91      *  Signal that the caller is done recording. This invalidates the canvas returned by
     92      *  beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who
     93      *  must call unref() when they are done using it.
     94      *
     95      *  Unlike finishRecordingAsPicture(), which returns an immutable picture, the returned drawable
     96      *  may contain live references to other drawables (if they were added to the recording canvas)
     97      *  and therefore this drawable will reflect the current state of those nested drawables anytime
     98      *  it is drawn or a new picture is snapped from it (by calling drawable->newPictureSnapshot()).
     99      */
    100     sk_sp<SkDrawable> finishRecordingAsDrawable(uint32_t endFlags = 0);
    101 
    102 private:
    103     void reset();
    104 
    105     /** Replay the current (partially recorded) operation stream into
    106         canvas. This call doesn't close the current recording.
    107     */
    108 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    109     friend class android::Picture;
    110 #endif
    111     friend class SkPictureRecorderReplayTester; // for unit testing
    112     void partialReplay(SkCanvas* canvas) const;
    113 
    114     bool                        fActivelyRecording;
    115     uint32_t                    fFlags;
    116     SkRect                      fCullRect;
    117     sk_sp<SkBBoxHierarchy>      fBBH;
    118     std::unique_ptr<SkRecorder> fRecorder;
    119     sk_sp<SkRecord>             fRecord;
    120     SkMiniRecorder              fMiniRecorder;
    121 
    122     typedef SkNoncopyable INHERITED;
    123 };
    124 
    125 #endif
    126