Flutter Engine
The Flutter Engine
SkPictureRecorder.cpp
Go to the documentation of this file.
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
9
16#include "src/core/SkRecord.h"
20#include "src/core/SkRecorder.h"
21
22#include <cstddef>
23#include <memory>
24#include <utility>
25
26using namespace skia_private;
27
29 fActivelyRecording = false;
30 fRecorder = std::make_unique<SkRecorder>(nullptr, SkRect::MakeEmpty());
31}
32
34
37 const SkRect cullRect = userCullRect.isEmpty() ? SkRect::MakeEmpty() : userCullRect;
38
39 fCullRect = cullRect;
40 fBBH = std::move(bbh);
41
42 if (!fRecord) {
43 fRecord.reset(new SkRecord);
44 }
45 fRecorder->reset(fRecord.get(), cullRect);
46 fActivelyRecording = true;
47 return this->getRecordingCanvas();
48}
49
51 return this->beginRecording(bounds, factory ? (*factory)() : nullptr);
52}
53
55 return fActivelyRecording ? fRecorder.get() : nullptr;
56}
57
58class SkEmptyPicture final : public SkPicture {
59public:
60 void playback(SkCanvas*, AbortCallback*) const override { }
61
62 size_t approximateBytesUsed() const override { return sizeof(*this); }
63 int approximateOpCount(bool nested) const override { return 0; }
64 SkRect cullRect() const override { return SkRect::MakeEmpty(); }
65};
66
68 fActivelyRecording = false;
69 fRecorder->restoreToCount(1); // If we were missing any restores, add them now.
70
71 if (fRecord->count() == 0) {
72 return sk_make_sp<SkEmptyPicture>();
73 }
74
75 // TODO: delay as much of this work until just before first playback?
76 SkRecordOptimize(fRecord.get());
77
78 SkDrawableList* drawableList = fRecorder->getDrawableList();
79 std::unique_ptr<SkBigPicture::SnapshotArray> pictList{
80 drawableList ? drawableList->newDrawableSnapshot() : nullptr
81 };
82
83 if (fBBH) {
86 SkRecordFillBounds(fCullRect, *fRecord, bounds.data(), meta);
87
88 fBBH->insert(bounds.data(), meta, fRecord->count());
89
90 // Now that we've calculated content bounds, we can update fCullRect, often trimming it.
91 SkRect bbhBound = SkRect::MakeEmpty();
92 for (int i = 0; i < fRecord->count(); i++) {
93 bbhBound.join(bounds[i]);
94 }
95 SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound))
96 || (bbhBound.isEmpty() && fCullRect.isEmpty()));
97 fCullRect = bbhBound;
98 }
99
100 size_t subPictureBytes = fRecorder->approxBytesUsedBySubPictures();
101 for (int i = 0; pictList && i < pictList->count(); i++) {
102 subPictureBytes += pictList->begin()[i]->approximateBytesUsed();
103 }
104 return sk_make_sp<SkBigPicture>(fCullRect,
105 std::move(fRecord),
106 std::move(pictList),
107 std::move(fBBH),
108 subPictureBytes);
109}
110
112 fCullRect = cullRect;
113 return this->finishRecordingAsPicture();
114}
115
116
117void SkPictureRecorder::partialReplay(SkCanvas* canvas) const {
118 if (nullptr == canvas) {
119 return;
120 }
121
122 int drawableCount = 0;
123 SkDrawable* const* drawables = nullptr;
124 SkDrawableList* drawableList = fRecorder->getDrawableList();
125 if (drawableList) {
126 drawableCount = drawableList->count();
127 drawables = drawableList->begin();
128 }
129 SkRecordDraw(*fRecord, canvas, nullptr, drawables, drawableCount, nullptr/*bbh*/, nullptr/*callback*/);
130}
131
133 fActivelyRecording = false;
134 fRecorder->restoreToCount(1); // If we were missing any restores, add them now.
135
136 SkRecordOptimize(fRecord.get());
137
138 if (fBBH) {
139 AutoTArray<SkRect> bounds(fRecord->count());
141 SkRecordFillBounds(fCullRect, *fRecord, bounds.data(), meta);
142 fBBH->insert(bounds.data(), meta, fRecord->count());
143 }
144
145 sk_sp<SkDrawable> drawable =
146 sk_make_sp<SkRecordedDrawable>(std::move(fRecord), std::move(fBBH),
147 fRecorder->detachDrawableList(), fCullRect);
148
149 return drawable;
150}
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SkRecordFillBounds(const SkRect &cullRect, const SkRecord &record, SkRect bounds[], SkBBoxHierarchy::Metadata meta[])
void SkRecordDraw(const SkRecord &record, SkCanvas *canvas, SkPicture const *const drawablePicts[], SkDrawable *const drawables[], int drawableCount, const SkBBoxHierarchy *bbh, SkPicture::AbortCallback *callback)
void SkRecordOptimize(SkRecord *record)
virtual void insert(const SkRect[], int N)=0
SkBigPicture::SnapshotArray * newDrawableSnapshot()
Definition: SkRecorder.cpp:62
int count() const
Definition: SkRecorder.h:62
SkDrawable *const * begin() const
Definition: SkRecorder.h:63
SkRect cullRect() const override
size_t approximateBytesUsed() const override
void playback(SkCanvas *, AbortCallback *) const override
int approximateOpCount(bool nested) const override
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPictureWithCull(const SkRect &cullRect)
SkCanvas * getRecordingCanvas()
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkDrawable > finishRecordingAsDrawable()
int count() const
Definition: SkRecord.h:38
T * get() const
Definition: SkRefCnt.h:303
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
Optional< SkRect > bounds
Definition: SkRecords.h:189
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595
bool contains(SkScalar x, SkScalar y) const
Definition: extension.cpp:19
bool isEmpty() const
Definition: SkRect.h:693
void join(const SkRect &r)
Definition: SkRect.cpp:126