Home | History | Annotate | Download | only in bench
      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