1/* 2 * Copyright 2015 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 8#include "Benchmark.h" 9#include "SkColorData.h" 10#include "SkFixed.h" 11#include "SkMatrix.h" 12#include "SkPaint.h" 13#include "SkRandom.h" 14#include "SkString.h" 15 16#define TILE(x, width) (((x) & 0xFFFF) * width >> 16) 17 18class InterpBench : public Benchmark { 19 enum { 20 kBuffer = 128, 21 kLoop = 20000 22 }; 23 SkString fName; 24 int16_t fDst[kBuffer]; 25 float fFx, fDx; 26public: 27 InterpBench(const char name[]) { 28 fName.printf("interp_%s", name); 29 fFx = 3.3f; 30 fDx = 0.1257f; 31 } 32 33 bool isSuitableFor(Backend backend) override { 34 return backend == kNonRendering_Backend; 35 } 36 37 virtual void performTest(int16_t dst[], float x, float dx, int count) = 0; 38 39protected: 40 virtual int mulLoopCount() const { return 1; } 41 42 const char* onGetName() override { 43 return fName.c_str(); 44 } 45 46 void onDraw(int loops, SkCanvas*) override { 47 int n = loops * this->mulLoopCount(); 48 for (int i = 0; i < n; i++) { 49 this->performTest(fDst, fFx, fDx, kBuffer); 50 } 51 } 52 53private: 54 typedef Benchmark INHERITED; 55}; 56 57class Fixed16D16Interp : public InterpBench { 58public: 59 Fixed16D16Interp() : INHERITED("16.16") {} 60 61protected: 62 void performTest(int16_t dst[], float fx, float dx, int count) override { 63 SkFixed curr = SkFloatToFixed(fx); 64 SkFixed step = SkFloatToFixed(dx); 65 for (int i = 0; i < count; i += 4) { 66 dst[i + 0] = TILE(curr, count); curr += step; 67 dst[i + 1] = TILE(curr, count); curr += step; 68 dst[i + 2] = TILE(curr, count); curr += step; 69 dst[i + 3] = TILE(curr, count); curr += step; 70 } 71 } 72private: 73 typedef InterpBench INHERITED; 74}; 75 76class Fixed32D32Interp : public InterpBench { 77public: 78 Fixed32D32Interp() : INHERITED("32.32") {} 79 80protected: 81 void performTest(int16_t dst[], float fx, float dx, int count) override { 82 int64_t curr = (int64_t)(fx * 65536 * 655536); 83 int64_t step = (int64_t)(dx * 65536 * 655536); 84 SkFixed tmp; 85 for (int i = 0; i < count; i += 4) { 86 tmp = (SkFixed)(curr >> 16); 87 dst[i + 0] = TILE(tmp, count); 88 curr += step; 89 90 tmp = (SkFixed)(curr >> 16); 91 dst[i + 1] = TILE(tmp, count); 92 curr += step; 93 94 tmp = (SkFixed)(curr >> 16); 95 dst[i + 2] = TILE(tmp, count); 96 curr += step; 97 98 tmp = (SkFixed)(curr >> 16); 99 dst[i + 3] = TILE(tmp, count); 100 curr += step; 101 } 102 } 103private: 104 typedef InterpBench INHERITED; 105}; 106 107class Fixed16D48Interp : public InterpBench { 108public: 109 Fixed16D48Interp() : INHERITED("16.48") {} 110 111protected: 112 void performTest(int16_t dst[], float fx, float dx, int count) override { 113 int64_t curr = (int64_t)(fx * 65536 * 655536 * 65536); 114 int64_t step = (int64_t)(dx * 65536 * 655536 * 65536); 115 SkFixed tmp; 116 for (int i = 0; i < count; i += 4) { 117 tmp = (SkFixed) (curr >> 32); dst[i + 0] = TILE(tmp, count); curr += step; 118 tmp = (SkFixed) (curr >> 32); dst[i + 1] = TILE(tmp, count); curr += step; 119 tmp = (SkFixed) (curr >> 32); dst[i + 2] = TILE(tmp, count); curr += step; 120 tmp = (SkFixed) (curr >> 32); dst[i + 3] = TILE(tmp, count); curr += step; 121 } 122 } 123private: 124 typedef InterpBench INHERITED; 125}; 126 127class FloatInterp : public InterpBench { 128public: 129 FloatInterp() : INHERITED("float") {} 130 131protected: 132 void performTest(int16_t dst[], float fx, float dx, int count) override { 133 SkFixed tmp; 134 for (int i = 0; i < count; i += 4) { 135 tmp = SkFloatToFixed(fx); dst[i + 0] = TILE(tmp, count); fx += dx; 136 tmp = SkFloatToFixed(fx); dst[i + 1] = TILE(tmp, count); fx += dx; 137 tmp = SkFloatToFixed(fx); dst[i + 2] = TILE(tmp, count); fx += dx; 138 tmp = SkFloatToFixed(fx); dst[i + 3] = TILE(tmp, count); fx += dx; 139 } 140 } 141private: 142 typedef InterpBench INHERITED; 143}; 144 145class DoubleInterp : public InterpBench { 146public: 147 DoubleInterp() : INHERITED("double") {} 148 149protected: 150 void performTest(int16_t dst[], float fx, float dx, int count) override { 151 double ffx = fx; 152 double ddx = dx; 153 SkFixed tmp; 154 for (int i = 0; i < count; i += 4) { 155 tmp = SkDoubleToFixed(ffx); dst[i + 0] = TILE(tmp, count); ffx += ddx; 156 tmp = SkDoubleToFixed(ffx); dst[i + 1] = TILE(tmp, count); ffx += ddx; 157 tmp = SkDoubleToFixed(ffx); dst[i + 2] = TILE(tmp, count); ffx += ddx; 158 tmp = SkDoubleToFixed(ffx); dst[i + 3] = TILE(tmp, count); ffx += ddx; 159 } 160 } 161private: 162 typedef InterpBench INHERITED; 163}; 164 165/////////////////////////////////////////////////////////////////////////////// 166 167DEF_BENCH( return new Fixed16D16Interp(); ) 168DEF_BENCH( return new Fixed32D32Interp(); ) 169DEF_BENCH( return new Fixed16D48Interp(); ) 170DEF_BENCH( return new FloatInterp(); ) 171DEF_BENCH( return new DoubleInterp(); ) 172