| /* | 
 |  * Copyright 2013 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "bench/Benchmark.h" | 
 | #include "include/core/SkCanvas.h" | 
 | #include "include/core/SkFont.h" | 
 | #include "include/core/SkPaint.h" | 
 | #include "include/core/SkString.h" | 
 | #include "include/core/SkTextBlob.h" | 
 | #include "src/base/SkRandom.h" | 
 | #include "src/core/SkBlendModePriv.h" | 
 | #include "tools/DecodeUtils.h" | 
 | #include "tools/Resources.h" | 
 | #include "tools/fonts/FontToolUtils.h" | 
 |  | 
 | namespace { | 
 | enum Type { | 
 |     kText, | 
 |     kRect, | 
 |     kSprite, | 
 | }; | 
 | } | 
 |  | 
 | const char* gTypeNames[] = { | 
 |     "mask", "rect", "sprite", | 
 | }; | 
 |  | 
 | // Benchmark that draws non-AA rects or AA text with an SkBlendMode. | 
 | class XfermodeBench : public Benchmark { | 
 | public: | 
 |     XfermodeBench(SkBlendMode mode, Type t) : fBlendMode(mode) { | 
 |         fType = t; | 
 |         fName.printf("blendmicro_%s_%s", gTypeNames[t], SkBlendMode_Name(mode)); | 
 |     } | 
 |  | 
 | protected: | 
 |     const char* onGetName() override { return fName.c_str(); } | 
 |  | 
 |     void onDelayedSetup() override { | 
 |         if (fType == kSprite) { | 
 |             fImage = ToolUtils::GetResourceAsImage("images/color_wheel.png"); | 
 |         } | 
 |     } | 
 |  | 
 |     void onDraw(int loops, SkCanvas* canvas) override { | 
 |         const char* text = "Hamburgefons"; | 
 |         size_t len = strlen(text); | 
 |         SkISize size = canvas->getBaseLayerSize(); | 
 |         SkRandom random; | 
 |         while (loops > 0) { | 
 |             SkPaint paint; | 
 |             paint.setBlendMode(fBlendMode); | 
 |             paint.setColor(random.nextU()); | 
 |             switch (fType) { | 
 |                 case kText: { | 
 |                     // Draw text to exercise AA code paths. | 
 |                     SkFont font = ToolUtils::DefaultFont(); | 
 |                     font.setSize(random.nextRangeScalar(12, 96)); | 
 |                     SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth), | 
 |                              y = random.nextRangeScalar(0, (SkScalar)size.fHeight); | 
 |                     auto blob = SkTextBlob::MakeFromText(text, len, font, SkTextEncoding::kUTF8); | 
 |                     int iterations = std::min(1000, loops); | 
 |                     for (int j = 0; j < iterations; ++j) { | 
 |                         canvas->drawTextBlob(blob, x, y, paint); | 
 |                     } | 
 |                     loops -= iterations; | 
 |                 } break; | 
 |                 case kRect: { | 
 |                     // Draw rects to exercise non-AA code paths. | 
 |                     SkScalar w = random.nextRangeScalar(50, 100); | 
 |                     SkScalar h = random.nextRangeScalar(50, 100); | 
 |                     SkRect rect = SkRect::MakeXYWH( | 
 |                         random.nextUScalar1() * (size.fWidth - w), | 
 |                         random.nextUScalar1() * (size.fHeight - h), | 
 |                         w, | 
 |                         h | 
 |                     ); | 
 |                     int iterations = std::min(1000, loops); | 
 |                     for (int j = 0; j < iterations; ++j) { | 
 |                         canvas->drawRect(rect, paint); | 
 |                     } | 
 |                     loops -= iterations; | 
 |                 } break; | 
 |                 case kSprite: | 
 |                     paint.setAlphaf(1.0f); | 
 |                     for (int i = 0; i < 10; ++i) { | 
 |                         canvas->drawImage(fImage, 0, 0, SkSamplingOptions(), &paint); | 
 |                     } | 
 |                     loops -= 1; | 
 |                     break; | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 | private: | 
 |     SkBlendMode fBlendMode; | 
 |     SkString    fName; | 
 |     sk_sp<SkImage> fImage; | 
 |     Type        fType; | 
 |  | 
 |     using INHERITED = Benchmark; | 
 | }; | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | #define BENCH(mode)                                      \ | 
 |     DEF_BENCH( return new XfermodeBench(mode, kText); )  \ | 
 |     DEF_BENCH( return new XfermodeBench(mode, kRect); )  \ | 
 |     DEF_BENCH( return new XfermodeBench(mode, kSprite); ) | 
 |  | 
 | BENCH(SkBlendMode::kClear) | 
 | BENCH(SkBlendMode::kSrc) | 
 | BENCH(SkBlendMode::kDst) | 
 | BENCH(SkBlendMode::kSrcOver) | 
 | BENCH(SkBlendMode::kDstOver) | 
 | BENCH(SkBlendMode::kSrcIn) | 
 | BENCH(SkBlendMode::kDstIn) | 
 | BENCH(SkBlendMode::kSrcOut) | 
 | BENCH(SkBlendMode::kDstOut) | 
 | BENCH(SkBlendMode::kSrcATop) | 
 | BENCH(SkBlendMode::kDstATop) | 
 | BENCH(SkBlendMode::kXor) | 
 |  | 
 | BENCH(SkBlendMode::kPlus) | 
 | BENCH(SkBlendMode::kModulate) | 
 | BENCH(SkBlendMode::kScreen) | 
 |  | 
 | BENCH(SkBlendMode::kOverlay) | 
 | BENCH(SkBlendMode::kDarken) | 
 | BENCH(SkBlendMode::kLighten) | 
 | BENCH(SkBlendMode::kColorDodge) | 
 | BENCH(SkBlendMode::kColorBurn) | 
 | BENCH(SkBlendMode::kHardLight) | 
 | BENCH(SkBlendMode::kSoftLight) | 
 | BENCH(SkBlendMode::kDifference) | 
 | BENCH(SkBlendMode::kExclusion) | 
 | BENCH(SkBlendMode::kMultiply) | 
 |  | 
 | BENCH(SkBlendMode::kHue) | 
 | BENCH(SkBlendMode::kSaturation) | 
 | BENCH(SkBlendMode::kColor) | 
 | BENCH(SkBlendMode::kLuminosity) |