paint_op_perftest.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <utility>
  5. #include "base/test/launcher/unit_test_launcher.h"
  6. #include "base/test/test_suite.h"
  7. #include "base/timer/lap_timer.h"
  8. #include "cc/paint/paint_op_buffer.h"
  9. #include "cc/paint/paint_op_buffer_serializer.h"
  10. #include "cc/paint/paint_shader.h"
  11. #include "cc/test/test_options_provider.h"
  12. #include "testing/perf/perf_result_reporter.h"
  13. #include "third_party/skia/include/core/SkMaskFilter.h"
  14. #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
  15. #include "third_party/skia/include/effects/SkDashPathEffect.h"
  16. #include "third_party/skia/include/effects/SkLayerDrawLooper.h"
  17. namespace cc {
  18. namespace {
  19. static const int kTimeLimitMillis = 2000;
  20. static const int kNumWarmupRuns = 20;
  21. static const int kTimeCheckInterval = 1;
  22. static const size_t kMaxSerializedBufferBytes = 100000;
  23. class PaintOpPerfTest : public testing::Test {
  24. public:
  25. PaintOpPerfTest()
  26. : timer_(kNumWarmupRuns,
  27. base::Milliseconds(kTimeLimitMillis),
  28. kTimeCheckInterval),
  29. serialized_data_(static_cast<char*>(
  30. base::AlignedAlloc(kMaxSerializedBufferBytes,
  31. PaintOpBuffer::PaintOpAlign))),
  32. deserialized_data_(static_cast<char*>(
  33. base::AlignedAlloc(sizeof(LargestPaintOp),
  34. PaintOpBuffer::PaintOpAlign))) {}
  35. void RunTest(const std::string& name, const PaintOpBuffer& buffer) {
  36. TestOptionsProvider test_options_provider;
  37. size_t bytes_written = 0u;
  38. PaintOpBufferSerializer::Preamble preamble;
  39. timer_.Reset();
  40. do {
  41. SimpleBufferSerializer serializer(
  42. serialized_data_.get(), kMaxSerializedBufferBytes,
  43. test_options_provider.serialize_options());
  44. serializer.Serialize(&buffer, nullptr, preamble);
  45. bytes_written = serializer.written();
  46. // Force client paint cache entries to be written every time.
  47. test_options_provider.client_paint_cache()->PurgeAll();
  48. timer_.NextLap();
  49. } while (!timer_.HasTimeLimitExpired());
  50. CHECK_GT(bytes_written, 0u);
  51. perf_test::PerfResultReporter reporter(name, " serialize");
  52. reporter.RegisterImportantMetric("", "runs/s");
  53. reporter.AddResult("", timer_.LapsPerSecond());
  54. size_t bytes_read = 0;
  55. timer_.Reset();
  56. test_options_provider.PushFonts();
  57. do {
  58. size_t remaining_read_bytes = bytes_written;
  59. char* to_read = serialized_data_.get();
  60. while (true) {
  61. PaintOp* deserialized_op = PaintOp::Deserialize(
  62. to_read, remaining_read_bytes, deserialized_data_.get(),
  63. sizeof(LargestPaintOp), &bytes_read,
  64. test_options_provider.deserialize_options());
  65. CHECK(deserialized_op);
  66. deserialized_op->DestroyThis();
  67. DCHECK_GE(remaining_read_bytes, bytes_read);
  68. if (remaining_read_bytes == bytes_read)
  69. break;
  70. remaining_read_bytes -= bytes_read;
  71. to_read += bytes_read;
  72. }
  73. timer_.NextLap();
  74. } while (!timer_.HasTimeLimitExpired());
  75. reporter = perf_test::PerfResultReporter(name, "deserialize");
  76. reporter.RegisterImportantMetric("", "runs/s");
  77. reporter.AddResult("", timer_.LapsPerSecond());
  78. }
  79. protected:
  80. base::LapTimer timer_;
  81. std::unique_ptr<char, base::AlignedFreeDeleter> serialized_data_;
  82. std::unique_ptr<char, base::AlignedFreeDeleter> deserialized_data_;
  83. };
  84. // Ops that can be memcopied both when serializing and deserializing.
  85. TEST_F(PaintOpPerfTest, SimpleOps) {
  86. PaintOpBuffer buffer;
  87. for (size_t i = 0; i < 100; ++i)
  88. buffer.push<ConcatOp>(SkM44());
  89. RunTest("simple", buffer);
  90. }
  91. // Drawing ops with flags that don't have nested objects.
  92. TEST_F(PaintOpPerfTest, DrawOps) {
  93. PaintOpBuffer buffer;
  94. PaintFlags flags;
  95. for (size_t i = 0; i < 100; ++i)
  96. buffer.push<DrawRectOp>(SkRect::MakeXYWH(1, 1, 1, 1), flags);
  97. RunTest("draw", buffer);
  98. }
  99. // Ops with worst case flags.
  100. TEST_F(PaintOpPerfTest, ManyFlagsOps) {
  101. PaintOpBuffer buffer;
  102. PaintFlags flags;
  103. SkScalar intervals[] = {1.f, 1.f};
  104. flags.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
  105. flags.setMaskFilter(SkMaskFilter::MakeBlur(
  106. SkBlurStyle::kOuter_SkBlurStyle, 4.3));
  107. flags.setColorFilter(
  108. SkColorMatrixFilter::MakeLightingFilter(SK_ColorYELLOW, SK_ColorGREEN));
  109. SkLayerDrawLooper::Builder looper_builder;
  110. looper_builder.addLayer();
  111. looper_builder.addLayer(2.3f, 4.5f);
  112. SkLayerDrawLooper::LayerInfo layer_info;
  113. looper_builder.addLayer(layer_info);
  114. flags.setLooper(looper_builder.detach());
  115. sk_sp<PaintShader> shader = PaintShader::MakeColor(SkColors::kTransparent);
  116. flags.setShader(std::move(shader));
  117. SkPath path;
  118. path.addCircle(2, 2, 5);
  119. path.addCircle(3, 4, 2);
  120. path.addArc(SkRect::MakeXYWH(1, 2, 3, 4), 5, 6);
  121. for (size_t i = 0; i < 100; ++i)
  122. buffer.push<DrawPathOp>(path, flags);
  123. RunTest("flags", buffer);
  124. }
  125. // DrawTextBlobOps,
  126. TEST_F(PaintOpPerfTest, TextOps) {
  127. PaintOpBuffer buffer;
  128. auto typeface = SkTypeface::MakeDefault();
  129. SkFont font;
  130. font.setTypeface(typeface);
  131. SkTextBlobBuilder builder;
  132. int glyph_count = 5;
  133. const auto& run = builder.allocRun(font, glyph_count, 1.2f, 2.3f);
  134. std::fill(run.glyphs, run.glyphs + glyph_count, 0);
  135. auto blob = builder.make();
  136. PaintFlags flags;
  137. for (size_t i = 0; i < 100; ++i)
  138. buffer.push<DrawTextBlobOp>(blob, 0.f, 0.f, flags);
  139. RunTest("text", buffer);
  140. }
  141. } // namespace
  142. } // namespace cc