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 "Timer.h" 15 16namespace { 17 18class Dumper { 19public: 20 explicit Dumper(SkCanvas* canvas, int count, bool timeWithCommand) 21 : fDigits(0) 22 , fIndent(0) 23 , fIndex(0) 24 , fDraw(canvas) 25 , fTimeWithCommand(timeWithCommand) { 26 while (count > 0) { 27 count /= 10; 28 fDigits++; 29 } 30 } 31 32 template <typename T> 33 void operator()(const T& command) { 34 Timer timer; 35 timer.start(); 36 fDraw(command); 37 timer.end(); 38 39 this->print(command, timer.fCpu); 40 } 41 42 void operator()(const SkRecords::NoOp&) { 43 // Move on without printing anything. 44 } 45 46 template <typename T> 47 void print(const T& command, double time) { 48 this->printNameAndTime(command, time); 49 } 50 51 void print(const SkRecords::Restore& command, double time) { 52 --fIndent; 53 this->printNameAndTime(command, time); 54 } 55 56 void print(const SkRecords::Save& command, double time) { 57 this->printNameAndTime(command, time); 58 ++fIndent; 59 } 60 61 void print(const SkRecords::SaveLayer& command, double time) { 62 this->printNameAndTime(command, time); 63 ++fIndent; 64 } 65 66private: 67 template <typename T> 68 void printNameAndTime(const T& command, double time) { 69 if (!fTimeWithCommand) { 70 printf("%6.1f ", time * 1000); 71 } 72 printf("%*d ", fDigits, fIndex++); 73 for (int i = 0; i < fIndent; i++) { 74 putchar('\t'); 75 } 76 if (fTimeWithCommand) { 77 printf("%6.1f ", time * 1000); 78 } 79 puts(NameOf(command)); 80 } 81 82 template <typename T> 83 static const char* NameOf(const T&) { 84 #define CASE(U) case SkRecords::U##_Type: return #U; 85 switch(T::kType) { SK_RECORD_TYPES(CASE); } 86 #undef CASE 87 SkDEBUGFAIL("Unknown T"); 88 return "Unknown T"; 89 } 90 91 static const char* NameOf(const SkRecords::SaveLayer&) { 92 return "\x1b[31;1mSaveLayer\x1b[0m"; // Bold red. 93 } 94 95 int fDigits; 96 int fIndent; 97 int fIndex; 98 SkRecords::Draw fDraw; 99 const bool fTimeWithCommand; 100}; 101 102} // namespace 103 104void DumpRecord(const SkRecord& record, 105 SkCanvas* canvas, 106 bool timeWithCommand) { 107 Dumper dumper(canvas, record.count(), timeWithCommand); 108 for (unsigned i = 0; i < record.count(); i++) { 109 record.visit<void>(i, dumper); 110 } 111} 112