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