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