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