1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Benchmark.h"
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkBitmap.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkColorPriv.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGradientShader.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPaint.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkShader.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkString.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct GradData {
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int             fCount;
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkColor*  fColors;
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkScalar* fPos;
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char*     fName;
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const SkColor gColors[] = {
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK, // 10 lines, 50 colors
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const SkColor gShallowColors[] = { 0xFF555555, 0xFF444444 };
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const SkScalar gPos[] = {0.25f, 0.75f};
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// We have several special-cases depending on the number (and spacing) of colors, so
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// try to exercise those here.
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const GradData gGradData[] = {
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { 2, gColors, nullptr, "" },
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { 50, gColors, nullptr, "_hicolor" }, // many color gradient
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { 3, gColors, nullptr, "_3color" },
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { 2, gShallowColors, nullptr, "_shallow" },
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { 2, gColors, gPos, "_pos" },
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/// Ignores scale
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data,
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                  SkShader::TileMode tm, float scale) {
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data,
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                  SkShader::TileMode tm, float scale) {
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint center;
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               SkScalarAve(pts[0].fY, pts[1].fY));
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeRadial(center, center.fX * scale, data.fColors,
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        data.fPos, data.fCount, tm);
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/// Ignores scale
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data,
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                 SkShader::TileMode tm, float scale) {
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint center;
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               SkScalarAve(pts[0].fY, pts[1].fY));
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/// Ignores scale
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeConical(const SkPoint pts[2], const GradData& data,
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                   SkShader::TileMode tm, float scale) {
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint center0, center1;
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkScalarAve(pts[0].fY, pts[1].fY));
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 center0, (pts[1].fX - pts[0].fX) / 2,
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 data.fColors, data.fPos, data.fCount, tm);
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/// Ignores scale
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeConicalZeroRad(const SkPoint pts[2], const GradData& data,
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          SkShader::TileMode tm, float scale) {
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint center0, center1;
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkScalarAve(pts[0].fY, pts[1].fY));
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeTwoPointConical(center1, 0.0,
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 center0, (pts[1].fX - pts[0].fX) / 2,
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 data.fColors, data.fPos, data.fCount, tm);
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/// Ignores scale
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeConicalOutside(const SkPoint pts[2], const GradData& data,
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          SkShader::TileMode tm, float scale) {
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint center0, center1;
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeTwoPointConical(center0, radius0,
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 center1, radius1,
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 data.fColors, data.fPos,
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 data.fCount, tm);
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/// Ignores scale
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<SkShader> MakeConicalOutsideZeroRad(const SkPoint pts[2], const GradData& data,
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 SkShader::TileMode tm, float scale) {
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPoint center0, center1;
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkGradientShader::MakeTwoPointConical(center0, 0.0,
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 center1, radius1,
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 data.fColors, data.fPos,
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                 data.fCount, tm);
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottypedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data,
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                     SkShader::TileMode tm, float scale);
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const struct {
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GradMaker   fMaker;
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* fName;
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} gGrads[] = {
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { MakeLinear,                 "linear"  },
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { MakeRadial,                 "radial1" },
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { MakeSweep,                  "sweep"   },
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { MakeConical,                "conical" },
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { MakeConicalZeroRad,         "conicalZero" },
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { MakeConicalOutside,         "conicalOut" },
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    { MakeConicalOutsideZeroRad,  "conicalOutZero" },
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum GradType { // these must match the order in gGrads
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kLinear_GradType,
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kRadial_GradType,
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kSweep_GradType,
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kConical_GradType,
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kConicalZero_GradType,
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kConicalOut_GradType,
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kConicalOutZero_GradType
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotenum GeomType {
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kRect_GeomType,
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    kOval_GeomType
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const char* tilemodename(SkShader::TileMode tm) {
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    switch (tm) {
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case SkShader::kClamp_TileMode:
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return "clamp";
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case SkShader::kRepeat_TileMode:
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return "repeat";
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case SkShader::kMirror_TileMode:
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return "mirror";
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        default:
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDEBUGFAIL("unknown tilemode");
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return "error";
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const char* geomtypename(GeomType gt) {
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    switch (gt) {
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case kRect_GeomType:
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return "rectangle";
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case kOval_GeomType:
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return "oval";
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        default:
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkDEBUGFAIL("unknown geometry type");
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return "error";
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GradientBench : public Benchmark {
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GradientBench(GradType gradType,
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  GradData data = gGradData[0],
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  SkShader::TileMode tm = SkShader::kClamp_TileMode,
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  GeomType geomType = kRect_GeomType,
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  float scale = 1.0f)
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : fGeomType(geomType) {
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fName.printf("gradient_%s_%s", gGrads[gradType].fName,
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                     tilemodename(tm));
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (geomType != kRect_GeomType) {
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fName.appendf("_%s", geomtypename(geomType));
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (scale != 1.f) {
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fName.appendf("_scale_%g", scale);
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fName.append(data.fName);
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setupPaint(&fPaint);
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPaint.setShader(MakeShader(gradType, data, tm, scale));
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GradientBench(GradType gradType, GradData data, bool dither)
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : fGeomType(kRect_GeomType) {
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char *tmname = tilemodename(SkShader::kClamp_TileMode);
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fName.printf("gradient_%s_%s", gGrads[gradType].fName, tmname);
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fName.append(data.fName);
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (dither) {
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fName.appendf("_dither");
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setupPaint(&fPaint);
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPaint.setShader(MakeShader(gradType, data, SkShader::kClamp_TileMode, 1.0f));
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fPaint.setDither(dither);
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* onGetName() override {
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fName.c_str();
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkIPoint onGetSize() override {
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SkIPoint::Make(kSize, kSize);
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onDraw(int loops, SkCanvas* canvas) override {
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkRect r = SkRect::MakeIWH(kSize, kSize);
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < loops; i++) {
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            switch (fGeomType) {
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               case kRect_GeomType:
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   canvas->drawRect(r, fPaint);
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   break;
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               case kOval_GeomType:
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   canvas->drawOval(r, fPaint);
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   break;
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef Benchmark INHERITED;
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkShader> MakeShader(GradType gradType, GradData data,
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                               SkShader::TileMode tm, float scale) {
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkPoint pts[2] = {
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { 0, 0 },
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkIntToScalar(kSize), SkIntToScalar(kSize) }
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return gGrads[gradType].fMaker(pts, data, tm, scale);
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kSize = 400;
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString       fName;
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPaint        fPaint;
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const GeomType fGeomType;
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0]); )
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1]); )
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2]); )
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[4]); )
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kRepeat_TileMode); )
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kRepeat_TileMode); )
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kRepeat_TileMode); )
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kMirror_TileMode); )
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kMirror_TileMode); )
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kMirror_TileMode); )
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0]); )
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[1]); )
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[2]); )
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Draw a radial gradient of radius 1/2 on a rectangle; half the lines should
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// be completely pinned, the other half should pe partially pinned
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kClamp_TileMode, kRect_GeomType, 0.5f); )
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Draw a radial gradient on a circle of equal size; all the lines should
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// hit the unpinned fast path (so long as GradientBench.W == H)
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kClamp_TileMode, kOval_GeomType); )
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kMirror_TileMode); )
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kRepeat_TileMode); )
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kSweep_GradType); )
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[1]); )
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[2]); )
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConical_GradType); )
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[1]); )
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[2]); )
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalZero_GradType); )
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalZero_GradType, gGradData[1]); )
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalZero_GradType, gGradData[2]); )
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalOut_GradType); )
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalOut_GradType, gGradData[1]); )
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalOut_GradType, gGradData[2]); )
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalOutZero_GradType); )
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalOutZero_GradType, gGradData[1]); )
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConicalOutZero_GradType, gGradData[2]); )
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Dithering
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], true); )
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], false); )
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], true); )
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], false); )
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], true); )
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], false); )
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], true); )
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], false); )
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Gradient2Bench : public Benchmark {
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString fName;
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool     fHasAlpha;
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Gradient2Bench(bool hasAlpha)  {
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fName.printf("gradient_create_%s", hasAlpha ? "alpha" : "opaque");
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fHasAlpha = hasAlpha;
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected:
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual const char* onGetName() {
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fName.c_str();
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    virtual void onDraw(int loops, SkCanvas* canvas) {
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkPaint paint;
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setupPaint(&paint);
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkRect r = { 0, 0, SkIntToScalar(4), SkIntToScalar(4) };
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const SkPoint pts[] = {
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { 0, 0 },
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            { SkIntToScalar(100), SkIntToScalar(100) },
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < loops; i++) {
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const int gray = i % 256;
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            const int alpha = fHasAlpha ? gray : 0xFF;
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkColor colors[] = {
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SK_ColorBLACK,
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkColorSetARGB(alpha, gray, gray, gray),
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SK_ColorWHITE };
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr,
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                         SK_ARRAY_COUNT(colors),
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                         SkShader::kClamp_TileMode));
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            canvas->drawRect(r, paint);
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef Benchmark INHERITED;
364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new Gradient2Bench(false); )
367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_BENCH( return new Gradient2Bench(true); )
368