| /* | |
| * Copyright 2015 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "Benchmark.h" | |
| #include "SkColorData.h" | |
| #include "SkFixed.h" | |
| #include "SkMatrix.h" | |
| #include "SkPaint.h" | |
| #include "SkRandom.h" | |
| #include "SkString.h" | |
| #define TILE(x, width) (((x) & 0xFFFF) * width >> 16) | |
| class InterpBench : public Benchmark { | |
| enum { | |
| kBuffer = 128, | |
| kLoop = 20000 | |
| }; | |
| SkString fName; | |
| int16_t fDst[kBuffer]; | |
| float fFx, fDx; | |
| public: | |
| InterpBench(const char name[]) { | |
| fName.printf("interp_%s", name); | |
| fFx = 3.3f; | |
| fDx = 0.1257f; | |
| } | |
| bool isSuitableFor(Backend backend) override { | |
| return backend == kNonRendering_Backend; | |
| } | |
| virtual void performTest(int16_t dst[], float x, float dx, int count) = 0; | |
| protected: | |
| virtual int mulLoopCount() const { return 1; } | |
| const char* onGetName() override { | |
| return fName.c_str(); | |
| } | |
| void onDraw(int loops, SkCanvas*) override { | |
| int n = loops * this->mulLoopCount(); | |
| for (int i = 0; i < n; i++) { | |
| this->performTest(fDst, fFx, fDx, kBuffer); | |
| } | |
| } | |
| private: | |
| typedef Benchmark INHERITED; | |
| }; | |
| class Fixed16D16Interp : public InterpBench { | |
| public: | |
| Fixed16D16Interp() : INHERITED("16.16") {} | |
| protected: | |
| void performTest(int16_t dst[], float fx, float dx, int count) override { | |
| SkFixed curr = SkFloatToFixed(fx); | |
| SkFixed step = SkFloatToFixed(dx); | |
| for (int i = 0; i < count; i += 4) { | |
| dst[i + 0] = TILE(curr, count); curr += step; | |
| dst[i + 1] = TILE(curr, count); curr += step; | |
| dst[i + 2] = TILE(curr, count); curr += step; | |
| dst[i + 3] = TILE(curr, count); curr += step; | |
| } | |
| } | |
| private: | |
| typedef InterpBench INHERITED; | |
| }; | |
| class Fixed32D32Interp : public InterpBench { | |
| public: | |
| Fixed32D32Interp() : INHERITED("32.32") {} | |
| protected: | |
| void performTest(int16_t dst[], float fx, float dx, int count) override { | |
| int64_t curr = (int64_t)(fx * 65536 * 655536); | |
| int64_t step = (int64_t)(dx * 65536 * 655536); | |
| SkFixed tmp; | |
| for (int i = 0; i < count; i += 4) { | |
| tmp = (SkFixed)(curr >> 16); | |
| dst[i + 0] = TILE(tmp, count); | |
| curr += step; | |
| tmp = (SkFixed)(curr >> 16); | |
| dst[i + 1] = TILE(tmp, count); | |
| curr += step; | |
| tmp = (SkFixed)(curr >> 16); | |
| dst[i + 2] = TILE(tmp, count); | |
| curr += step; | |
| tmp = (SkFixed)(curr >> 16); | |
| dst[i + 3] = TILE(tmp, count); | |
| curr += step; | |
| } | |
| } | |
| private: | |
| typedef InterpBench INHERITED; | |
| }; | |
| class Fixed16D48Interp : public InterpBench { | |
| public: | |
| Fixed16D48Interp() : INHERITED("16.48") {} | |
| protected: | |
| void performTest(int16_t dst[], float fx, float dx, int count) override { | |
| int64_t curr = (int64_t)(fx * 65536 * 655536 * 65536); | |
| int64_t step = (int64_t)(dx * 65536 * 655536 * 65536); | |
| SkFixed tmp; | |
| for (int i = 0; i < count; i += 4) { | |
| tmp = (SkFixed) (curr >> 32); dst[i + 0] = TILE(tmp, count); curr += step; | |
| tmp = (SkFixed) (curr >> 32); dst[i + 1] = TILE(tmp, count); curr += step; | |
| tmp = (SkFixed) (curr >> 32); dst[i + 2] = TILE(tmp, count); curr += step; | |
| tmp = (SkFixed) (curr >> 32); dst[i + 3] = TILE(tmp, count); curr += step; | |
| } | |
| } | |
| private: | |
| typedef InterpBench INHERITED; | |
| }; | |
| class FloatInterp : public InterpBench { | |
| public: | |
| FloatInterp() : INHERITED("float") {} | |
| protected: | |
| void performTest(int16_t dst[], float fx, float dx, int count) override { | |
| SkFixed tmp; | |
| for (int i = 0; i < count; i += 4) { | |
| tmp = SkFloatToFixed(fx); dst[i + 0] = TILE(tmp, count); fx += dx; | |
| tmp = SkFloatToFixed(fx); dst[i + 1] = TILE(tmp, count); fx += dx; | |
| tmp = SkFloatToFixed(fx); dst[i + 2] = TILE(tmp, count); fx += dx; | |
| tmp = SkFloatToFixed(fx); dst[i + 3] = TILE(tmp, count); fx += dx; | |
| } | |
| } | |
| private: | |
| typedef InterpBench INHERITED; | |
| }; | |
| class DoubleInterp : public InterpBench { | |
| public: | |
| DoubleInterp() : INHERITED("double") {} | |
| protected: | |
| void performTest(int16_t dst[], float fx, float dx, int count) override { | |
| double ffx = fx; | |
| double ddx = dx; | |
| SkFixed tmp; | |
| for (int i = 0; i < count; i += 4) { | |
| tmp = SkDoubleToFixed(ffx); dst[i + 0] = TILE(tmp, count); ffx += ddx; | |
| tmp = SkDoubleToFixed(ffx); dst[i + 1] = TILE(tmp, count); ffx += ddx; | |
| tmp = SkDoubleToFixed(ffx); dst[i + 2] = TILE(tmp, count); ffx += ddx; | |
| tmp = SkDoubleToFixed(ffx); dst[i + 3] = TILE(tmp, count); ffx += ddx; | |
| } | |
| } | |
| private: | |
| typedef InterpBench INHERITED; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| DEF_BENCH( return new Fixed16D16Interp(); ) | |
| DEF_BENCH( return new Fixed32D32Interp(); ) | |
| DEF_BENCH( return new Fixed16D48Interp(); ) | |
| DEF_BENCH( return new FloatInterp(); ) | |
| DEF_BENCH( return new DoubleInterp(); ) |