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 22using std::string; 23using std::vector; 24 25DEFINE_int32(duration, 0, 26 "Run all tests again and again in a loop for at least this many seconds."); 27DEFINE_string(tests, "", 28 "Colon-separated list of tests to run; all tests if omitted."); 29DEFINE_string(blacklist, "", "colon-separated list of tests to disable"); 30DEFINE_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"); 33DEFINE_bool(list, false, "List available tests"); 34DEFINE_bool(notemp, false, "Skip temperature checking"); 35DEFINE_bool(verbose, false, "Print extra debugging messages"); 36 37bool g_verbose; 38GLint g_max_texture_size; 39bool g_hasty; 40bool g_notemp; 41 42bool 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 59bool 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 76void 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 85bool 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 106int 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