1 2/* 3 * Copyright 2013 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9#include "Benchmark.h" 10#include "SkCanvas.h" 11#include "SkPaint.h" 12#include "SkRandom.h" 13#include "SkString.h" 14#include "SkXfermode.h" 15 16// Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode. 17class XfermodeBench : public Benchmark { 18public: 19 XfermodeBench(SkXfermode::Mode mode, bool aa) { 20 fXfermode.reset(SkXfermode::Create(mode)); 21 fAA = aa; 22 SkASSERT(fXfermode.get() || SkXfermode::kSrcOver_Mode == mode); 23 fName.printf("Xfermode_%s%s", SkXfermode::ModeName(mode), aa ? "_aa" : ""); 24 } 25 26 XfermodeBench(SkXfermode* xferMode, const char* name, bool aa) { 27 SkASSERT(xferMode); 28 fXfermode.reset(xferMode); 29 fAA = aa; 30 fName.printf("Xfermode_%s%s", name, aa ? "_aa" : ""); 31 } 32 33protected: 34 const char* onGetName() override { return fName.c_str(); } 35 36 void onDraw(int loops, SkCanvas* canvas) override { 37 const char* text = "Hamburgefons"; 38 size_t len = strlen(text); 39 SkISize size = canvas->getDeviceSize(); 40 SkRandom random; 41 for (int i = 0; i < loops; ++i) { 42 SkPaint paint; 43 paint.setXfermode(fXfermode.get()); 44 paint.setColor(random.nextU()); 45 if (fAA) { 46 // Draw text to exercise AA code paths. 47 paint.setAntiAlias(true); 48 paint.setTextSize(random.nextRangeScalar(12, 96)); 49 SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth), 50 y = random.nextRangeScalar(0, (SkScalar)size.fHeight); 51 for (int j = 0; j < 1000; ++j) { 52 canvas->drawText(text, len, x, y, paint); 53 } 54 } else { 55 // Draw rects to exercise non-AA code paths. 56 SkScalar w = random.nextRangeScalar(50, 100); 57 SkScalar h = random.nextRangeScalar(50, 100); 58 SkRect rect = SkRect::MakeXYWH( 59 random.nextUScalar1() * (size.fWidth - w), 60 random.nextUScalar1() * (size.fHeight - h), 61 w, 62 h 63 ); 64 for (int j = 0; j < 1000; ++j) { 65 canvas->drawRect(rect, paint); 66 } 67 } 68 } 69 } 70 71private: 72 SkAutoTUnref<SkXfermode> fXfermode; 73 SkString fName; 74 bool fAA; 75 76 typedef Benchmark INHERITED; 77}; 78 79class XferCreateBench : public Benchmark { 80public: 81 bool isSuitableFor(Backend backend) override { 82 return backend == kNonRendering_Backend; 83 } 84 85protected: 86 const char* onGetName() override { return "xfermode_create"; } 87 88 void onDraw(int loops, SkCanvas* canvas) override { 89 for (int outer = 0; outer < loops * 10; ++outer) { 90 for (int i = 0; i <= SkXfermode::kLastMode; ++i) { 91 SkXfermode* xfer = SkXfermode::Create(SkXfermode::Mode(i)); 92 SkSafeUnref(xfer); 93 } 94 } 95 } 96 97private: 98 typedef Benchmark INHERITED; 99}; 100 101////////////////////////////////////////////////////////////////////////////// 102 103#define BENCH(...) \ 104 DEF_BENCH( return new XfermodeBench(__VA_ARGS__, true); ) \ 105 DEF_BENCH( return new XfermodeBench(__VA_ARGS__, false); ) 106 107BENCH(SkXfermode::kClear_Mode) 108BENCH(SkXfermode::kSrc_Mode) 109BENCH(SkXfermode::kDst_Mode) 110BENCH(SkXfermode::kSrcOver_Mode) 111BENCH(SkXfermode::kDstOver_Mode) 112BENCH(SkXfermode::kSrcIn_Mode) 113BENCH(SkXfermode::kDstIn_Mode) 114BENCH(SkXfermode::kSrcOut_Mode) 115BENCH(SkXfermode::kDstOut_Mode) 116BENCH(SkXfermode::kSrcATop_Mode) 117BENCH(SkXfermode::kDstATop_Mode) 118BENCH(SkXfermode::kXor_Mode) 119 120BENCH(SkXfermode::kPlus_Mode) 121BENCH(SkXfermode::kModulate_Mode) 122BENCH(SkXfermode::kScreen_Mode) 123 124BENCH(SkXfermode::kOverlay_Mode) 125BENCH(SkXfermode::kDarken_Mode) 126BENCH(SkXfermode::kLighten_Mode) 127BENCH(SkXfermode::kColorDodge_Mode) 128BENCH(SkXfermode::kColorBurn_Mode) 129BENCH(SkXfermode::kHardLight_Mode) 130BENCH(SkXfermode::kSoftLight_Mode) 131BENCH(SkXfermode::kDifference_Mode) 132BENCH(SkXfermode::kExclusion_Mode) 133BENCH(SkXfermode::kMultiply_Mode) 134 135BENCH(SkXfermode::kHue_Mode) 136BENCH(SkXfermode::kSaturation_Mode) 137BENCH(SkXfermode::kColor_Mode) 138BENCH(SkXfermode::kLuminosity_Mode) 139 140DEF_BENCH(return new XferCreateBench;) 141