• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <stdio.h>
9 
10 #include "SkRecord.h"
11 #include "SkRecordDraw.h"
12 
13 #include "DumpRecord.h"
14 #include "SkTime.h"
15 
16 namespace {
17 
18 class Dumper {
19 public:
Dumper(SkCanvas * canvas,int count,bool timeWithCommand)20     explicit Dumper(SkCanvas* canvas, int count, bool timeWithCommand)
21         : fDigits(0)
22         , fIndent(0)
23         , fIndex(0)
24         , fDraw(canvas, nullptr, nullptr, 0, nullptr)
25         , fTimeWithCommand(timeWithCommand) {
26         while (count > 0) {
27             count /= 10;
28             fDigits++;
29         }
30     }
31 
32     template <typename T>
operator ()(const T & command)33     void operator()(const T& command) {
34         auto start = SkTime::GetNSecs();
35         fDraw(command);
36         this->print(command, SkTime::GetNSecs() - start);
37     }
38 
operator ()(const SkRecords::NoOp &)39     void operator()(const SkRecords::NoOp&) {
40         // Move on without printing anything.
41     }
42 
43     template <typename T>
print(const T & command,double ns)44     void print(const T& command, double ns) {
45         this->printNameAndTime(command, ns);
46     }
47 
print(const SkRecords::Restore & command,double ns)48     void print(const SkRecords::Restore& command, double ns) {
49         --fIndent;
50         this->printNameAndTime(command, ns);
51     }
52 
print(const SkRecords::Save & command,double ns)53     void print(const SkRecords::Save& command, double ns) {
54         this->printNameAndTime(command, ns);
55         ++fIndent;
56     }
57 
print(const SkRecords::SaveLayer & command,double ns)58     void print(const SkRecords::SaveLayer& command, double ns) {
59         this->printNameAndTime(command, ns);
60         ++fIndent;
61     }
62 
print(const SkRecords::DrawPicture & command,double ns)63     void print(const SkRecords::DrawPicture& command, double ns) {
64         this->printNameAndTime(command, ns);
65 
66         if (auto bp = command.picture->asSkBigPicture()) {
67             ++fIndent;
68 
69             const SkRecord& record = *bp->record();
70             for (int i = 0; i < record.count(); i++) {
71                 record.visit(i, *this);
72             }
73 
74             --fIndent;
75         }
76     }
77 
78 #if 1
print(const SkRecords::DrawAnnotation & command,double ns)79     void print(const SkRecords::DrawAnnotation& command, double ns) {
80         int us = (int)(ns * 1e-3);
81         if (!fTimeWithCommand) {
82             printf("%6dus  ", us);
83         }
84         printf("%*d ", fDigits, fIndex++);
85         for (int i = 0; i < fIndent; i++) {
86             printf("    ");
87         }
88         if (fTimeWithCommand) {
89             printf("%6dus  ", us);
90         }
91         printf("DrawAnnotation [%g %g %g %g] %s\n",
92                command.rect.left(), command.rect.top(), command.rect.right(), command.rect.bottom(),
93                command.key.c_str());
94     }
95 #endif
96 
97 private:
98     template <typename T>
printNameAndTime(const T & command,double ns)99     void printNameAndTime(const T& command, double ns) {
100         int us = (int)(ns * 1e-3);
101         if (!fTimeWithCommand) {
102             printf("%6dus  ", us);
103         }
104         printf("%*d ", fDigits, fIndex++);
105         for (int i = 0; i < fIndent; i++) {
106             printf("    ");
107         }
108         if (fTimeWithCommand) {
109             printf("%6dus  ", us);
110         }
111         puts(NameOf(command));
112     }
113 
114     template <typename T>
NameOf(const T &)115     static const char* NameOf(const T&) {
116     #define CASE(U) case SkRecords::U##_Type: return #U;
117         switch(T::kType) { SK_RECORD_TYPES(CASE); }
118     #undef CASE
119         SkDEBUGFAIL("Unknown T");
120         return "Unknown T";
121     }
122 
NameOf(const SkRecords::SaveLayer &)123     static const char* NameOf(const SkRecords::SaveLayer&) {
124         return "\x1b[31;1mSaveLayer\x1b[0m";  // Bold red.
125     }
126 
127     int fDigits;
128     int fIndent;
129     int fIndex;
130     SkRecords::Draw fDraw;
131     const bool fTimeWithCommand;
132 };
133 
134 }  // namespace
135 
DumpRecord(const SkRecord & record,SkCanvas * canvas,bool timeWithCommand)136 void DumpRecord(const SkRecord& record,
137                   SkCanvas* canvas,
138                   bool timeWithCommand) {
139     Dumper dumper(canvas, record.count(), timeWithCommand);
140     for (int i = 0; i < record.count(); i++) {
141         record.visit(i, dumper);
142     }
143 }
144