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