DumpRecord.cpp 3.7 KB

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