1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
984e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com#include "SkBitmap.h"
1084e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com#include "SkCanvas.h"
1184e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com#include "SkColorPriv.h"
1284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com#include "SkGradientShader.h"
1384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com#include "SkPaint.h"
1484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com#include "SkShader.h"
1584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com#include "SkString.h"
1684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
1784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comstruct GradData {
1884e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    int             fCount;
1984e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    const SkColor*  fColors;
2084e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    const SkScalar* fPos;
215396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    const char*     fName;
2284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com};
2384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
2484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comstatic const SkColor gColors[] = {
25b686539ab5270c66ab4994b4d6a8740143dec73acommit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
265396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
275396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
285396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
295396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
305396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
315396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
325396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
335396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
345396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK, // 10 lines, 50 colors
3584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com};
3684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
37f461a8fdf642ba713dcdfb217534652df1eac278krajcevskistatic const SkColor gShallowColors[] = { 0xFF555555, 0xFF444444 };
38f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
393400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org// We have several special-cases depending on the number (and spacing) of colors, so
403400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org// try to exercise those here.
4184e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comstatic const GradData gGradData[] = {
425396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    { 2, gColors, NULL, "" },
435396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org    { 50, gColors, NULL, "_hicolor" }, // many color gradient
443400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org    { 3, gColors, NULL, "_3color" },
45f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    { 2, gShallowColors, NULL, "_shallow" },
4684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com};
4784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
485ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com/// Ignores scale
4984e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comstatic SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
5083f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                            SkShader::TileMode tm, float scale) {
5183f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCount, tm);
5284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com}
5384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
5484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comstatic SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
5583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                            SkShader::TileMode tm, float scale) {
5684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    SkPoint center;
5784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
5884e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com               SkScalarAve(pts[0].fY, pts[1].fY));
595ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com    return SkGradientShader::CreateRadial(center, center.fX * scale,
605ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                                          data.fColors,
6183f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                          data.fPos, data.fCount, tm);
6284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com}
6384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
645ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com/// Ignores scale
6584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comstatic SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
6683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                           SkShader::TileMode tm, float scale) {
6784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    SkPoint center;
6884e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
6984e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com               SkScalarAve(pts[0].fY, pts[1].fY));
7084e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
7183f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                         data.fPos, data.fCount);
7284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com}
7384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
745ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com/// Ignores scale
75258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.comstatic SkShader* MakeConical(const SkPoint pts[2], const GradData& data,
7683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                             SkShader::TileMode tm, float scale) {
77258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.com    SkPoint center0, center1;
78258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.com    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
79258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.com                SkScalarAve(pts[0].fY, pts[1].fY));
80258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.com    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
81258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.com                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
82258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.com    return SkGradientShader::CreateTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
83258e0bf00cbb6fcc9c1b0db1a6b7dbd90b1b83f6reed@google.com                                                   center0, (pts[1].fX - pts[0].fX) / 2,
8483f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                                   data.fColors, data.fPos, data.fCount, tm);
8584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com}
8684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
8795f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org/// Ignores scale
8895f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgstatic SkShader* MakeConicalZeroRad(const SkPoint pts[2], const GradData& data,
8983f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                    SkShader::TileMode tm, float scale) {
9095f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    SkPoint center0, center1;
9195f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
9295f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org                SkScalarAve(pts[0].fY, pts[1].fY));
9395f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
9495f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
9595f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    return SkGradientShader::CreateTwoPointConical(center1, 0.0,
9695f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org                                                   center0, (pts[1].fX - pts[0].fX) / 2,
9783f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                                   data.fColors, data.fPos, data.fCount, tm);
9895f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org}
9995f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org
10095f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org/// Ignores scale
10195f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgstatic SkShader* MakeConicalOutside(const SkPoint pts[2], const GradData& data,
10283f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                    SkShader::TileMode tm, float scale) {
10395f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    SkPoint center0, center1;
10480ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed    SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
10580ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed    SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
10695f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
10795f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
10895f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    return SkGradientShader::CreateTwoPointConical(center0, radius0,
10995f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org                                                   center1, radius1,
11095f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org                                                   data.fColors, data.fPos,
11183f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                                   data.fCount, tm);
11295f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org}
11395f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org
11495f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org/// Ignores scale
11595f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgstatic SkShader* MakeConicalOutsideZeroRad(const SkPoint pts[2], const GradData& data,
11683f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                           SkShader::TileMode tm, float scale) {
11795f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    SkPoint center0, center1;
11880ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed    SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
11980ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed    SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
12095f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
12195f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
12295f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    return SkGradientShader::CreateTwoPointConical(center0, 0.0,
12395f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org                                                   center1, radius1,
12495f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org                                                   data.fColors, data.fPos,
12583f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                                                   data.fCount, tm);
12695f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org}
12795f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org
12884e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comtypedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
12983f23d87f1d67e6e73873e1ef7cda621c43703a0commit-bot@chromium.org                               SkShader::TileMode tm, float scale);
13084e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
13184e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comstatic const struct {
13284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    GradMaker   fMaker;
13384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    const char* fName;
13484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com} gGrads[] = {
13595f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    { MakeLinear,                 "linear"  },
13695f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    { MakeRadial,                 "radial1" },
13795f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    { MakeSweep,                  "sweep"   },
13895f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    { MakeConical,                "conical" },
13995f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    { MakeConicalZeroRad,         "conicalZero" },
14095f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    { MakeConicalOutside,         "conicalOut" },
14195f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    { MakeConicalOutsideZeroRad,  "conicalOutZero" },
14284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com};
14384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
14484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comenum GradType { // these must match the order in gGrads
14584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    kLinear_GradType,
14684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    kRadial_GradType,
14784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    kSweep_GradType,
14895f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    kConical_GradType,
14995f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    kConicalZero_GradType,
15095f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    kConicalOut_GradType,
15195f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.org    kConicalOutZero_GradType
15284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com};
15384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
1545ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.comenum GeomType {
1555ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com    kRect_GeomType,
1565ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com    kOval_GeomType
1575ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com};
1585ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com
15972415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.comstatic const char* tilemodename(SkShader::TileMode tm) {
16072415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com    switch (tm) {
16172415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com        case SkShader::kClamp_TileMode:
16272415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com            return "clamp";
16372415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com        case SkShader::kRepeat_TileMode:
16472415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com            return "repeat";
16572415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com        case SkShader::kMirror_TileMode:
16672415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com            return "mirror";
16772415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com        default:
168330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com            SkDEBUGFAIL("unknown tilemode");
16972415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com            return "error";
17072415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com    }
17172415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com}
17272415161dde26f6aa2b206a8eaa0abaff2f782dereed@google.com
1735ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.comstatic const char* geomtypename(GeomType gt) {
1745ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com    switch (gt) {
1755ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com        case kRect_GeomType:
1765ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            return "rectangle";
1775ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com        case kOval_GeomType:
1785ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            return "oval";
1795ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com        default:
180330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com            SkDEBUGFAIL("unknown geometry type");
1815ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            return "error";
1825ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com    }
1835ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com}
1845ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com
18584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com///////////////////////////////////////////////////////////////////////////////
18684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
187f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass GradientBench : public Benchmark {
18884e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    SkString fName;
18984e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    SkShader* fShader;
190f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    bool fDither;
19184e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    enum {
19284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        W   = 400,
19384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        H   = 400,
19484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    };
19584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.compublic:
196f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    SkShader* makeShader(GradType gradType, GradData data, SkShader::TileMode tm, float scale) {
197f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        const SkPoint pts[2] = {
198f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            { 0, 0 },
199f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            { SkIntToScalar(W), SkIntToScalar(H) }
200f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        };
201f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
202f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        return gGrads[gradType].fMaker(pts, data, tm, scale);
203f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
204f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
205410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    GradientBench(GradType gradType,
2065396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org                  GradData data = gGradData[0],
2075ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                  SkShader::TileMode tm = SkShader::kClamp_TileMode,
2085ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                  GeomType geomType = kRect_GeomType,
2093400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org                  float scale = 1.0f) {
2105ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com        fName.printf("gradient_%s_%s", gGrads[gradType].fName,
2115ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                     tilemodename(tm));
2125ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com        if (geomType != kRect_GeomType) {
2135ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            fName.append("_");
2145ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            fName.append(geomtypename(geomType));
2155ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com        }
21684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
2173400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org        if (scale != 1.f) {
2183400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org            fName.appendf("_scale_%g", scale);
2193400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org        }
2203400f4b00aaf9159713d9a7bb0a4f828fd6899c3commit-bot@chromium.org
2215396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org        fName.append(data.fName);
2225396a048d2f9f32fd3977d44f580c86028f4b1b9commit-bot@chromium.org
223f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        fDither = false;
224f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        fShader = this->makeShader(gradType, data, tm, scale);
2255ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com        fGeomType = geomType;
22684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    }
22784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
228f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    GradientBench(GradType gradType, GradData data, bool dither) {
229f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        const char *tmname = tilemodename(SkShader::kClamp_TileMode);
230f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        fName.printf("gradient_%s_%s", gGrads[gradType].fName, tmname);
231f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        fName.append(data.fName);
232f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
233f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        fDither = dither;
234f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        if (dither) {
235f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            fName.appendf("_dither");
236f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        }
237f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
238f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        fShader = this->makeShader(gradType, data, SkShader::kClamp_TileMode, 1.0f);
239f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        fGeomType = kRect_GeomType;
240f461a8fdf642ba713dcdfb217534652df1eac278krajcevski    }
241f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
24284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    virtual ~GradientBench() {
24384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        fShader->unref();
24484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    }
24584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
24684e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comprotected:
24784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    virtual const char* onGetName() {
24884e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        return fName.c_str();
24984e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    }
25084e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
2513361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas* canvas) {
25284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        SkPaint paint;
25384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        this->setupPaint(&paint);
25484e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
25584e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        paint.setShader(fShader);
256f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        if (fDither) {
257f461a8fdf642ba713dcdfb217534652df1eac278krajcevski            paint.setDither(true);
258f461a8fdf642ba713dcdfb217534652df1eac278krajcevski        }
25984e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
26084e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
261a7f79b47fa8924691f69da5d71d3c402c7f9bf6fbsalomon        for (int i = 0; i < loops; i++) {
2625ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            switch (fGeomType) {
2635ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com               case kRect_GeomType:
2645ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                   canvas->drawRect(r, paint);
2655ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                   break;
2665ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com               case kOval_GeomType:
2675ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                   canvas->drawOval(r, paint);
2685ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                   break;
2695ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            }
27084e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com        }
27184e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com    }
27284e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
27384e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.comprivate:
274f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
2755ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com
2765ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com    GeomType fGeomType;
27784e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com};
27884e9c0801f9a2da1ca12a38250a95fd393caded1reed@google.com
279b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kLinear_GradType); )
280b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1]); )
281b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2]); )
282b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kMirror_TileMode); )
283b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org
284b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0]); )
285b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[1]); )
286b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[2]); )
287b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org// Draw a radial gradient of radius 1/2 on a rectangle; half the lines should
288b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org// be completely pinned, the other half should pe partially pinned
289b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kClamp_TileMode, kRect_GeomType, 0.5f); )
290b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org
291b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org// Draw a radial gradient on a circle of equal size; all the lines should
292b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org// hit the unpinned fast path (so long as GradientBench.W == H)
293b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kClamp_TileMode, kOval_GeomType); )
294b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org
295b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kMirror_TileMode); )
29634150b451da7d3c70a2d34e67b0285cb36932d45commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kRepeat_TileMode); )
297b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kSweep_GradType); )
298b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[1]); )
299b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[2]); )
300b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConical_GradType); )
301b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[1]); )
302b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[2]); )
30395f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalZero_GradType); )
30495f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalZero_GradType, gGradData[1]); )
30595f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalZero_GradType, gGradData[2]); )
30695f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalOut_GradType); )
30795f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalOut_GradType, gGradData[1]); )
30895f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalOut_GradType, gGradData[2]); )
30995f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalOutZero_GradType); )
31095f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalOutZero_GradType, gGradData[1]); )
31195f79261addecd8c3b4e64f2f1469f9e1aa0acb2commit-bot@chromium.orgDEF_BENCH( return new GradientBench(kConicalOutZero_GradType, gGradData[2]); )
312b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org
313f461a8fdf642ba713dcdfb217534652df1eac278krajcevski// Dithering
314f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], true); )
315f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], false); )
316f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], true); )
317f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], false); )
318f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], true); )
319f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], false); )
320f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], true); )
321f461a8fdf642ba713dcdfb217534652df1eac278krajcevskiDEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], false); )
322f461a8fdf642ba713dcdfb217534652df1eac278krajcevski
323b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
324b120bd986ec5e5eeaacdbb8aec04cbe352f98434commit-bot@chromium.org
325f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass Gradient2Bench : public Benchmark {
32673349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com    SkString fName;
32773349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com    bool     fHasAlpha;
32873349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com
3298ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.compublic:
330410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    Gradient2Bench(bool hasAlpha)  {
33173349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com        fName.printf("gradient_create_%s", hasAlpha ? "alpha" : "opaque");
33273349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com        fHasAlpha = hasAlpha;
33373349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com    }
334fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3358ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.comprotected:
3368ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com    virtual const char* onGetName() {
33773349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com        return fName.c_str();
3388ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com    }
339fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3403361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas* canvas) {
3418ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com        SkPaint paint;
3428ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com        this->setupPaint(&paint);
343fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3448ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com        const SkRect r = { 0, 0, SkIntToScalar(4), SkIntToScalar(4) };
3451ca4f26039eb1dc08b301b7624cd05ab9b682cb8reed@google.com        const SkPoint pts[] = {
3461ca4f26039eb1dc08b301b7624cd05ab9b682cb8reed@google.com            { 0, 0 },
3471ca4f26039eb1dc08b301b7624cd05ab9b682cb8reed@google.com            { SkIntToScalar(100), SkIntToScalar(100) },
3481ca4f26039eb1dc08b301b7624cd05ab9b682cb8reed@google.com        };
3498ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com
3503361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; i++) {
35173349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com            const int gray = i % 256;
35273349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com            const int alpha = fHasAlpha ? gray : 0xFF;
3535ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com            SkColor colors[] = {
3545ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                SK_ColorBLACK,
35573349aa33277889d79e3e8bd8cef89cdf0310288reed@google.com                SkColorSetARGB(alpha, gray, gray, gray),
3565ea050f6620fa9e675a1c801f738e946fa993e14tomhudson@google.com                SK_ColorWHITE };
3578ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com            SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL,
3588ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com                                                         SK_ARRAY_COUNT(colors),
3598ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com                                                         SkShader::kClamp_TileMode);
3608ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com            paint.setShader(s)->unref();
3618ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com            canvas->drawRect(r, paint);
3628ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com        }
3638ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com    }
364fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3658ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.comprivate:
366f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
3678ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com};
3688ac7a0fcef6c830935905fdaeda97cab87581ce8reed@google.com
369410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new Gradient2Bench(false); )
370410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return new Gradient2Bench(true); )
371