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