1 /* 2 * Copyright 2011 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 "Benchmark.h" 8 #include "SkBitmap.h" 9 #include "SkCanvas.h" 10 #include "SkColorPriv.h" 11 #include "SkPaint.h" 12 #include "SkShader.h" 13 #include "SkString.h" 14 #include "sk_tool_utils.h" 15 16 static void draw_into_bitmap(const SkBitmap& bm) { 17 const int w = bm.width(); 18 const int h = bm.height(); 19 20 SkCanvas canvas(bm); 21 SkPaint p; 22 p.setAntiAlias(true); 23 p.setColor(SK_ColorRED); 24 canvas.drawCircle(SkIntToScalar(w)/2, SkIntToScalar(h)/2, 25 SkIntToScalar(SkMin32(w, h))*3/8, p); 26 27 SkRect r; 28 r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h)); 29 p.setStyle(SkPaint::kStroke_Style); 30 p.setStrokeWidth(SkIntToScalar(4)); 31 p.setColor(SK_ColorBLUE); 32 canvas.drawRect(r, p); 33 } 34 35 static int conv_6_to_byte(int x) { 36 return x * 0xFF / 5; 37 } 38 39 static int conv_byte_to_6(int x) { 40 return x * 5 / 255; 41 } 42 43 static uint8_t compute_666_index(SkPMColor c) { 44 int r = SkGetPackedR32(c); 45 int g = SkGetPackedG32(c); 46 int b = SkGetPackedB32(c); 47 48 return conv_byte_to_6(r) * 36 + conv_byte_to_6(g) * 6 + conv_byte_to_6(b); 49 } 50 51 static void convert_to_index666(const SkBitmap& src, SkBitmap* dst) { 52 SkPMColor storage[216]; 53 SkPMColor* colors = storage; 54 // rrr ggg bbb 55 for (int r = 0; r < 6; r++) { 56 int rr = conv_6_to_byte(r); 57 for (int g = 0; g < 6; g++) { 58 int gg = conv_6_to_byte(g); 59 for (int b = 0; b < 6; b++) { 60 int bb = conv_6_to_byte(b); 61 *colors++ = SkPreMultiplyARGB(0xFF, rr, gg, bb); 62 } 63 } 64 } 65 SkColorTable* ctable = new SkColorTable(storage, 216); 66 dst->allocPixels(SkImageInfo::Make(src.width(), src.height(), 67 kIndex_8_SkColorType, kOpaque_SkAlphaType), 68 nullptr, ctable); 69 ctable->unref(); 70 71 SkAutoLockPixels alps(src); 72 SkAutoLockPixels alpd(*dst); 73 74 for (int y = 0; y < src.height(); y++) { 75 const SkPMColor* srcP = src.getAddr32(0, y); 76 uint8_t* dstP = dst->getAddr8(0, y); 77 for (int x = src.width() - 1; x >= 0; --x) { 78 *dstP++ = compute_666_index(*srcP++); 79 } 80 } 81 } 82 83 class RepeatTileBench : public Benchmark { 84 const SkColorType fColorType; 85 const SkAlphaType fAlphaType; 86 SkPaint fPaint; 87 SkString fName; 88 SkBitmap fBitmap; 89 public: 90 RepeatTileBench(SkColorType ct, SkAlphaType at = kPremul_SkAlphaType) 91 : fColorType(ct), fAlphaType(at) 92 { 93 const int w = 50; 94 const int h = 50; 95 96 if (kIndex_8_SkColorType == ct) { 97 fBitmap.setInfo(SkImageInfo::MakeN32(w, h, at)); 98 } else { 99 fBitmap.setInfo(SkImageInfo::Make(w, h, ct, at)); 100 } 101 fName.printf("repeatTile_%s_%c", 102 sk_tool_utils::colortype_name(ct), kOpaque_SkAlphaType == at ? 'X' : 'A'); 103 } 104 105 protected: 106 const char* onGetName() override { 107 return fName.c_str(); 108 } 109 110 void onDelayedSetup() override { 111 fBitmap.allocPixels(); 112 fBitmap.eraseColor(kOpaque_SkAlphaType == fAlphaType ? SK_ColorWHITE : 0); 113 114 draw_into_bitmap(fBitmap); 115 116 if (kIndex_8_SkColorType == fColorType) { 117 SkBitmap tmp; 118 convert_to_index666(fBitmap, &tmp); 119 fBitmap = tmp; 120 } 121 122 fPaint.setShader(SkShader::MakeBitmapShader(fBitmap, 123 SkShader::kRepeat_TileMode, 124 SkShader::kRepeat_TileMode)); 125 } 126 127 128 void onDraw(int loops, SkCanvas* canvas) override { 129 SkPaint paint(fPaint); 130 this->setupPaint(&paint); 131 132 for (int i = 0; i < loops; i++) { 133 canvas->drawPaint(paint); 134 } 135 } 136 137 private: 138 typedef Benchmark INHERITED; 139 }; 140 141 DEF_BENCH(return new RepeatTileBench(kN32_SkColorType, kOpaque_SkAlphaType)) 142 DEF_BENCH(return new RepeatTileBench(kN32_SkColorType, kPremul_SkAlphaType)) 143 DEF_BENCH(return new RepeatTileBench(kRGB_565_SkColorType, kOpaque_SkAlphaType)) 144 DEF_BENCH(return new RepeatTileBench(kIndex_8_SkColorType, kPremul_SkAlphaType)) 145