skia_test.cpp revision 5a6324e3140eb16cd5255867eae02a2c88d54271
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org
85a6324e3140eb16cd5255867eae02a2c88d54271scroggo@google.com#include "SkCommandLineFlags.h"
95e5adfd12cc2cb194db971708cd7f34ff47e10b4reed@android.com#include "SkGraphics.h"
10ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com#include "Test.h"
11789c6f291ecfff925086015360da525d6de1c835reed@google.com#include "SkOSFile.h"
12ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
13bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com#if SK_SUPPORT_GPU
14bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com#include "GrContext.h"
15bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com#endif
16bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com
17ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comusing namespace skiatest;
18ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
19d252db03d9650013b545ef9781fe993c07f8f314reed@android.com// need to explicitly declare this, or we get some weird infinite loop llist
20d252db03d9650013b545ef9781fe993c07f8f314reed@android.comtemplate TestRegistry* TestRegistry::gHead;
21d252db03d9650013b545ef9781fe993c07f8f314reed@android.com
22ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comclass Iter {
23ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.compublic:
24ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    Iter(Reporter* r) : fReporter(r) {
25ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        r->ref();
26ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        fReg = TestRegistry::Head();
27ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
2880e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
29ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    ~Iter() {
30ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        fReporter->unref();
31ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
3280e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
33ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    Test* next() {
34ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        if (fReg) {
35ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            TestRegistry::Factory fact = fReg->factory();
36ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            fReg = fReg->next();
37ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            Test* test = fact(NULL);
38ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            test->setReporter(fReporter);
39ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com            return test;
40ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        }
41ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        return NULL;
42ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
4380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
4457b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com    static int Count() {
4557b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        const TestRegistry* reg = TestRegistry::Head();
4657b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        int count = 0;
4757b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        while (reg) {
4857b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com            count += 1;
4957b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com            reg = reg->next();
5057b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        }
5157b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        return count;
5257b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com    }
5380e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
54ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comprivate:
55ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    Reporter* fReporter;
56ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    const TestRegistry* fReg;
57ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com};
58ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
59ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comstatic const char* result2string(Reporter::Result result) {
60ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    return result == Reporter::kPassed ? "passed" : "FAILED";
61ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
62ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
63d252db03d9650013b545ef9781fe993c07f8f314reed@android.comclass DebugfReporter : public Reporter {
6457b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.compublic:
65d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com    DebugfReporter(bool allowExtendedTest)
66d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com        : fIndex(0)
67d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com        , fTotal(0)
68d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com        , fAllowExtendedTest(allowExtendedTest) {
69d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com    }
70eeb3b7ff9813600b6cab662e1a0174ee2e279cacreed@android.com
7157b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com    void setIndexOfTotal(int index, int total) {
7257b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        fIndex = index;
7357b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        fTotal = total;
7457b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com    }
75d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com
76d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com    virtual bool allowExtendedTest() const {
77391ca66276b27464f255c371e7e95f56f9042042skia.committer@gmail.com        return fAllowExtendedTest;
78d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com    }
79d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com
80ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.comprotected:
81ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    virtual void onStart(Test* test) {
82f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.com        SkDebugf("[%d/%d] %s...\n", fIndex+1, fTotal, test->getName());
83ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
84ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    virtual void onReport(const char desc[], Reporter::Result result) {
85f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.com        SkDebugf("\t%s: %s\n", result2string(result), desc);
86eeb3b7ff9813600b6cab662e1a0174ee2e279cacreed@android.com    }
8754f0d1b7113cb0dc184e522539aab1030a28a421sugoi@google.com    virtual void onEnd(Test*) {
88f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.com        if (!this->getCurrSuccess()) {
89f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.com            SkDebugf("---- FAILED\n");
90eeb3b7ff9813600b6cab662e1a0174ee2e279cacreed@android.com        }
91eeb3b7ff9813600b6cab662e1a0174ee2e279cacreed@android.com    }
92f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.comprivate:
9357b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com    int fIndex, fTotal;
94d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com    bool fAllowExtendedTest;
95ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com};
96ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com
97789c6f291ecfff925086015360da525d6de1c835reed@google.comstatic const char* make_canonical_dir_path(const char* path, SkString* storage) {
98789c6f291ecfff925086015360da525d6de1c835reed@google.com    if (path) {
99789c6f291ecfff925086015360da525d6de1c835reed@google.com        // clean it up so it always has a trailing searator
100789c6f291ecfff925086015360da525d6de1c835reed@google.com        size_t len = strlen(path);
101789c6f291ecfff925086015360da525d6de1c835reed@google.com        if (0 == len) {
102789c6f291ecfff925086015360da525d6de1c835reed@google.com            path = NULL;
103789c6f291ecfff925086015360da525d6de1c835reed@google.com        } else if (SkPATH_SEPARATOR != path[len - 1]) {
104789c6f291ecfff925086015360da525d6de1c835reed@google.com            // resize to len + 1, to make room for searator
105789c6f291ecfff925086015360da525d6de1c835reed@google.com            storage->set(path, len + 1);
106789c6f291ecfff925086015360da525d6de1c835reed@google.com            storage->writable_str()[len] = SkPATH_SEPARATOR;
107789c6f291ecfff925086015360da525d6de1c835reed@google.com            path = storage->c_str();
108789c6f291ecfff925086015360da525d6de1c835reed@google.com        }
109789c6f291ecfff925086015360da525d6de1c835reed@google.com    }
110789c6f291ecfff925086015360da525d6de1c835reed@google.com    return path;
111789c6f291ecfff925086015360da525d6de1c835reed@google.com}
112789c6f291ecfff925086015360da525d6de1c835reed@google.com
113cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.comstatic SkString gTmpDir;
114789c6f291ecfff925086015360da525d6de1c835reed@google.com
115cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.comconst SkString& Test::GetTmpDir() {
116789c6f291ecfff925086015360da525d6de1c835reed@google.com    return gTmpDir;
117789c6f291ecfff925086015360da525d6de1c835reed@google.com}
118789c6f291ecfff925086015360da525d6de1c835reed@google.com
119cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.comstatic SkString gResourcePath;
120cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com
121cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.comconst SkString& Test::GetResourcePath() {
122cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com    return gResourcePath;
123cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com}
124cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com
1259aff14831b45a7e31e46ebec482df9db6f125745reed@google.comDEFINE_string2(match, m, NULL, "substring of test name to run.");
126ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.orgDEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use.");
127ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.orgDEFINE_string2(resourcePath, i, NULL, "directory for test resources.");
128ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.orgDEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
129ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.orgDEFINE_bool2(verbose, v, false, "enable verbose output.");
130ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org
1315987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
1325987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
133ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    SkCommandLineFlags::SetUsage("");
134ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    SkCommandLineFlags::Parse(argc, argv);
135ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org
136ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    if (!FLAGS_tmpDir.isEmpty()) {
137ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org        make_canonical_dir_path(FLAGS_tmpDir[0], &gTmpDir);
138ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    }
139ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    if (!FLAGS_resourcePath.isEmpty()) {
140ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org        make_canonical_dir_path(FLAGS_resourcePath[0], &gResourcePath);
141ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    }
142ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org
1434e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
144a276975a62ef4d9941e40c831fdfe7852e0e243ereed@google.com    gPrintInstCount = true;
145a276975a62ef4d9941e40c831fdfe7852e0e243ereed@google.com#endif
146d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com
147a276975a62ef4d9941e40c831fdfe7852e0e243ereed@google.com    SkGraphics::Init();
1485af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com
14991d449ebf895d3c412a051272af3175be6976872reed@google.com    {
15091d449ebf895d3c412a051272af3175be6976872reed@google.com        SkString header("Skia UnitTests:");
1519aff14831b45a7e31e46ebec482df9db6f125745reed@google.com        if (!FLAGS_match.isEmpty()) {
1529aff14831b45a7e31e46ebec482df9db6f125745reed@google.com            header.appendf(" --match %s", FLAGS_match[0]);
15391d449ebf895d3c412a051272af3175be6976872reed@google.com        }
154cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com        if (!gTmpDir.isEmpty()) {
155cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com            header.appendf(" --tmpDir %s", gTmpDir.c_str());
156cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com        }
157cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com        if (!gResourcePath.isEmpty()) {
158cb62650ecfd323a1ac215103a4d3106faad3c3cddjsollen@google.com            header.appendf(" --resourcePath %s", gResourcePath.c_str());
159789c6f291ecfff925086015360da525d6de1c835reed@google.com        }
16091d449ebf895d3c412a051272af3175be6976872reed@google.com#ifdef SK_DEBUG
16191d449ebf895d3c412a051272af3175be6976872reed@google.com        header.append(" SK_DEBUG");
16291d449ebf895d3c412a051272af3175be6976872reed@google.com#else
16391d449ebf895d3c412a051272af3175be6976872reed@google.com        header.append(" SK_RELEASE");
16491d449ebf895d3c412a051272af3175be6976872reed@google.com#endif
16591d449ebf895d3c412a051272af3175be6976872reed@google.com#ifdef SK_SCALAR_IS_FIXED
16691d449ebf895d3c412a051272af3175be6976872reed@google.com        header.append(" SK_SCALAR_IS_FIXED");
16791d449ebf895d3c412a051272af3175be6976872reed@google.com#else
16891d449ebf895d3c412a051272af3175be6976872reed@google.com        header.append(" SK_SCALAR_IS_FLOAT");
16991d449ebf895d3c412a051272af3175be6976872reed@google.com#endif
170f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.com        SkDebugf("%s\n", header.c_str());
17191d449ebf895d3c412a051272af3175be6976872reed@google.com    }
17291d449ebf895d3c412a051272af3175be6976872reed@google.com
173ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    DebugfReporter reporter(FLAGS_extendedTest);
174ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    Iter iter(&reporter);
175ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    Test* test;
17680e39a77b16f4396eed230efea1d0b2fc8cbfb00reed@android.com
17757b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com    const int count = Iter::Count();
17857b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com    int index = 0;
1795af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com    int failCount = 0;
1805af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com    int skipCount = 0;
181ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    while ((test = iter.next()) != NULL) {
18257b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        reporter.setIndexOfTotal(index, count);
1839aff14831b45a7e31e46ebec482df9db6f125745reed@google.com        if (!FLAGS_match.isEmpty() && !strstr(test->getName(), FLAGS_match[0])) {
1845af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com            ++skipCount;
1855af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com        } else {
1865af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com            if (!test->run()) {
1875af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com                ++failCount;
1885af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com            }
1895af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com        }
190ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com        SkDELETE(test);
19157b799e951064b9328b5c676dcc3b4cb4477cc2breed@android.com        index += 1;
192ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com    }
193eeb3b7ff9813600b6cab662e1a0174ee2e279cacreed@android.com
194f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.com    SkDebugf("Finished %d tests, %d failures, %d skipped.\n",
195f4d1b3911831d2111a351b2742b3a94a9d17f92edjsollen@google.com             count, failCount, skipCount);
196d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com    int testCount = reporter.countTests();
197ba59d64b05b13081060a266c999158efab575b61commit-bot@chromium.org    if (FLAGS_verbose && testCount > 0) {
198d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com        SkDebugf("Ran %d Internal tests.\n", testCount);
199d54e1e9751eea63b528a6e62d919d06929c9bd8fcaryclark@google.com    }
200bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com#if SK_SUPPORT_GPU
201bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com
202bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com#if GR_CACHE_STATS
203bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com    GrContext *gr = GpuTest::GetContext();
204bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com
205bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com    gr->printCacheStats();
206bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com#endif
207bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com
208bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com#endif
209bdb1be599436a894ab88dfc323d14c0afb496a6frobertphillips@google.com
210a276975a62ef4d9941e40c831fdfe7852e0e243ereed@google.com    SkGraphics::Term();
21167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com    GpuTest::DestroyContexts();
212a276975a62ef4d9941e40c831fdfe7852e0e243ereed@google.com
2135af16f8d670b3ce1c7644a4737e02e2e2257614ebungeman@google.com    return (failCount == 0) ? 0 : 1;
214ed673310e2551e64d8196f7776d7d4c92085f8c2reed@android.com}
2155987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
2167158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
2175987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
2185987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
2195987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
2205987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
221