main.cpp revision 8160f20b0aca8c6595d4b385d673f59b6bcd16a4
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 "Benchmark.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; 30 31// 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; 36} 37 38void Benchmark::registerBenchmark(const BenchmarkInfo& info) { 39 testMap()[info.name] = info; 40} 41 42static int gFrameCount = 150; 43static int gRepeatCount = 1; 44static std::vector<BenchmarkInfo> gRunTests; 45 46void run(const BenchmarkInfo& info, const BenchmarkOptions& opts); 47 48static 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"); 62 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"); 87 } 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++]; 171 auto pos = testMap().find(test); 172 if (pos == testMap().end()) { 173 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 { 180 gRunTests.push_back(testMap()["shadowgrid"]); 181 } 182} 183 184int main(int argc, char* argv[]) { 185 parseOptions(argc, argv); 186 187 BenchmarkOptions opts; 188 opts.count = gFrameCount; 189 for (int i = 0; i < gRepeatCount; i++) { 190 for (auto&& test : gRunTests) { 191 run(test, opts); 192 } 193 } 194 printf("Success!\n"); 195 return 0; 196} 197