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"
146670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
156670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// This bench simulates the calls Skia sees from various HTML5 canvas
166670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// game bench marks
17f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass GameBench : public Benchmark {
186670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.compublic:
196670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    enum Type {
200f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com        kScale_Type,
210f20a3fc59dee846ca137dd7a263e655550e6cbfskia.committer@gmail.com        kTranslate_Type,
226670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        kRotate_Type
236670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    };
246670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
25f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    enum Clear {
26f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        kFull_Clear,
27f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        kPartial_Clear
28f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    };
29f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
30410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com    GameBench(Type type, Clear clear,
31631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com              bool aligned = false, bool useAtlas = false,
32631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com              bool useDrawVertices = false)
33410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com        : fType(type)
34f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        , fClear(clear)
35347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com        , fAligned(aligned)
36f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        , fUseAtlas(useAtlas)
37631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        , fUseDrawVertices(useDrawVertices)
386670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        , fName("game")
396670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        , fNumSaved(0)
406670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        , fInitialized(false) {
416670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
426670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        switch (fType) {
436670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        case kScale_Type:
446670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_scale");
456670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            break;
466670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        case kTranslate_Type:
476670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_trans");
486670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            break;
496670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        case kRotate_Type:
506670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_rot");
516670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            break;
526670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        };
536670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
54347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com        if (aligned) {
55347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com            fName.append("_aligned");
56347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com        }
57347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com
58f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        if (kPartial_Clear == clear) {
596670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_partial");
606670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        } else {
616670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fName.append("_full");
626670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
636670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
64f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        if (useAtlas) {
65f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            fName.append("_atlas");
66f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        }
67f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
68631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        if (useDrawVertices) {
69631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            fName.append("_drawVerts");
70631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        }
71631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com
726670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        // It's HTML 5 canvas, so always AA
736670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        fName.append("_aa");
746670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
756670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
766670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.comprotected:
776670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    virtual const char* onGetName() SK_OVERRIDE {
78f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        return fName.c_str();
796670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
806670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
816670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    virtual void onPreDraw() SK_OVERRIDE {
826670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        if (!fInitialized) {
836670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            this->makeCheckerboard();
84f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            this->makeAtlas();
856670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fInitialized = true;
866670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
876670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
886670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
893361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
90e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom scaleRand;
91e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom transRand;
92e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        SkRandom rotRand;
936670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
94f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        int width, height;
95f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        if (fUseAtlas) {
96f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            width = kAtlasCellWidth;
97f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            height = kAtlasCellHeight;
98f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        } else {
99f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            width = kCheckerboardWidth;
100f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            height = kCheckerboardHeight;
101f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        }
102f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
1036670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkPaint clearPaint;
1046670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        clearPaint.setColor(0xFF000000);
1056670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        clearPaint.setAntiAlias(true);
1066670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1076670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkISize size = canvas->getDeviceSize();
1086670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1096670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkScalar maxTransX, maxTransY;
1106670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1116670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        if (kScale_Type == fType) {
112f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransX = size.fWidth  - (1.5f * width);
113f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransY = size.fHeight - (1.5f * height);
1146670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        } else if (kTranslate_Type == fType) {
115f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransX = SkIntToScalar(size.fWidth  - width);
116f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransY = SkIntToScalar(size.fHeight - height);
1176670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        } else {
1186670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            SkASSERT(kRotate_Type == fType);
1196670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            // Yes, some rotations will be off the top and left sides
120f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransX = size.fWidth  - SK_ScalarSqrt2 * height;
121f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            maxTransY = size.fHeight - SK_ScalarSqrt2 * height;
1226670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
1236670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1246670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkMatrix mat;
125f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) };
126f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f };
127631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        SkPoint verts[4] = { // for drawVertices path
128631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { 0, 0 },
129631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { 0, SkIntToScalar(height) },
130631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { SkIntToScalar(width), SkIntToScalar(height) },
131631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com            { SkIntToScalar(width), 0 }
132631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        };
133631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 };
1346670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1356670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkPaint p;
1366670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        p.setColor(0xFF000000);
1374469938e92d779dff05e745559e67907bbf21e78reed@google.com        p.setFilterLevel(SkPaint::kLow_FilterLevel);
1386670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
139631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        SkPaint p2;         // for drawVertices path
140631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com        p2.setColor(0xFF000000);
1414469938e92d779dff05e745559e67907bbf21e78reed@google.com        p2.setFilterLevel(SkPaint::kLow_FilterLevel);
1425d4b7733ae1d68b12163447977a74893c04b7342skia.committer@gmail.com        p2.setShader(SkShader::CreateBitmapShader(fAtlas,
143631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                                                  SkShader::kClamp_TileMode,
144631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                                                  SkShader::kClamp_TileMode))->unref();
145631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com
1463361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; ++i, ++fNumSaved) {
1476670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            if (0 == i % kNumBeforeClear) {
148f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                if (kPartial_Clear == fClear) {
1496670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    for (int j = 0; j < fNumSaved; ++j) {
1506670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        canvas->setMatrix(SkMatrix::I());
1516670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        mat.setTranslate(fSaved[j][0], fSaved[j][1]);
1526670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1536670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        if (kScale_Type == fType) {
1546670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                            mat.preScale(fSaved[j][2], fSaved[j][2]);
1556670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        } else if (kRotate_Type == fType) {
1566670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                            mat.preRotate(fSaved[j][2]);
1576670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        }
1586670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1596670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        canvas->concat(mat);
1606670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                        canvas->drawRect(clearRect, clearPaint);
1616670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    }
1626670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                } else {
1636670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                    canvas->clear(0xFF000000);
1646670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                }
1656670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1666670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                fNumSaved = 0;
1676670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            }
1686670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1696670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            SkASSERT(fNumSaved < kNumBeforeClear);
1706670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1716670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            canvas->setMatrix(SkMatrix::I());
1726670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1736670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fSaved[fNumSaved][0] = transRand.nextRangeScalar(0.0f, maxTransX);
1746670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            fSaved[fNumSaved][1] = transRand.nextRangeScalar(0.0f, maxTransY);
175347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com            if (fAligned) {
176347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com                // make the translations integer aligned
177347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com                fSaved[fNumSaved][0] = SkScalarFloorToScalar(fSaved[fNumSaved][0]);
178347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com                fSaved[fNumSaved][1] = SkScalarFloorToScalar(fSaved[fNumSaved][1]);
179347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com            }
1806670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1816670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            mat.setTranslate(fSaved[fNumSaved][0], fSaved[fNumSaved][1]);
1826670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1836670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            if (kScale_Type == fType) {
1846670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                fSaved[fNumSaved][2] = scaleRand.nextRangeScalar(0.5f, 1.5f);
1856670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                mat.preScale(fSaved[fNumSaved][2], fSaved[fNumSaved][2]);
1866670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            } else if (kRotate_Type == fType) {
1876670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                fSaved[fNumSaved][2] = rotRand.nextRangeScalar(0.0f, 360.0f);
1886670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com                mat.preRotate(fSaved[fNumSaved][2]);
1896670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            }
1906670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
1916670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com            canvas->concat(mat);
19226da7f00aedba107d4b3e382283034e265db09b6skia.committer@gmail.com            if (fUseAtlas) {
19344e3f715e694e2a97ab283a10dcbc26556d92018commit-bot@chromium.org                const int curCell = i % (kNumAtlasedX * kNumAtlasedY);
194631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                SkIRect src = fAtlasRects[curCell % (kNumAtlasedX)][curCell / (kNumAtlasedX)];
195631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com
196631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                if (fUseDrawVertices) {
1975d4b7733ae1d68b12163447977a74893c04b7342skia.committer@gmail.com                    SkPoint uvs[4] = {
198631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fLeft),  SkIntToScalar(src.fBottom) },
199631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fLeft),  SkIntToScalar(src.fTop) },
200631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fRight), SkIntToScalar(src.fTop) },
201631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                        { SkIntToScalar(src.fRight), SkIntToScalar(src.fBottom) },
202631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                    };
203631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                    canvas->drawVertices(SkCanvas::kTriangles_VertexMode,
2045d4b7733ae1d68b12163447977a74893c04b7342skia.committer@gmail.com                                         4, verts, uvs, NULL, NULL,
205631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                                         indices, 6, p2);
206631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                } else {
2073c3c46238d72a365b8e11e295ad03bdf1bcbe206robertphillips@google.com                    canvas->drawBitmapRect(fAtlas, &src, dst, &p,
2083c3c46238d72a365b8e11e295ad03bdf1bcbe206robertphillips@google.com                                           SkCanvas::kBleed_DrawBitmapRectFlag);
209631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                }
210f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            } else {
211631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                canvas->drawBitmapRect(fCheckerboard, NULL, dst, &p);
212f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            }
2136670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        }
2146670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    }
2156670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2166670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.comprivate:
2176670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    static const int kCheckerboardWidth = 64;
2186670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    static const int kCheckerboardHeight = 128;
219f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
220f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kAtlasCellWidth = 48;
221f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kAtlasCellHeight = 36;
222f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kNumAtlasedX = 5;
223f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kNumAtlasedY = 5;
224f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kAtlasSpacer = 2;
225f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kTotAtlasWidth  = kNumAtlasedX * kAtlasCellWidth +
226f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                       (kNumAtlasedX+1) * kAtlasSpacer;
227f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    static const int kTotAtlasHeight = kNumAtlasedY * kAtlasCellHeight +
228f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                       (kNumAtlasedY+1) * kAtlasSpacer;
229c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    static const int kNumBeforeClear = 100;
2306670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2316670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    Type     fType;
232f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    Clear    fClear;
233347fd4e9fde6843128c841a3f0ba2482154781a5robertphillips@google.com    bool     fAligned;
234f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    bool     fUseAtlas;
235631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com    bool     fUseDrawVertices;
2366670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    SkString fName;
2376670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    int      fNumSaved; // num draws stored in 'fSaved'
2386670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    bool     fInitialized;
2396670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2406670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    // 0 & 1 are always x & y translate. 2 is either scale or rotate.
2416670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    SkScalar fSaved[kNumBeforeClear][3];
242f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
2436670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    SkBitmap fCheckerboard;
244f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    SkBitmap fAtlas;
245f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    SkIRect  fAtlasRects[kNumAtlasedX][kNumAtlasedY];
2466670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2476670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    // Note: the resulting checker board has transparency
2486670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com    void makeCheckerboard() {
2496d58ad3a82852ba16eebaef323516b923905eaecrobertphillips@google.com        static int kCheckSize = 16;
2506670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
2516c22573edb234ad14df947278cfed010669a39a7reed        fCheckerboard.allocN32Pixels(kCheckerboardWidth, kCheckerboardHeight);
2526670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com        SkAutoLockPixels lock(fCheckerboard);
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        SkAutoLockPixels lock(fAtlas);
286f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
287f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        for (int y = 0; y < kTotAtlasHeight; ++y) {
288f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            int colorY = y / (kAtlasCellHeight + kAtlasSpacer);
289f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            bool inColorY = (y % (kAtlasCellHeight + kAtlasSpacer)) >= kAtlasSpacer;
290f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
291f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            SkPMColor* scanline = fAtlas.getAddr32(0, y);
292f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
293f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            for (int x = 0; x < kTotAtlasWidth; ++x, ++scanline) {
294f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                int colorX = x / (kAtlasCellWidth + kAtlasSpacer);
295f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                bool inColorX = (x % (kAtlasCellWidth + kAtlasSpacer)) >= kAtlasSpacer;
296f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
297f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                if (inColorX && inColorY) {
298f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                    SkASSERT(colorX < kNumAtlasedX && colorY < kNumAtlasedY);
299f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                    *scanline = colors[colorX][colorY];
300f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                } else {
301f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                    *scanline = 0x00000000;
302f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                }
303f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com            }
304f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com        }
305f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com    }
306f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
307f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
3086670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com};
3096670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
3106670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// Partial clear
311410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kScale_Type,
312f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kPartial_Clear)); )
313410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type,
314f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kPartial_Clear)); )
315410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type,
316f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kPartial_Clear, true)); )
317410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kRotate_Type,
318f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kPartial_Clear)); )
3196670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com
3206670ab9e6313e219284bb1df9005c9c3217a52ddrobertphillips@google.com// Full clear
321410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kScale_Type,
322f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kFull_Clear)); )
323410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type,
324f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kFull_Clear)); )
325410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type,
326f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kFull_Clear, true)); )
327410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kRotate_Type,
328f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kFull_Clear)); )
329f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com
330f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com// Atlased
331410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type,
332f865be37868430ab75e3c787afc2869ba18216c3robertphillips@google.com                                            GameBench::kFull_Clear, false, true)); )
333410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.comDEF_BENCH( return SkNEW_ARGS(GameBench, (GameBench::kTranslate_Type,
334631a59b9393208ed3546e81ca843f2f7da06ca64robertphillips@google.com                                            GameBench::kFull_Clear, false, true, true)); )
335