main.cpp revision 27e58b4f54d693ff1db7ab2edb5d47ca296c1278
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "tests/common/TestScene.h"
18
19#include "protos/hwui.pb.h"
20
21#include <getopt.h>
22#include <stdio.h>
23#include <string>
24#include <unistd.h>
25#include <unordered_map>
26#include <vector>
27
28using namespace android;
29using namespace android::uirenderer;
30using namespace android::uirenderer::test;
31
32static int gFrameCount = 150;
33static int gRepeatCount = 1;
34static std::vector<TestScene::Info> gRunTests;
35
36void run(const TestScene::Info& info, const TestScene::Options& opts);
37
38static void printHelp() {
39    printf("\
40USAGE: hwuitest [OPTIONS] <TESTNAME>\n\
41\n\
42OPTIONS:\n\
43  -c, --count=NUM      NUM loops a test should run (example, number of frames)\n\
44  -r, --runs=NUM       Repeat the test(s) NUM times\n\
45  -h, --help           Display this help\n\
46  --list               List all tests\n\
47\n");
48}
49
50static void listTests() {
51    printf("Tests: \n");
52    for (auto&& test : TestScene::testMap()) {
53        auto&& info = test.second;
54        const char* col1 = info.name.c_str();
55        int dlen = info.description.length();
56        const char* col2 = info.description.c_str();
57        // World's best line breaking algorithm.
58        do {
59            int toPrint = dlen;
60            if (toPrint > 50) {
61                char* found = (char*) memrchr(col2, ' ', 50);
62                if (found) {
63                    toPrint = found - col2;
64                } else {
65                    toPrint = 50;
66                }
67            }
68            printf("%-20s %.*s\n", col1, toPrint, col2);
69            col1 = "";
70            col2 += toPrint;
71            dlen -= toPrint;
72            while (*col2 == ' ') {
73                col2++; dlen--;
74            }
75        } while (dlen > 0);
76        printf("\n");
77    }
78}
79
80static const struct option LONG_OPTIONS[] = {
81    { "frames", required_argument, nullptr, 'f' },
82    { "repeat", required_argument, nullptr, 'r' },
83    { "help", no_argument, nullptr, 'h' },
84    { "list", no_argument, nullptr, 'l' },
85    { 0, 0, 0, 0 }
86};
87
88static const char* SHORT_OPTIONS = "c:r:h";
89
90void parseOptions(int argc, char* argv[]) {
91    int c;
92    // temporary variable
93    int count;
94    bool error = false;
95    opterr = 0;
96
97    while (true) {
98
99        /* getopt_long stores the option index here. */
100        int option_index = 0;
101
102        c = getopt_long(argc, argv, SHORT_OPTIONS, LONG_OPTIONS, &option_index);
103
104        if (c == -1)
105            break;
106
107        switch (c) {
108        case 0:
109            // Option set a flag, don't need to do anything
110            // (although none of the current LONG_OPTIONS do this...)
111            break;
112
113        case 'l':
114            listTests();
115            exit(EXIT_SUCCESS);
116            break;
117
118        case 'c':
119            count = atoi(optarg);
120            if (!count) {
121                fprintf(stderr, "Invalid frames argument '%s'\n", optarg);
122                error = true;
123            } else {
124                gFrameCount = (count > 0 ? count : INT_MAX);
125            }
126            break;
127
128        case 'r':
129            count = atoi(optarg);
130            if (!count) {
131                fprintf(stderr, "Invalid repeat argument '%s'\n", optarg);
132                error = true;
133            } else {
134                gRepeatCount = (count > 0 ? count : INT_MAX);
135            }
136            break;
137
138        case 'h':
139            printHelp();
140            exit(EXIT_SUCCESS);
141            break;
142
143        case '?':
144            fprintf(stderr, "Unrecognized option '%s'\n", argv[optind - 1]);
145            // fall-through
146        default:
147            error = true;
148            break;
149        }
150    }
151
152    if (error) {
153        fprintf(stderr, "Try 'hwuitest --help' for more information.\n");
154        exit(EXIT_FAILURE);
155    }
156
157    /* Print any remaining command line arguments (not options). */
158    if (optind < argc) {
159        do {
160            const char* test = argv[optind++];
161            auto pos = TestScene::testMap().find(test);
162            if (pos == TestScene::testMap().end()) {
163                fprintf(stderr, "Unknown test '%s'\n", test);
164                exit(EXIT_FAILURE);
165            } else {
166                gRunTests.push_back(pos->second);
167            }
168        } while (optind < argc);
169    } else {
170        gRunTests.push_back(TestScene::testMap()["shadowgrid"]);
171    }
172}
173
174int main(int argc, char* argv[]) {
175    parseOptions(argc, argv);
176
177    TestScene::Options opts;
178    opts.count = gFrameCount;
179    for (int i = 0; i < gRepeatCount; i++) {
180        for (auto&& test : gRunTests) {
181            run(test, opts);
182        }
183    }
184    printf("Success!\n");
185    return 0;
186}
187