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 8 #include "bench/Benchmark.h" 9 #include "include/core/SkCanvas.h" 10 #include "include/core/SkFont.h" 11 #include "include/core/SkPaint.h" 12 #include "include/core/SkString.h" 13 #include "include/core/SkTextBlob.h" 14 #include "src/base/SkRandom.h" 15 #include "src/core/SkBlendModePriv.h" 16 #include "tools/DecodeUtils.h" 17 #include "tools/Resources.h" 18 #include "tools/fonts/FontToolUtils.h" 19 20 namespace { 21 enum Type { 22 kText, 23 kRect, 24 kSprite, 25 }; 26 } 27 28 const char* gTypeNames[] = { 29 "mask", "rect", "sprite", 30 }; 31 32 // Benchmark that draws non-AA rects or AA text with an SkBlendMode. 33 class XfermodeBench : public Benchmark { 34 public: XfermodeBench(SkBlendMode mode,Type t)35 XfermodeBench(SkBlendMode mode, Type t) : fBlendMode(mode) { 36 fType = t; 37 fName.printf("blendmicro_%s_%s", gTypeNames[t], SkBlendMode_Name(mode)); 38 } 39 40 protected: onGetName()41 const char* onGetName() override { return fName.c_str(); } 42 onDelayedSetup()43 void onDelayedSetup() override { 44 if (fType == kSprite) { 45 fImage = ToolUtils::GetResourceAsImage("images/color_wheel.png"); 46 } 47 } 48 onDraw(int loops,SkCanvas * canvas)49 void onDraw(int loops, SkCanvas* canvas) override { 50 const char* text = "Hamburgefons"; 51 size_t len = strlen(text); 52 SkISize size = canvas->getBaseLayerSize(); 53 SkRandom random; 54 while (loops > 0) { 55 SkPaint paint; 56 paint.setBlendMode(fBlendMode); 57 paint.setColor(random.nextU()); 58 switch (fType) { 59 case kText: { 60 // Draw text to exercise AA code paths. 61 SkFont font = ToolUtils::DefaultFont(); 62 font.setSize(random.nextRangeScalar(12, 96)); 63 SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth), 64 y = random.nextRangeScalar(0, (SkScalar)size.fHeight); 65 auto blob = SkTextBlob::MakeFromText(text, len, font, SkTextEncoding::kUTF8); 66 int iterations = std::min(1000, loops); 67 for (int j = 0; j < iterations; ++j) { 68 canvas->drawTextBlob(blob, x, y, paint); 69 } 70 loops -= iterations; 71 } break; 72 case kRect: { 73 // Draw rects to exercise non-AA code paths. 74 SkScalar w = random.nextRangeScalar(50, 100); 75 SkScalar h = random.nextRangeScalar(50, 100); 76 SkRect rect = SkRect::MakeXYWH( 77 random.nextUScalar1() * (size.fWidth - w), 78 random.nextUScalar1() * (size.fHeight - h), 79 w, 80 h 81 ); 82 int iterations = std::min(1000, loops); 83 for (int j = 0; j < iterations; ++j) { 84 canvas->drawRect(rect, paint); 85 } 86 loops -= iterations; 87 } break; 88 case kSprite: 89 paint.setAlphaf(1.0f); 90 for (int i = 0; i < 10; ++i) { 91 canvas->drawImage(fImage, 0, 0, SkSamplingOptions(), &paint); 92 } 93 loops -= 1; 94 break; 95 } 96 } 97 } 98 99 private: 100 SkBlendMode fBlendMode; 101 SkString fName; 102 sk_sp<SkImage> fImage; 103 Type fType; 104 105 using INHERITED = Benchmark; 106 }; 107 108 ////////////////////////////////////////////////////////////////////////////// 109 110 #define BENCH(mode) \ 111 DEF_BENCH( return new XfermodeBench(mode, kText); ) \ 112 DEF_BENCH( return new XfermodeBench(mode, kRect); ) \ 113 DEF_BENCH( return new XfermodeBench(mode, kSprite); ) 114 115 BENCH(SkBlendMode::kClear) 116 BENCH(SkBlendMode::kSrc) 117 BENCH(SkBlendMode::kDst) 118 BENCH(SkBlendMode::kSrcOver) 119 BENCH(SkBlendMode::kDstOver) 120 BENCH(SkBlendMode::kSrcIn) 121 BENCH(SkBlendMode::kDstIn) 122 BENCH(SkBlendMode::kSrcOut) 123 BENCH(SkBlendMode::kDstOut) 124 BENCH(SkBlendMode::kSrcATop) 125 BENCH(SkBlendMode::kDstATop) 126 BENCH(SkBlendMode::kXor) 127 128 BENCH(SkBlendMode::kPlus) 129 BENCH(SkBlendMode::kModulate) 130 BENCH(SkBlendMode::kScreen) 131 132 BENCH(SkBlendMode::kOverlay) 133 BENCH(SkBlendMode::kDarken) 134 BENCH(SkBlendMode::kLighten) 135 BENCH(SkBlendMode::kColorDodge) 136 BENCH(SkBlendMode::kColorBurn) 137 BENCH(SkBlendMode::kHardLight) 138 BENCH(SkBlendMode::kSoftLight) 139 BENCH(SkBlendMode::kDifference) 140 BENCH(SkBlendMode::kExclusion) 141 BENCH(SkBlendMode::kMultiply) 142 143 BENCH(SkBlendMode::kHue) 144 BENCH(SkBlendMode::kSaturation) 145 BENCH(SkBlendMode::kColor) 146 BENCH(SkBlendMode::kLuminosity) 147