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