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 "SkTime.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         , 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>
     33     void operator()(const T& command) {
     34         auto start = SkTime::GetNSecs();
     35         fDraw(command);
     36         this->print(command, SkTime::GetNSecs() - start);
     37     }
     38 
     39     void operator()(const SkRecords::NoOp&) {
     40         // Move on without printing anything.
     41     }
     42 
     43     template <typename T>
     44     void print(const T& command, double ns) {
     45         this->printNameAndTime(command, ns);
     46     }
     47 
     48     void print(const SkRecords::Restore& command, double ns) {
     49         --fIndent;
     50         this->printNameAndTime(command, ns);
     51     }
     52 
     53     void print(const SkRecords::Save& command, double ns) {
     54         this->printNameAndTime(command, ns);
     55         ++fIndent;
     56     }
     57 
     58     void print(const SkRecords::SaveLayer& command, double ns) {
     59         this->printNameAndTime(command, ns);
     60         ++fIndent;
     61     }
     62 
     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
     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>
     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>
    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 
    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 
    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