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