RectoriBench.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright 2013 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/SkMaskFilter.h"
  10. #include "include/core/SkPaint.h"
  11. #include "include/core/SkPath.h"
  12. #include "include/effects/SkLayerDrawLooper.h"
  13. #include "include/utils/SkRandom.h"
  14. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  15. // This bench replicates a problematic use case of a draw looper used
  16. // to create an inner blurred rect
  17. class RectoriBench : public Benchmark {
  18. public:
  19. RectoriBench() {}
  20. protected:
  21. const char* onGetName() override {
  22. return "rectori";
  23. }
  24. void onDraw(int loops, SkCanvas* canvas) override {
  25. SkRandom Random;
  26. for (int i = 0; i < loops; i++) {
  27. SkScalar blurSigma = Random.nextRangeScalar(1.5f, 25.0f);
  28. SkScalar size = Random.nextRangeScalar(20*blurSigma, 50*blurSigma);
  29. SkScalar x = Random.nextRangeScalar(0.0f, W - size);
  30. SkScalar y = Random.nextRangeScalar(0.0f, H - size);
  31. SkRect inner = { x, y, x + size, y + size };
  32. SkRect outer(inner);
  33. // outer is always outset either 2x or 4x the blur radius (we go with 2x)
  34. outer.outset(2*blurSigma, 2*blurSigma);
  35. SkPath p;
  36. p.addRect(outer);
  37. p.addRect(inner);
  38. p.setFillType(SkPath::kEvenOdd_FillType);
  39. // This will be used to translate the normal draw outside the
  40. // clip rect and translate the blurred version back inside
  41. SkScalar translate = 2.0f * size;
  42. SkPaint paint;
  43. paint.setLooper(this->createLooper(-translate, blurSigma));
  44. paint.setColor(0xff000000 | Random.nextU());
  45. paint.setAntiAlias(true);
  46. canvas->save();
  47. // clip always equals inner rect so we get the inside blur
  48. canvas->clipRect(inner);
  49. canvas->translate(translate, 0);
  50. canvas->drawPath(p, paint);
  51. canvas->restore();
  52. }
  53. }
  54. private:
  55. enum {
  56. W = 640,
  57. H = 480,
  58. };
  59. sk_sp<SkDrawLooper> createLooper(SkScalar xOff, SkScalar sigma) {
  60. SkLayerDrawLooper::Builder looperBuilder;
  61. //-----------------------------------------------
  62. SkLayerDrawLooper::LayerInfo info;
  63. // TODO: add a color filter to better match what is seen in the wild
  64. info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/
  65. SkLayerDrawLooper::kMaskFilter_Bit;
  66. info.fColorMode = SkBlendMode::kDst;
  67. info.fOffset.set(xOff, 0);
  68. info.fPostTranslate = false;
  69. SkPaint* paint = looperBuilder.addLayer(info);
  70. paint->setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma));
  71. //-----------------------------------------------
  72. info.fPaintBits = 0;
  73. info.fOffset.set(0, 0);
  74. paint = looperBuilder.addLayer(info);
  75. return looperBuilder.detach();
  76. }
  77. typedef Benchmark INHERITED;
  78. };
  79. DEF_BENCH(return new RectoriBench();)
  80. #endif