1/* 2 * Copyright 2014 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 "SkCanvas.h" 9#include "SkColorCubeFilter.h" 10#include "SkGradientShader.h" 11 12class ColorCubeBench : public Benchmark { 13 SkISize fSize; 14 int fCubeDimension; 15 SkData* fCubeData; 16 SkBitmap fBitmap; 17 18public: 19 ColorCubeBench() 20 : fCubeDimension(0) 21 , fCubeData(NULL) { 22 fSize = SkISize::Make(2880, 1800); // 2014 Macbook Pro resolution 23 } 24 25 ~ColorCubeBench() { 26 SkSafeUnref(fCubeData); 27 } 28 29protected: 30 const char* onGetName() override { 31 return "colorcube"; 32 } 33 34 void onPreDraw() override { 35 if (!SkToBool(fCubeData)) { 36 this->makeCubeData(); 37 this->make_bitmap(); 38 } 39 } 40 41 void onDraw(const int loops, SkCanvas* canvas) override { 42 this->test(loops, canvas); 43 } 44 45 SkIPoint onGetSize() override { 46 return SkIPoint::Make(fSize.width(), fSize.height()); 47 } 48 49private: 50 static SkShader* MakeLinear(const SkISize& size) { 51 const SkPoint pts[2] = { 52 { 0, 0 }, 53 { SkIntToScalar(size.width()), SkIntToScalar(size.height()) } 54 }; 55 static const SkColor colors[] = { SK_ColorYELLOW, SK_ColorBLUE }; 56 return SkGradientShader::CreateLinear( 57 pts, colors, NULL, 2, SkShader::kRepeat_TileMode, 0, &SkMatrix::I()); 58 } 59 60 void make_bitmap() { 61 fBitmap.allocN32Pixels(fSize.width(), fSize.height()); 62 SkCanvas canvas(fBitmap); 63 canvas.clear(0x00000000); 64 SkPaint paint; 65 paint.setAntiAlias(true); 66 SkShader* shader = MakeLinear(fSize); 67 paint.setShader(shader); 68 SkRect r = { 0, 0, SkIntToScalar(fSize.width()), SkIntToScalar(fSize.height()) }; 69 canvas.drawRect(r, paint); 70 shader->unref(); 71 } 72 73 void makeCubeData() { 74 fCubeDimension = 32; 75 fCubeData = SkData::NewUninitialized(sizeof(SkColor) * 76 fCubeDimension * fCubeDimension * fCubeDimension); 77 SkColor* pixels = (SkColor*)(fCubeData->writable_data()); 78 SkAutoMalloc lutMemory(fCubeDimension); 79 uint8_t* lut = (uint8_t*)lutMemory.get(); 80 const int maxIndex = fCubeDimension - 1; 81 for (int i = 0; i < fCubeDimension; ++i) { 82 // Make an invert lut, but the content of 83 // the lut shouldn't affect performance. 84 lut[i] = ((maxIndex - i) * 255) / maxIndex; 85 } 86 for (int r = 0; r < fCubeDimension; ++r) { 87 for (int g = 0; g < fCubeDimension; ++g) { 88 for (int b = 0; b < fCubeDimension; ++b) { 89 pixels[(fCubeDimension * ((fCubeDimension * b) + g)) + r] = 90 SkColorSetARGB(0xFF, lut[r], lut[g], lut[b]); 91 } 92 } 93 } 94 } 95 96 void test(const int loops, SkCanvas* canvas) { 97 SkPaint paint; 98 for (int i = 0; i < loops; i++) { 99 SkAutoTUnref<SkColorFilter> colorCube( 100 SkColorCubeFilter::Create(fCubeData, fCubeDimension)); 101 paint.setColorFilter(colorCube); 102 canvas->drawBitmap(fBitmap, 0, 0, &paint); 103 } 104 } 105 106 typedef Benchmark INHERITED; 107}; 108 109/////////////////////////////////////////////////////////////////////////////// 110 111DEF_BENCH( return new ColorCubeBench(); ) 112