1/*
2 * Copyright 2016 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
10#include "SkCanvas.h"
11#include "SkShader.h"
12#include "SkGradientShader.h"
13#include "SkString.h"
14#include "SkColor.h"
15#include "SkPaint.h"
16
17class HardStopGradientBench_ScaleNumHardStops : public Benchmark {
18public:
19    HardStopGradientBench_ScaleNumHardStops(int colorCount, int hardStopCount) {
20        SkASSERT(hardStopCount <= colorCount/2);
21
22        fName.printf("hardstop_scale_num_hard_stops_%03d_colors_%03d_hard_stops",
23                     colorCount, hardStopCount);
24
25        fColorCount    = colorCount;
26        fHardStopCount = hardStopCount;
27    }
28
29    const char* onGetName() override {
30        return fName.c_str();
31    }
32
33    SkIPoint onGetSize() override {
34        return SkIPoint::Make(kSize, kSize);
35    }
36
37    void onPreDraw(SkCanvas* canvas) override {
38        // Left to right
39        SkPoint points[2] = {
40            SkPoint::Make(0,        kSize/2),
41            SkPoint::Make(kSize-1,  kSize/2),
42        };
43
44        constexpr int kNumColorChoices = 4;
45        SkColor color_choices[kNumColorChoices] = {
46            SK_ColorRED,
47            SK_ColorGREEN,
48            SK_ColorBLUE,
49            SK_ColorYELLOW,
50        };
51
52        // Alternate between different choices
53        SkAutoTArray<SkColor> colors(fColorCount);
54        for (int i = 0; i < fColorCount; i++) {
55            colors[i] = color_choices[i % kNumColorChoices];
56        }
57
58        // Create requisite number of hard stops, and evenly
59        // space positions after that
60        SkAutoTArray<SkScalar> positions(fColorCount);
61        int k = 0;
62        for (int i = 0; i < fHardStopCount; i++) {
63            float val = k/2.0f;
64            positions[k++] = val / fColorCount;
65            positions[k++] = val / fColorCount;
66        }
67        for (int i = k; i < fColorCount; i++) {
68            positions[i] = i / (fColorCount - 1.0f);
69        }
70
71        fPaint.setShader(SkGradientShader::MakeLinear(points,
72                                                      colors.get(),
73                                                      positions.get(),
74                                                      fColorCount,
75                                                      SkShader::kClamp_TileMode,
76                                                      0,
77                                                      nullptr));
78    }
79
80    /*
81     * Draw simple linear gradient from left to right
82     */
83    void onDraw(int loops, SkCanvas* canvas) override {
84        for (int i = 0; i < loops; i++) {
85            canvas->drawPaint(fPaint);
86        }
87    }
88
89private:
90    static const int kSize = 500;
91
92    SkString fName;
93    int      fColorCount;
94    int      fHardStopCount;
95    SkPaint  fPaint;
96
97    typedef Benchmark INHERITED;
98};
99
100DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(10, 1);)
101DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(10, 2);)
102DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(10, 5);)
103
104DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(20,  1);)
105DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(20,  5);)
106DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(20, 10);)
107
108DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(50,  1);)
109DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(50, 10);)
110DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(50, 25);)
111
112DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(100,  1);)
113DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(100, 25);)
114DEF_BENCH(return new HardStopGradientBench_ScaleNumHardStops(100, 50);)
115