PathTextBench.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright 2017 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 "bench/Benchmark.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkPaint.h"
  10. #include "include/core/SkPath.h"
  11. #include "include/utils/SkRandom.h"
  12. #include "src/core/SkStrike.h"
  13. #include "src/core/SkStrikeCache.h"
  14. #include "src/core/SkStrikeSpec.h"
  15. #include "tools/ToolUtils.h"
  16. static constexpr int kScreenWidth = 1500;
  17. static constexpr int kScreenHeight = 1500;
  18. static constexpr int kNumDraws = 2000;
  19. // I and l are rects on OS X.
  20. static constexpr char kGlyphs[] = "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
  21. static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
  22. static_assert(52 == kNumGlyphs, "expected 52 glyphs");
  23. /*
  24. * This class benchmarks drawing many glyphs at random scales and rotations.
  25. */
  26. class PathTextBench : public Benchmark {
  27. public:
  28. PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}
  29. private:
  30. const char* onGetName() override {
  31. fName = "path_text";
  32. if (fClipped) {
  33. fName.append("_clipped");
  34. }
  35. if (fUncached) {
  36. fName.append("_uncached");
  37. }
  38. return fName.c_str();
  39. }
  40. SkIPoint onGetSize() override { return SkIPoint::Make(kScreenWidth, kScreenHeight); }
  41. void onDelayedSetup() override {
  42. SkFont defaultFont;
  43. SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
  44. auto cache = strikeSpec.findOrCreateExclusiveStrike();
  45. for (int i = 0; i < kNumGlyphs; ++i) {
  46. SkPackedGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
  47. sk_ignore_unused_variable(cache->getScalerContext()->getPath(id, &fGlyphs[i]));
  48. fGlyphs[i].setIsVolatile(fUncached);
  49. }
  50. SkRandom rand;
  51. for (int i = 0; i < kNumDraws; ++i) {
  52. const SkPath& glyph = fGlyphs[i % kNumGlyphs];
  53. const SkRect& bounds = glyph.getBounds();
  54. float glyphSize = SkTMax(bounds.width(), bounds.height());
  55. float t0 = pow(rand.nextF(), 100);
  56. float size = (1 - t0) * SkTMin(kScreenWidth, kScreenHeight) / 50 +
  57. t0 * SkTMin(kScreenWidth, kScreenHeight) / 3;
  58. float scale = size / glyphSize;
  59. float t1 = rand.nextF(), t2 = rand.nextF();
  60. fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
  61. t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
  62. (1 - t2) * sqrt(2) * scale/2 * glyphSize +
  63. t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
  64. fXforms[i].preRotate(rand.nextF() * 360);
  65. fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
  66. fXforms[i].preScale(scale, scale);
  67. fPaints[i].setAntiAlias(true);
  68. fPaints[i].setColor(rand.nextU() | 0x80808080);
  69. }
  70. if (fClipped) {
  71. fClipPath = ToolUtils::make_star(SkRect::MakeIWH(kScreenWidth, kScreenHeight), 11, 3);
  72. fClipPath.setIsVolatile(fUncached);
  73. }
  74. }
  75. void onDraw(int loops, SkCanvas* canvas) override {
  76. SkAutoCanvasRestore acr(canvas, true);
  77. if (fClipped) {
  78. canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
  79. }
  80. for (int i = 0; i < kNumDraws; ++i) {
  81. const SkPath& glyph = fGlyphs[i % kNumGlyphs];
  82. canvas->setMatrix(fXforms[i]);
  83. canvas->drawPath(glyph, fPaints[i]);
  84. }
  85. }
  86. const bool fClipped;
  87. const bool fUncached;
  88. SkString fName;
  89. SkPath fGlyphs[kNumGlyphs];
  90. SkPaint fPaints[kNumDraws];
  91. SkMatrix fXforms[kNumDraws];
  92. SkPath fClipPath;
  93. typedef Benchmark INHERITED;
  94. };
  95. DEF_BENCH(return new PathTextBench(false, false);)
  96. DEF_BENCH(return new PathTextBench(false, true);)
  97. DEF_BENCH(return new PathTextBench(true, true);)