16670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com/*
26670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com * Copyright 2012 Google Inc.
36670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com *
46670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
56670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com * found in the LICENSE file.
66670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com */
76670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
96670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com#include "SkCanvas.h"
106670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com#include "SkPaint.h"
116670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com#include "SkRandom.h"
12631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com#include "SkShader.h"
136670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com#include "SkString.h"
14887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed#include "SkVertices.h"
156670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
166670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// This bench simulates the calls Skia sees from various HTML5 canvas
176670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// game bench marks
18f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass GameBench : public Benchmark {
196670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.compublic:
206670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    enum Type {
210f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com        kScale_Type,
220f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com        kTranslate_Type,
236670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        kRotate_Type
246670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    };
256670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
26f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    enum Clear {
27f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        kFull_Clear,
28f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        kPartial_Clear
29f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    };
30f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
31410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    GameBench(Type type, Clear clear,
32631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com              bool aligned = false, bool useAtlas = false,
33631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com              bool useDrawVertices = false)
34410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com        : fType(type)
35f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        , fClear(clear)
36347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com        , fAligned(aligned)
37f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        , fUseAtlas(useAtlas)
38631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        , fUseDrawVertices(useDrawVertices)
396670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        , fName("game")
406670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        , fNumSaved(0)
416670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        , fInitialized(false) {
426670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
436670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        switch (fType) {
446670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        case kScale_Type:
456670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_scale");
466670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            break;
476670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        case kTranslate_Type:
486670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_trans");
496670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            break;
506670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        case kRotate_Type:
516670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_rot");
526670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            break;
536670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        };
546670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
55347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com        if (aligned) {
56347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com            fName.append("_aligned");
57347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com        }
58347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com
59f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        if (kPartial_Clear == clear) {
606670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_partial");
616670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        } else {
626670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_full");
636670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
646670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
65f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        if (useAtlas) {
66f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            fName.append("_atlas");
67f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        }
68f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
69631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        if (useDrawVertices) {
70631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            fName.append("_drawVerts");
71631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        }
72631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com
736670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        // It's HTML 5 canvas, so always AA
746670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        fName.append("_aa");
756670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
766670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
776670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.comprotected:
7836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* onGetName() override {
79f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        return fName.c_str();
806670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
816670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
828a6697af95b340aad6dee7e6228048fa305c1e59joshualitt    void onDelayedSetup() override {
836670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        if (!fInitialized) {
846670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            this->makeCheckerboard();
85f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            this->makeAtlas();
866670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fInitialized = true;
876670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
886670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
896670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
90a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein    void onDraw(int loops, SkCanvas* canvas) override {
91e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom scaleRand;
92e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom transRand;
93e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rotRand;
946670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
95f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        int width, height;
96f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        if (fUseAtlas) {
97f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            width = kAtlasCellWidth;
98f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            height = kAtlasCellHeight;
99f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        } else {
100f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            width = kCheckerboardWidth;
101f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            height = kCheckerboardHeight;
102f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        }
103f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
1046670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkPaint clearPaint;
1056670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        clearPaint.setColor(0xFF000000);
1066670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        clearPaint.setAntiAlias(true);
1076670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1083661bc997620899695041010a750d11dbe8a972dMike Reed        SkISize size = canvas->getBaseLayerSize();
1096670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1106670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkScalar maxTransX, maxTransY;
1116670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1126670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        if (kScale_Type == fType) {
113f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransX = size.fWidth  - (1.5f * width);
114f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransY = size.fHeight - (1.5f * height);
1156670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        } else if (kTranslate_Type == fType) {
116f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransX = SkIntToScalar(size.fWidth  - width);
117f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransY = SkIntToScalar(size.fHeight - height);
1186670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        } else {
1196670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            SkASSERT(kRotate_Type == fType);
1206670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            // Yes, some rotations will be off the top and left sides
121f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransX = size.fWidth  - SK_ScalarSqrt2 * height;
122f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransY = size.fHeight - SK_ScalarSqrt2 * height;
1236670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
1246670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1256670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkMatrix mat;
126f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) };
127f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f };
128631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        SkPoint verts[4] = { // for drawVertices path
129631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { 0, 0 },
130631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { 0, SkIntToScalar(height) },
131631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { SkIntToScalar(width), SkIntToScalar(height) },
132631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { SkIntToScalar(width), 0 }
133631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        };
134631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 };
1356670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1366670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkPaint p;
1376670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        p.setColor(0xFF000000);
13893a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        p.setFilterQuality(kLow_SkFilterQuality);
1396670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
140631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        SkPaint p2;         // for drawVertices path
141631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        p2.setColor(0xFF000000);
14293a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed        p2.setFilterQuality(kLow_SkFilterQuality);
143c6f28f7f0e788dc43cad4494e277e9ad7b958b6ereed        p2.setShader(SkShader::MakeBitmapShader(fAtlas,
144c6f28f7f0e788dc43cad4494e277e9ad7b958b6ereed                                                SkShader::kClamp_TileMode,
145c6f28f7f0e788dc43cad4494e277e9ad7b958b6ereed                                                SkShader::kClamp_TileMode));
146631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com
1473361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; ++i, ++fNumSaved) {
1486670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            if (0 == i % kNumBeforeClear) {
149f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                if (kPartial_Clear == fClear) {
1506670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    for (int j = 0; j < fNumSaved; ++j) {
1516670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        canvas->setMatrix(SkMatrix::I());
1526670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        mat.setTranslate(fSaved[j][0], fSaved[j][1]);
1536670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1546670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        if (kScale_Type == fType) {
1556670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                            mat.preScale(fSaved[j][2], fSaved[j][2]);
1566670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        } else if (kRotate_Type == fType) {
1576670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                            mat.preRotate(fSaved[j][2]);
1586670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        }
1596670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1606670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        canvas->concat(mat);
1616670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        canvas->drawRect(clearRect, clearPaint);
1626670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    }
1636670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                } else {
1646670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    canvas->clear(0xFF000000);
1656670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                }
1666670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1676670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                fNumSaved = 0;
1686670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            }
1696670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1706670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            SkASSERT(fNumSaved < kNumBeforeClear);
1716670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1726670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            canvas->setMatrix(SkMatrix::I());
1736670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1746670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fSaved[fNumSaved][0] = transRand.nextRangeScalar(0.0f, maxTransX);
1756670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fSaved[fNumSaved][1] = transRand.nextRangeScalar(0.0f, maxTransY);
176347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com            if (fAligned) {
177347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com                // make the translations integer aligned
178347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com                fSaved[fNumSaved][0] = SkScalarFloorToScalar(fSaved[fNumSaved][0]);
179347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com                fSaved[fNumSaved][1] = SkScalarFloorToScalar(fSaved[fNumSaved][1]);
180347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com            }
1816670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1826670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            mat.setTranslate(fSaved[fNumSaved][0], fSaved[fNumSaved][1]);
1836670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1846670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            if (kScale_Type == fType) {
1856670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                fSaved[fNumSaved][2] = scaleRand.nextRangeScalar(0.5f, 1.5f);
1866670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                mat.preScale(fSaved[fNumSaved][2], fSaved[fNumSaved][2]);
1876670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            } else if (kRotate_Type == fType) {
1886670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                fSaved[fNumSaved][2] = rotRand.nextRangeScalar(0.0f, 360.0f);
1896670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                mat.preRotate(fSaved[fNumSaved][2]);
1906670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            }
1916670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1926670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            canvas->concat(mat);
19326da7f00aedba107d4b3e382283034e265db09b6skia.committer@gmail.com            if (fUseAtlas) {
19444e3f715e694e2a97ab283a10dcbc26556d92018commit-bot@chromium.org                const int curCell = i % (kNumAtlasedX * kNumAtlasedY);
195631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                SkIRect src = fAtlasRects[curCell % (kNumAtlasedX)][curCell / (kNumAtlasedX)];
196631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com
197631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                if (fUseDrawVertices) {
1985d4b7733ae1d68b12163447977a74893c04b7342skia.committer@gmail.com                    SkPoint uvs[4] = {
199631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fLeft),  SkIntToScalar(src.fBottom) },
200631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fLeft),  SkIntToScalar(src.fTop) },
201631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fRight), SkIntToScalar(src.fTop) },
202631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fRight), SkIntToScalar(src.fBottom) },
203631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                    };
204887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed                    canvas->drawVertices(SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
205887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed                                                              4, verts, uvs, nullptr, 6, indices),
206887cdf112809727c51890ba8b98b3ddce22249f0Mike Reed                                         SkBlendMode::kModulate, p2);
207631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                } else {
20884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed                    canvas->drawBitmapRect(fAtlas, src, dst, &p,
20984984efeb64787b88c5f8bd6929cfe2d58a3ba06reed                                           SkCanvas::kFast_SrcRectConstraint);
210631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                }
211f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            } else {
21284984efeb64787b88c5f8bd6929cfe2d58a3ba06reed                canvas->drawBitmapRect(fCheckerboard, dst, &p);
213f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            }
2146670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
2156670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
2166670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2176670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.comprivate:
2186670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    static const int kCheckerboardWidth = 64;
2196670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    static const int kCheckerboardHeight = 128;
220f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
221f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kAtlasCellWidth = 48;
222f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kAtlasCellHeight = 36;
223f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kNumAtlasedX = 5;
224f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kNumAtlasedY = 5;
225f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kAtlasSpacer = 2;
226f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kTotAtlasWidth  = kNumAtlasedX * kAtlasCellWidth +
227f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                       (kNumAtlasedX+1) * kAtlasSpacer;
228f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kTotAtlasHeight = kNumAtlasedY * kAtlasCellHeight +
229f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                       (kNumAtlasedY+1) * kAtlasSpacer;
230c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    static const int kNumBeforeClear = 100;
2316670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2326670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    Type     fType;
233f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    Clear    fClear;
234347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com    bool     fAligned;
235f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    bool     fUseAtlas;
236631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com    bool     fUseDrawVertices;
2376670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    SkString fName;
2386670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    int      fNumSaved; // num draws stored in 'fSaved'
2396670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    bool     fInitialized;
2406670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2416670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    // 0 & 1 are always x & y translate. 2 is either scale or rotate.
2426670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    SkScalar fSaved[kNumBeforeClear][3];
243f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
2446670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    SkBitmap fCheckerboard;
245f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    SkBitmap fAtlas;
246f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    SkIRect  fAtlasRects[kNumAtlasedX][kNumAtlasedY];
2476670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2486670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    // Note: the resulting checker board has transparency
2496670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    void makeCheckerboard() {
2506d58ad3a82852ba16eebaef323516b923905eaecrobertphillips@google.com        static int kCheckSize = 16;
2516670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2526c22573edb234ad14df947278cfed010669a39a7reed        fCheckerboard.allocN32Pixels(kCheckerboardWidth, kCheckerboardHeight);
2536d58ad3a82852ba16eebaef323516b923905eaecrobertphillips@google.com        for (int y = 0; y < kCheckerboardHeight; ++y) {
2546670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            int even = (y / kCheckSize) % 2;
2556670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2566670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            SkPMColor* scanline = fCheckerboard.getAddr32(0, y);
2576670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2586d58ad3a82852ba16eebaef323516b923905eaecrobertphillips@google.com            for (int x = 0; x < kCheckerboardWidth; ++x) {
2596670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                if (even == (x / kCheckSize) % 2) {
2606670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    *scanline++ = 0xFFFF0000;
2616670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                } else {
2626670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    *scanline++ = 0x00000000;
2636670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                }
2646670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            }
2656670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
2666670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
2676670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
268f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    // Note: the resulting atlas has transparency
269f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    void makeAtlas() {
270e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rand;
271f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
272f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        SkColor colors[kNumAtlasedX][kNumAtlasedY];
273f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
274f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        for (int y = 0; y < kNumAtlasedY; ++y) {
275f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            for (int x = 0; x < kNumAtlasedX; ++x) {
276f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                colors[x][y] = rand.nextU() | 0xff000000;
277f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                fAtlasRects[x][y] = SkIRect::MakeXYWH(kAtlasSpacer + x * (kAtlasCellWidth + kAtlasSpacer),
278f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                                      kAtlasSpacer + y * (kAtlasCellHeight + kAtlasSpacer),
279f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                                      kAtlasCellWidth,
280f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                                      kAtlasCellHeight);
281f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            }
282f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        }
283f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
2846c22573edb234ad14df947278cfed010669a39a7reed        fAtlas.allocN32Pixels(kTotAtlasWidth, kTotAtlasHeight);
285f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
286f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        for (int y = 0; y < kTotAtlasHeight; ++y) {
287f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            int colorY = y / (kAtlasCellHeight + kAtlasSpacer);
288f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            bool inColorY = (y % (kAtlasCellHeight + kAtlasSpacer)) >= kAtlasSpacer;
289f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
290f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            SkPMColor* scanline = fAtlas.getAddr32(0, y);
291f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
292f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            for (int x = 0; x < kTotAtlasWidth; ++x, ++scanline) {
293f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                int colorX = x / (kAtlasCellWidth + kAtlasSpacer);
294f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                bool inColorX = (x % (kAtlasCellWidth + kAtlasSpacer)) >= kAtlasSpacer;
295f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
296f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                if (inColorX && inColorY) {
297f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                    SkASSERT(colorX < kNumAtlasedX && colorY < kNumAtlasedY);
298f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                    *scanline = colors[colorX][colorY];
299f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                } else {
300f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                    *scanline = 0x00000000;
301f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                }
302f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            }
303f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        }
304f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    }
305f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
306f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
3076670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com};
3086670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
3096670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// Partial clear
310385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kScale_Type, GameBench::kPartial_Clear);)
311385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kPartial_Clear);)
312385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kPartial_Clear, true);)
313385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kRotate_Type, GameBench::kPartial_Clear);)
3146670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
3156670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// Full clear
316385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kScale_Type, GameBench::kFull_Clear);)
317385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kFull_Clear);)
318385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kFull_Clear, true);)
319385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kRotate_Type, GameBench::kFull_Clear);)
320f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
321f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com// Atlased
322385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kFull_Clear, false, true);)
323385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanaryDEF_BENCH(return new GameBench(
324385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary                         GameBench::kTranslate_Type, GameBench::kFull_Clear, false, true, true);)
325