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