blob: 48566e8f6ecd589412cfba5ee7f531ea594d057a [file] [log] [blame]
John Reck94c40fe2014-10-08 09:28:43 -07001/*
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
John Recke702c9c2015-10-07 10:26:02 -070017#include "Benchmark.h"
John Reck94c40fe2014-10-08 09:28:43 -070018
John Recke248bd12015-08-05 13:53:53 -070019#include "protos/hwui.pb.h"
20
John Reckb7dd29e2015-10-06 13:28:17 -070021#include <getopt.h>
John Recke702c9c2015-10-07 10:26:02 -070022#include <stdio.h>
23#include <string>
24#include <unistd.h>
25#include <unordered_map>
John Reckb7dd29e2015-10-06 13:28:17 -070026#include <vector>
John Reck7f2e5e32015-05-05 11:00:53 -070027
John Reck94c40fe2014-10-08 09:28:43 -070028using namespace android;
29using namespace android::uirenderer;
John Reck94c40fe2014-10-08 09:28:43 -070030
John Recke702c9c2015-10-07 10:26:02 -070031// Not a static global because we need to force the map to be constructed
32// before we try to add things to it.
33std::unordered_map<std::string, BenchmarkInfo>& testMap() {
34 static std::unordered_map<std::string, BenchmarkInfo> testMap;
35 return testMap;
John Reck94c40fe2014-10-08 09:28:43 -070036}
37
John Recke702c9c2015-10-07 10:26:02 -070038void Benchmark::registerBenchmark(const BenchmarkInfo& info) {
39 testMap()[info.name] = info;
John Reck94c40fe2014-10-08 09:28:43 -070040}
41
John Reckb7dd29e2015-10-06 13:28:17 -070042static int gFrameCount = 150;
43static int gRepeatCount = 1;
John Recke702c9c2015-10-07 10:26:02 -070044static std::vector<BenchmarkInfo> gRunTests;
John Reckb7dd29e2015-10-06 13:28:17 -070045
John Reck16c9d6a2015-11-17 15:51:08 -080046void run(const BenchmarkInfo& info, const BenchmarkOptions& opts);
47
John Reckb7dd29e2015-10-06 13:28:17 -070048static void printHelp() {
49 printf("\
50USAGE: hwuitest [OPTIONS] <TESTNAME>\n\
51\n\
52OPTIONS:\n\
53 -c, --count=NUM NUM loops a test should run (example, number of frames)\n\
54 -r, --runs=NUM Repeat the test(s) NUM times\n\
55 -h, --help Display this help\n\
56 --list List all tests\n\
57\n");
58}
59
60static void listTests() {
61 printf("Tests: \n");
John Recke702c9c2015-10-07 10:26:02 -070062 for (auto&& test : testMap()) {
63 auto&& info = test.second;
64 const char* col1 = info.name.c_str();
65 int dlen = info.description.length();
66 const char* col2 = info.description.c_str();
67 // World's best line breaking algorithm.
68 do {
69 int toPrint = dlen;
70 if (toPrint > 50) {
71 char* found = (char*) memrchr(col2, ' ', 50);
72 if (found) {
73 toPrint = found - col2;
74 } else {
75 toPrint = 50;
76 }
77 }
78 printf("%-20s %.*s\n", col1, toPrint, col2);
79 col1 = "";
80 col2 += toPrint;
81 dlen -= toPrint;
82 while (*col2 == ' ') {
83 col2++; dlen--;
84 }
85 } while (dlen > 0);
86 printf("\n");
John Reckb7dd29e2015-10-06 13:28:17 -070087 }
88}
89
90static const struct option LONG_OPTIONS[] = {
91 { "frames", required_argument, nullptr, 'f' },
92 { "repeat", required_argument, nullptr, 'r' },
93 { "help", no_argument, nullptr, 'h' },
94 { "list", no_argument, nullptr, 'l' },
95 { 0, 0, 0, 0 }
96};
97
98static const char* SHORT_OPTIONS = "c:r:h";
99
100void parseOptions(int argc, char* argv[]) {
101 int c;
102 // temporary variable
103 int count;
104 bool error = false;
105 opterr = 0;
106
107 while (true) {
108
109 /* getopt_long stores the option index here. */
110 int option_index = 0;
111
112 c = getopt_long(argc, argv, SHORT_OPTIONS, LONG_OPTIONS, &option_index);
113
114 if (c == -1)
115 break;
116
117 switch (c) {
118 case 0:
119 // Option set a flag, don't need to do anything
120 // (although none of the current LONG_OPTIONS do this...)
121 break;
122
123 case 'l':
124 listTests();
125 exit(EXIT_SUCCESS);
126 break;
127
128 case 'c':
129 count = atoi(optarg);
130 if (!count) {
131 fprintf(stderr, "Invalid frames argument '%s'\n", optarg);
132 error = true;
133 } else {
134 gFrameCount = (count > 0 ? count : INT_MAX);
135 }
136 break;
137
138 case 'r':
139 count = atoi(optarg);
140 if (!count) {
141 fprintf(stderr, "Invalid repeat argument '%s'\n", optarg);
142 error = true;
143 } else {
144 gRepeatCount = (count > 0 ? count : INT_MAX);
145 }
146 break;
147
148 case 'h':
149 printHelp();
150 exit(EXIT_SUCCESS);
151 break;
152
153 case '?':
154 fprintf(stderr, "Unrecognized option '%s'\n", argv[optind - 1]);
155 // fall-through
156 default:
157 error = true;
158 break;
159 }
160 }
161
162 if (error) {
163 fprintf(stderr, "Try 'hwuitest --help' for more information.\n");
164 exit(EXIT_FAILURE);
165 }
166
167 /* Print any remaining command line arguments (not options). */
168 if (optind < argc) {
169 do {
170 const char* test = argv[optind++];
John Recke702c9c2015-10-07 10:26:02 -0700171 auto pos = testMap().find(test);
172 if (pos == testMap().end()) {
John Reckb7dd29e2015-10-06 13:28:17 -0700173 fprintf(stderr, "Unknown test '%s'\n", test);
174 exit(EXIT_FAILURE);
175 } else {
176 gRunTests.push_back(pos->second);
177 }
178 } while (optind < argc);
179 } else {
John Recke702c9c2015-10-07 10:26:02 -0700180 gRunTests.push_back(testMap()["shadowgrid"]);
John Reckb7dd29e2015-10-06 13:28:17 -0700181 }
182}
183
Chris Craik03188872015-02-02 18:39:33 -0800184int main(int argc, char* argv[]) {
John Reckb7dd29e2015-10-06 13:28:17 -0700185 parseOptions(argc, argv);
186
John Recke702c9c2015-10-07 10:26:02 -0700187 BenchmarkOptions opts;
188 opts.count = gFrameCount;
John Reckb7dd29e2015-10-06 13:28:17 -0700189 for (int i = 0; i < gRepeatCount; i++) {
190 for (auto&& test : gRunTests) {
John Reck16c9d6a2015-11-17 15:51:08 -0800191 run(test, opts);
Tim Murray1a0f1c72015-05-06 11:37:37 -0700192 }
193 }
John Reck94c40fe2014-10-08 09:28:43 -0700194 printf("Success!\n");
195 return 0;
196}