Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
dump_record.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
14#include "src/base/SkTime.h"
16#include "src/core/SkRecord.h"
19#include "src/core/SkRecorder.h"
22
23#include <cstdio>
24
25static DEFINE_string2(skps, r, "", ".SKPs to dump.");
26static DEFINE_string(match, "", "The usual filters on file names to dump.");
27static DEFINE_bool2(optimize, O, false, "Run SkRecordOptimize before dumping.");
28static DEFINE_int(tile, 1000000000, "Simulated tile size.");
29static DEFINE_bool(timeWithCommand, false,
30 "If true, print time next to command, else in first column.");
31static DEFINE_string2(write, w, "", "Write the (optimized) picture to the named file.");
32
33class Dumper {
34public:
35 explicit Dumper(SkCanvas* canvas, int count)
36 : fDigits(0)
37 , fIndent(0)
38 , fIndex(0)
39 , fDraw(canvas, nullptr, nullptr, 0, nullptr)
40 {
41 while (count > 0) {
42 count /= 10;
43 fDigits++;
44 }
45 }
46
47 template <typename T>
48 void operator()(const T& command) {
49 auto start = SkTime::GetNSecs();
50 fDraw(command);
51 this->print(command, SkTime::GetNSecs() - start);
52 }
53
54 void operator()(const SkRecords::NoOp&) {
55 // Move on without printing anything.
56 }
57
58 template <typename T>
59 void print(const T& command, double ns) {
60 this->printNameAndTime(command, ns);
61 }
62
63 void print(const SkRecords::Restore& command, double ns) {
64 --fIndent;
65 this->printNameAndTime(command, ns);
66 }
67
68 void print(const SkRecords::Save& command, double ns) {
69 this->printNameAndTime(command, ns);
70 ++fIndent;
71 }
72
73 void print(const SkRecords::SaveLayer& command, double ns) {
74 this->printNameAndTime(command, ns);
75 ++fIndent;
76 }
77
78 void print(const SkRecords::DrawPicture& command, double ns) {
79 this->printNameAndTime(command, ns);
80
81 if (auto bp = SkPicturePriv::AsSkBigPicture(command.picture)) {
82 ++fIndent;
83
84 const SkRecord& record = *bp->record();
85 for (int i = 0; i < record.count(); i++) {
86 record.visit(i, *this);
87 }
88
89 --fIndent;
90 }
91 }
92
93 void print(const SkRecords::DrawAnnotation& command, double ns) {
94 int us = (int)(ns * 1e-3);
95 if (!FLAGS_timeWithCommand) {
96 printf("%6dus ", us);
97 }
98 printf("%*d ", fDigits, fIndex++);
99 for (int i = 0; i < fIndent; i++) {
100 printf(" ");
101 }
102 if (FLAGS_timeWithCommand) {
103 printf("%6dus ", us);
104 }
105 printf("DrawAnnotation [%g %g %g %g] %s\n",
106 command.rect.left(), command.rect.top(), command.rect.right(), command.rect.bottom(),
107 command.key.c_str());
108 }
109
110private:
111 template <typename T>
112 void printNameAndTime(const T& command, double ns) {
113 int us = (int)(ns * 1e-3);
114 if (!FLAGS_timeWithCommand) {
115 printf("%6dus ", us);
116 }
117 printf("%*d ", fDigits, fIndex++);
118 for (int i = 0; i < fIndent; i++) {
119 printf(" ");
120 }
121 if (FLAGS_timeWithCommand) {
122 printf("%6dus ", us);
123 }
124 puts(NameOf(command));
125 }
126
127 template <typename T>
128 static const char* NameOf(const T&) {
129 #define CASE(U) case SkRecords::U##_Type: return #U;
130 switch (T::kType) { SK_RECORD_TYPES(CASE) }
131 #undef CASE
132 SkDEBUGFAIL("Unknown T");
133 return "Unknown T";
134 }
135
136 static const char* NameOf(const SkRecords::SaveLayer&) {
137 return "\x1b[31;1mSaveLayer\x1b[0m"; // Bold red.
138 }
139
140 int fDigits;
141 int fIndent;
142 int fIndex;
143 SkRecords::Draw fDraw;
144};
145
146int main(int argc, char** argv) {
148
149 for (int i = 0; i < FLAGS_skps.size(); i++) {
150 if (CommandLineFlags::ShouldSkip(FLAGS_match, FLAGS_skps[i])) {
151 continue;
152 }
153
154 std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(FLAGS_skps[i]);
155 if (!stream) {
156 SkDebugf("Could not read %s.\n", FLAGS_skps[i]);
157 return 1;
158 }
160 if (!src) {
161 SkDebugf("Could not read %s as an SkPicture.\n", FLAGS_skps[i]);
162 return 1;
163 }
164 const int w = SkScalarCeilToInt(src->cullRect().width());
165 const int h = SkScalarCeilToInt(src->cullRect().height());
166
167 SkRecord record;
168 SkRecorder rec(&record, w, h);
169 src->playback(&rec);
170
171 if (FLAGS_optimize) {
172 SkRecordOptimize(&record);
173 }
174
176 bitmap.allocN32Pixels(w, h);
177 SkCanvas canvas(bitmap);
178 canvas.clipRect(SkRect::MakeWH(SkIntToScalar(FLAGS_tile),
179 SkIntToScalar(FLAGS_tile)));
180
181 printf("%s %s\n", FLAGS_optimize ? "optimized" : "not-optimized", FLAGS_skps[i]);
182
183 Dumper dumper(&canvas, record.count());
184 for (int j = 0; j < record.count(); j++) {
185 record.visit(j, dumper);
186 }
187
188 if (FLAGS_write.size() > 0) {
190 SkRecordDraw(record,
192 nullptr,
193 nullptr,
194 0,
195 nullptr,
196 nullptr);
198 SkFILEWStream ostream(FLAGS_write[0]);
199 SkSerialProcs sProcs;
200 sProcs.fImageProc = [](SkImage* img, void*) -> sk_sp<SkData> {
201 return SkPngEncoder::Encode(nullptr, img, SkPngEncoder::Options{});
202 };
203 dst->serialize(&ostream, &sProcs);
204 }
205 }
206
207 return 0;
208}
#define DEFINE_bool(name, defaultValue, helpString)
#define DEFINE_int(name, defaultValue, helpString)
#define DEFINE_bool2(name, shortName, defaultValue, helpString)
#define DEFINE_string2(name, shortName, defaultValue, helpString)
#define DEFINE_string(name, defaultValue, helpString)
static bool match(const char *needle, const char *haystack)
Definition DM.cpp:1132
int count
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkTileMode optimize(SkTileMode tm, int dimension)
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)
#define SK_RECORD_TYPES(M)
Definition SkRecords.h:56
#define SkScalarCeilToInt(x)
Definition SkScalar.h:36
#define SkIntToScalar(x)
Definition SkScalar.h:57
Type::kYUV Type::kRGBA() int(0.7 *637)
static bool ShouldSkip(const SkTDArray< const char * > &strings, const char *name)
static void Parse(int argc, const char *const *argv)
void operator()(const T &command)
void print(const SkRecords::DrawPicture &command, double ns)
void operator()(const SkRecords::NoOp &)
void print(const SkRecords::DrawAnnotation &command, double ns)
void print(const SkRecords::Restore &command, double ns)
void print(const SkRecords::Save &command, double ns)
void print(const T &command, double ns)
Dumper(SkCanvas *canvas, int count)
void print(const SkRecords::SaveLayer &command, double ns)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
static const SkBigPicture * AsSkBigPicture(const sk_sp< const SkPicture > &picture)
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
auto visit(int i, F &&f) const -> decltype(f(SkRecords::NoOp()))
Definition SkRecord.h:45
int count() const
Definition SkRecord.h:38
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
Definition SkStream.cpp:922
#define CASE(U)
char ** argv
Definition library.h:9
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
double GetNSecs()
Definition SkTime.cpp:17
Definition main.py:1
SkScalar w
SkScalar h
#define T
void write(SkWStream *wStream, const T &text)
Definition skqp.cpp:188
static SkRect MakeIWH(int w, int h)
Definition SkRect.h:623
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
SkSerialImageProc fImageProc