1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <gflags/gflags.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <ctime> 10 11 #include "base/logging.h" 12 #include "base/strings/string_split.h" 13 #include "base/strings/string_util.h" 14 15 #include "glinterface.h" 16 #include "main.h" 17 #include "utils.h" 18 19 #include "all_tests.h" 20 #include "testbase.h" 21 22 using std::string; 23 using std::vector; 24 25 DEFINE_int32(duration, 0, 26 "Run all tests again and again in a loop for at least this many seconds."); 27 DEFINE_string(tests, "", 28 "Colon-separated list of tests to run; all tests if omitted."); 29 DEFINE_string(blacklist, "", "colon-separated list of tests to disable"); 30 DEFINE_bool(hasty, false, 31 "Run a smaller set of tests with less accurate results. " 32 "Useful for running in BVT or debugging a failure. Implies notemp"); 33 DEFINE_bool(list, false, "List available tests"); 34 DEFINE_bool(notemp, false, "Skip temperature checking"); 35 DEFINE_bool(verbose, false, "Print extra debugging messages"); 36 37 bool g_verbose; 38 GLint g_max_texture_size; 39 bool g_hasty; 40 bool g_notemp; 41 42 bool test_is_enabled(glbench::TestBase* test, 43 const vector<string>& enabled_tests) { 44 if (enabled_tests.empty()) 45 return true; 46 47 const char* test_name = test->Name(); 48 for (vector<string>::const_iterator i = enabled_tests.begin(); 49 i != enabled_tests.end(); ++i) { 50 // This is not very precise, but will do until there's a need for something 51 // more flexible. 52 if (strstr(test_name, i->c_str())) 53 return true; 54 } 55 56 return false; 57 } 58 59 bool test_is_disabled(glbench::TestBase* test, 60 const vector<string>& disabled_tests) { 61 if (disabled_tests.empty()) 62 return false; 63 64 const char* test_name = test->Name(); 65 for (vector<string>::const_iterator i = disabled_tests.begin(); 66 i != disabled_tests.end(); ++i) { 67 // This is not very precise, but will do until there's a need for something 68 // more flexible. 69 if (strstr(test_name, i->c_str())) 70 return true; 71 } 72 73 return false; 74 } 75 76 void printDateTime(void) { 77 struct tm *ttime; 78 time_t tm = time(0); 79 char time_string[64]; 80 ttime = localtime(&tm); 81 strftime(time_string, 63, "%c",ttime); 82 printf("# DateTime: %s\n", time_string); 83 } 84 85 bool PassesSanityCheck(void) { 86 GLint size[2]; 87 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, size); 88 printf("# MAX_VIEWPORT_DIMS=(%d, %d)\n", size[0], size[1]); 89 if (size[0] < g_width || size[1] < g_height) { 90 printf("# Error: MAX_VIEWPORT_DIMS=(%d, %d) are too small.\n", 91 size[0], size[1]); 92 return false; 93 } 94 glGetIntegerv(GL_MAX_TEXTURE_SIZE, size); 95 printf("# GL_MAX_TEXTURE_SIZE=%d\n", size[0]); 96 if (size[0] < g_width || size[0] < g_height) { 97 printf("# Error: MAX_TEXTURE_SIZE=%d is too small.\n", 98 size[0]); 99 return false; 100 } 101 g_max_texture_size = size[0]; 102 103 return true; 104 } 105 106 int main(int argc, char *argv[]) { 107 SetBasePathFromArgv0(argv[0], "src"); 108 google::ParseCommandLineFlags(&argc, &argv, false); 109 110 g_verbose = FLAGS_verbose; 111 112 g_main_gl_interface.reset(GLInterface::Create()); 113 if (!g_main_gl_interface->Init()) { 114 printf("# Error: Failed to initialize %s.\n", argv[0]); 115 return 1; 116 } 117 118 printf("# board_id: %s - %s\n", 119 glGetString(GL_VENDOR), glGetString(GL_RENDERER)); 120 if (!PassesSanityCheck()) 121 return 1; 122 g_main_gl_interface->Cleanup(); 123 124 if (argc == 1) { 125 printf("# Usage: %s [-save [-outdir=<directory>]] to save images\n", argv[0]); 126 } else { 127 printf("# Running: "); 128 for (int i = 0; i < argc; i++) printf("%s ", argv[i]); 129 printf("\n"); 130 } 131 printDateTime(); 132 133 g_hasty = FLAGS_hasty; 134 g_notemp = FLAGS_notemp || g_hasty; 135 136 if (!g_notemp) 137 g_initial_temperature = GetMachineTemperature(); 138 139 vector<string> enabled_tests = 140 base::SplitString(FLAGS_tests, ":", base::TRIM_WHITESPACE, 141 base::SPLIT_WANT_ALL); 142 vector<string> disabled_tests = 143 base::SplitString(FLAGS_blacklist, ":", base::TRIM_WHITESPACE, 144 base::SPLIT_WANT_ALL); 145 146 glbench::TestBase* tests[] = { 147 // Please add new tests at the end of this list as tests are known to bleed 148 // state. Reordering them or inserting a new test may cause a change in the 149 // output images and MD5 causing graphics_GLBench failures. 150 // TODO(ihf): Fix this. 151 glbench::GetSwapTest(), 152 glbench::GetContextTest(), 153 glbench::GetClearTest(), 154 glbench::GetFillRateTest(), 155 glbench::GetWindowManagerCompositingTest(false), 156 glbench::GetWindowManagerCompositingTest(true), 157 glbench::GetTriangleSetupTest(), 158 glbench::GetYuvToRgbTest(), 159 glbench::GetReadPixelTest(), 160 glbench::GetAttributeFetchShaderTest(), 161 glbench::GetVaryingsAndDdxyShaderTest(), 162 glbench::GetTextureReuseTest(), 163 glbench::GetTextureUpdateTest(), 164 glbench::GetTextureUploadTest(), 165 glbench::GetFboFillRateTest(), 166 }; 167 168 if (FLAGS_list) { 169 for (unsigned int i = 0; i < arraysize(tests); i++) 170 printf("%s\n", tests[i]->Name()); 171 return 0; 172 } 173 174 uint64_t done = GetUTime() + 1000000ULL * FLAGS_duration; 175 do { 176 for (unsigned int i = 0; i < arraysize(tests); i++) { 177 if (!test_is_enabled(tests[i], enabled_tests) || 178 test_is_disabled(tests[i], disabled_tests)) 179 continue; 180 if (!g_main_gl_interface->Init()) { 181 printf("Initialize failed\n"); 182 return 1; 183 } 184 glbench::ClearBuffers(); 185 tests[i]->Run(); 186 g_main_gl_interface->Cleanup(); 187 } 188 } while (GetUTime() < done); 189 190 for (unsigned int i = 0; i < arraysize(tests); i++) { 191 delete tests[i]; 192 tests[i] = NULL; 193 } 194 195 printDateTime(); 196 // Signal to harness that we finished normally. 197 printf("@TEST_END\n"); 198 199 return 0; 200 } 201