| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium 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 "base/command_line.h" | |
| 6 #include "base/file_util.h" | |
| 7 #include "base/files/file_path.h" | |
| 8 #include "base/json/json_reader.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/path_service.h" | |
| 11 #include "base/run_loop.h" | |
| 12 #include "base/strings/string_number_conversions.h" | |
| 13 #include "base/strings/stringprintf.h" | |
| 14 #include "base/test/trace_event_analyzer.h" | |
| 15 #include "base/values.h" | |
| 16 #include "chrome/browser/ui/browser.h" | |
| 17 #include "chrome/browser/ui/browser_window.h" | |
| 18 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
| 19 #include "chrome/browser/ui/window_snapshot/window_snapshot.h" | |
| 20 #include "chrome/common/chrome_paths.h" | |
| 21 #include "chrome/common/chrome_switches.h" | |
| 22 #include "chrome/common/net/url_fixer_upper.h" | |
| 23 #include "chrome/test/base/test_switches.h" | |
| 24 #include "chrome/test/base/tracing.h" | |
| 25 #include "chrome/test/base/ui_test_utils.h" | |
| 26 #include "chrome/test/perf/browser_perf_test.h" | |
| 27 #include "chrome/test/perf/perf_test.h" | |
| 28 #include "content/public/browser/web_contents.h" | |
| 29 #include "content/public/browser/web_contents_view.h" | |
| 30 #include "content/public/common/content_switches.h" | |
| 31 #include "content/public/test/browser_test_utils.h" | |
| 32 #include "content/public/test/test_utils.h" | |
| 33 #include "gpu/config/gpu_test_config.h" | |
| 34 #include "net/base/net_util.h" | |
| 35 #include "net/dns/mock_host_resolver.h" | |
| 36 #include "testing/gtest/include/gtest/gtest.h" | |
| 37 #include "testing/perf/perf_test.h" | |
| 38 #include "third_party/skia/include/core/SkBitmap.h" | |
| 39 #include "third_party/skia/include/core/SkColor.h" | |
| 40 #include "ui/gfx/codec/png_codec.h" | |
| 41 #include "ui/gl/gl_switches.h" | |
| 42 #include "url/gurl.h" | |
| 43 | |
| 44 #if defined(OS_WIN) | |
| 45 #include "base/win/windows_version.h" | |
| 46 #endif | |
| 47 | |
| 48 namespace { | |
| 49 | |
| 50 enum RunTestFlags { | |
| 51 kNone = 0, | |
| 52 kInternal = 1 << 0, // Test uses internal test data. | |
| 53 kAllowExternalDNS = 1 << 1, // Test needs external DNS lookup. | |
| 54 kIsGpuCanvasTest = 1 << 2, // Test uses GPU accelerated canvas features. | |
| 55 kIsFlaky = 1 << 3 | |
| 56 }; | |
| 57 | |
| 58 enum ThroughputTestFlags { | |
| 59 kSW = 0, | |
| 60 kGPU = 1 << 0, | |
| 61 kCompositorThread = 1 << 1 | |
| 62 }; | |
| 63 | |
| 64 const int kSpinUpTimeMs = 4 * 1000; | |
| 65 const int kRunTimeMs = 10 * 1000; | |
| 66 const int kIgnoreSomeFrames = 3; | |
| 67 | |
| 68 class ThroughputTest : public BrowserPerfTest { | |
| 69 public: | |
| 70 explicit ThroughputTest(int flags) : | |
| 71 use_gpu_(flags & kGPU), | |
| 72 use_compositor_thread_(flags & kCompositorThread), | |
| 73 spinup_time_ms_(kSpinUpTimeMs), | |
| 74 run_time_ms_(kRunTimeMs) {} | |
| 75 | |
| 76 // This indicates running on GPU bots, not necessarily using the GPU. | |
| 77 bool IsGpuAvailable() const { | |
| 78 return CommandLine::ForCurrentProcess()->HasSwitch("enable-gpu"); | |
| 79 } | |
| 80 | |
| 81 // Parse flags from JSON to control the test behavior. | |
| 82 bool ParseFlagsFromJSON(const base::FilePath& json_dir, | |
| 83 const std::string& json, | |
| 84 int index) { | |
| 85 scoped_ptr<base::Value> root; | |
| 86 root.reset(base::JSONReader::Read(json)); | |
| 87 | |
| 88 base::ListValue* root_list = NULL; | |
| 89 if (!root.get() || !root->GetAsList(&root_list)) { | |
| 90 LOG(ERROR) << "JSON missing root list element"; | |
| 91 return false; | |
| 92 } | |
| 93 | |
| 94 base::DictionaryValue* item = NULL; | |
| 95 if (!root_list->GetDictionary(index, &item)) { | |
| 96 LOG(ERROR) << "index " << index << " not found in JSON"; | |
| 97 return false; | |
| 98 } | |
| 99 | |
| 100 std::string str; | |
| 101 if (item->GetStringASCII("url", &str)) { | |
| 102 gurl_ = GURL(str); | |
| 103 } else if (item->GetStringASCII("file", &str)) { | |
| 104 base::FilePath empty; | |
| 105 gurl_ = URLFixerUpper::FixupRelativeFile(empty, empty.AppendASCII(str)); | |
| 106 } else { | |
| 107 LOG(ERROR) << "missing url or file"; | |
| 108 return false; | |
| 109 } | |
| 110 | |
| 111 if (!gurl_.is_valid()) { | |
| 112 LOG(ERROR) << "invalid url: " << gurl_.possibly_invalid_spec(); | |
| 113 return false; | |
| 114 } | |
| 115 | |
| 116 base::FilePath::StringType cache_dir; | |
| 117 if (item->GetString("local_path", &cache_dir)) | |
| 118 local_cache_path_ = json_dir.Append(cache_dir); | |
| 119 | |
| 120 int num; | |
| 121 if (item->GetInteger("spinup_time", &num)) | |
| 122 spinup_time_ms_ = num * 1000; | |
| 123 if (item->GetInteger("run_time", &num)) | |
| 124 run_time_ms_ = num * 1000; | |
| 125 | |
| 126 base::DictionaryValue* pixel = NULL; | |
| 127 if (item->GetDictionary("wait_pixel", &pixel)) { | |
| 128 int x, y, r, g, b; | |
| 129 base::ListValue* color; | |
| 130 if (pixel->GetInteger("x", &x) && | |
| 131 pixel->GetInteger("y", &y) && | |
| 132 pixel->GetString("op", &str) && | |
| 133 pixel->GetList("color", &color) && | |
| 134 color->GetInteger(0, &r) && | |
| 135 color->GetInteger(1, &g) && | |
| 136 color->GetInteger(2, &b)) { | |
| 137 wait_for_pixel_.reset(new WaitPixel(x, y, r, g, b, str)); | |
| 138 } else { | |
| 139 LOG(ERROR) << "invalid wait_pixel args"; | |
| 140 return false; | |
| 141 } | |
| 142 } | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 // Parse extra-chrome-flags for extra command line flags. | |
| 147 void ParseFlagsFromCommandLine() { | |
| 148 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 149 switches::kExtraChromeFlags)) | |
| 150 return; | |
| 151 CommandLine::StringType flags = | |
| 152 CommandLine::ForCurrentProcess()->GetSwitchValueNative( | |
| 153 switches::kExtraChromeFlags); | |
| 154 if (MatchPattern(flags, FILE_PATH_LITERAL("*.json:*"))) { | |
| 155 CommandLine::StringType::size_type colon_pos = flags.find_last_of(':'); | |
| 156 CommandLine::StringType::size_type num_pos = colon_pos + 1; | |
| 157 int index; | |
| 158 ASSERT_TRUE(base::StringToInt( | |
| 159 flags.substr(num_pos, flags.size() - num_pos), &index)); | |
| 160 base::FilePath filepath(flags.substr(0, colon_pos)); | |
| 161 std::string json; | |
| 162 ASSERT_TRUE(base::ReadFileToString(filepath, &json)); | |
| 163 ASSERT_TRUE(ParseFlagsFromJSON(filepath.DirName(), json, index)); | |
| 164 } else { | |
| 165 gurl_ = GURL(flags); | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 void AllowExternalDNS() { | |
| 170 net::RuleBasedHostResolverProc* resolver = | |
| 171 new net::RuleBasedHostResolverProc(host_resolver()); | |
| 172 resolver->AllowDirectLookup("*"); | |
| 173 host_resolver_override_.reset( | |
| 174 new net::ScopedDefaultHostResolverProc(resolver)); | |
| 175 } | |
| 176 | |
| 177 void ResetAllowExternalDNS() { | |
| 178 host_resolver_override_.reset(); | |
| 179 } | |
| 180 | |
| 181 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | |
| 182 BrowserPerfTest::SetUpCommandLine(command_line); | |
| 183 ParseFlagsFromCommandLine(); | |
| 184 if (!local_cache_path_.value().empty()) { | |
| 185 // If --record-mode is already specified, don't set playback-mode. | |
| 186 if (!command_line->HasSwitch(switches::kRecordMode)) | |
| 187 command_line->AppendSwitch(switches::kPlaybackMode); | |
| 188 command_line->AppendSwitchNative(switches::kDiskCacheDir, | |
| 189 local_cache_path_.value()); | |
| 190 LOG(INFO) << local_cache_path_.value(); | |
| 191 } | |
| 192 // We are measuring throughput, so we don't want any FPS throttling. | |
| 193 command_line->AppendSwitch(switches::kDisableGpuVsync); | |
| 194 command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); | |
| 195 // Enable or disable GPU acceleration. | |
| 196 if (!use_gpu_) { | |
| 197 command_line->AppendSwitch(switches::kDisableAcceleratedCompositing); | |
| 198 command_line->AppendSwitch(switches::kDisableExperimentalWebGL); | |
| 199 command_line->AppendSwitch(switches::kDisableAccelerated2dCanvas); | |
| 200 } | |
| 201 if (use_compositor_thread_) { | |
| 202 ASSERT_TRUE(use_gpu_); | |
| 203 command_line->AppendSwitch(switches::kEnableThreadedCompositing); | |
| 204 } else { | |
| 205 command_line->AppendSwitch(switches::kDisableThreadedCompositing); | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void Wait(int ms) { | |
| 210 base::RunLoop run_loop; | |
| 211 base::MessageLoop::current()->PostDelayedTask( | |
| 212 FROM_HERE, | |
| 213 run_loop.QuitClosure(), | |
| 214 base::TimeDelta::FromMilliseconds(ms)); | |
| 215 content::RunThisRunLoop(&run_loop); | |
| 216 } | |
| 217 | |
| 218 // Take snapshot of the current tab, encode it as PNG, and save to a SkBitmap. | |
| 219 bool TabSnapShotToImage(SkBitmap* bitmap) { | |
| 220 CHECK(bitmap); | |
| 221 std::vector<unsigned char> png; | |
| 222 | |
| 223 gfx::Rect root_bounds = browser()->window()->GetBounds(); | |
| 224 gfx::Rect tab_contents_bounds; | |
| 225 browser()->tab_strip_model()->GetActiveWebContents()->GetView()-> | |
| 226 GetContainerBounds(&tab_contents_bounds); | |
| 227 | |
| 228 gfx::Rect snapshot_bounds(tab_contents_bounds.x() - root_bounds.x(), | |
| 229 tab_contents_bounds.y() - root_bounds.y(), | |
| 230 tab_contents_bounds.width(), | |
| 231 tab_contents_bounds.height()); | |
| 232 | |
| 233 gfx::NativeWindow native_window = browser()->window()->GetNativeWindow(); | |
| 234 if (!chrome::GrabWindowSnapshotForUser(native_window, &png, | |
| 235 snapshot_bounds)) { | |
| 236 LOG(ERROR) << "browser::GrabWindowSnapShot() failed"; | |
| 237 return false; | |
| 238 } | |
| 239 | |
| 240 if (!gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&*png.begin()), | |
| 241 png.size(), bitmap)) { | |
| 242 LOG(ERROR) << "Decode PNG to a SkBitmap failed"; | |
| 243 return false; | |
| 244 } | |
| 245 return true; | |
| 246 } | |
| 247 | |
| 248 // Check a pixel color every second until it passes test. | |
| 249 void WaitForPixelColor() { | |
| 250 if (wait_for_pixel_.get()) { | |
| 251 bool success = false; | |
| 252 do { | |
| 253 SkBitmap bitmap; | |
| 254 ASSERT_TRUE(TabSnapShotToImage(&bitmap)); | |
| 255 success = wait_for_pixel_->IsDone(bitmap); | |
| 256 if (!success) | |
| 257 Wait(1000); | |
| 258 } while (!success); | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 // flags is one or more of RunTestFlags OR'd together. | |
| 263 void RunTest(const std::string& test_name, int flags) { | |
| 264 // Set path to test html. | |
| 265 base::FilePath test_path; | |
| 266 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_path)); | |
| 267 test_path = test_path.Append(FILE_PATH_LITERAL("perf")); | |
| 268 if (flags & kInternal) | |
| 269 test_path = test_path.Append(FILE_PATH_LITERAL("private")); | |
| 270 test_path = test_path.Append(FILE_PATH_LITERAL("rendering")); | |
| 271 test_path = test_path.Append(FILE_PATH_LITERAL("throughput")); | |
| 272 test_path = test_path.AppendASCII(test_name); | |
| 273 test_path = test_path.Append(FILE_PATH_LITERAL("index.html")); | |
| 274 ASSERT_TRUE(base::PathExists(test_path)) | |
| 275 << "Missing test file: " << test_path.value(); | |
| 276 | |
| 277 gurl_ = net::FilePathToFileURL(test_path); | |
| 278 RunTestWithURL(test_name, flags); | |
| 279 } | |
| 280 | |
| 281 // flags is one or more of RunTestFlags OR'd together. | |
| 282 void RunCanvasBenchTest(const std::string& test_name, int flags) { | |
| 283 // Set path to test html. | |
| 284 base::FilePath test_path; | |
| 285 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_path)); | |
| 286 test_path = test_path.Append(FILE_PATH_LITERAL("perf")); | |
| 287 test_path = test_path.Append(FILE_PATH_LITERAL("canvas_bench")); | |
| 288 test_path = test_path.AppendASCII(test_name + ".html"); | |
| 289 ASSERT_TRUE(base::PathExists(test_path)) | |
| 290 << "Missing test file: " << test_path.value(); | |
| 291 | |
| 292 gurl_ = net::FilePathToFileURL(test_path); | |
| 293 RunTestWithURL(test_name, flags); | |
| 294 } | |
| 295 | |
| 296 // flags is one or more of RunTestFlags OR'd together. | |
| 297 void RunTestWithURL(int flags) { | |
| 298 RunTestWithURL(gurl_.possibly_invalid_spec(), flags); | |
| 299 } | |
| 300 | |
| 301 // flags is one or more of RunTestFlags OR'd together. | |
| 302 void RunTestWithURL(const std::string& test_name, int flags) { | |
| 303 using trace_analyzer::Query; | |
| 304 using trace_analyzer::TraceAnalyzer; | |
| 305 using trace_analyzer::TraceEventVector; | |
| 306 | |
| 307 #if defined(OS_WIN) | |
| 308 if (use_gpu_ && (flags & kIsGpuCanvasTest) && | |
| 309 base::win::OSInfo::GetInstance()->version() == base::win::VERSION_XP) { | |
| 310 // crbug.com/128208 | |
| 311 LOG(WARNING) << "Test skipped: GPU canvas tests do not run on XP."; | |
| 312 return; | |
| 313 } | |
| 314 #endif | |
| 315 | |
| 316 if (use_gpu_ && !IsGpuAvailable()) { | |
| 317 LOG(WARNING) << "Test skipped: requires gpu. Pass --enable-gpu on the " | |
| 318 "command line if use of GPU is desired."; | |
| 319 return; | |
| 320 } | |
| 321 | |
| 322 if (flags & kAllowExternalDNS) | |
| 323 AllowExternalDNS(); | |
| 324 | |
| 325 std::string json_events; | |
| 326 TraceEventVector events_sw, events_gpu; | |
| 327 scoped_ptr<TraceAnalyzer> analyzer; | |
| 328 | |
| 329 LOG(INFO) << gurl_.possibly_invalid_spec(); | |
| 330 ui_test_utils::NavigateToURLWithDisposition( | |
| 331 browser(), gurl_, CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); | |
| 332 content::WaitForLoadStop( | |
| 333 browser()->tab_strip_model()->GetActiveWebContents()); | |
| 334 | |
| 335 // Let the test spin up. | |
| 336 LOG(INFO) << "Spinning up test..."; | |
| 337 ASSERT_TRUE(tracing::BeginTracing("test_gpu")); | |
| 338 Wait(spinup_time_ms_); | |
| 339 ASSERT_TRUE(tracing::EndTracing(&json_events)); | |
| 340 | |
| 341 // Wait for a pixel color to change (if requested). | |
| 342 WaitForPixelColor(); | |
| 343 | |
| 344 // Check if GPU is rendering: | |
| 345 analyzer.reset(TraceAnalyzer::Create(json_events)); | |
| 346 bool ran_on_gpu = (analyzer->FindEvents( | |
| 347 Query::EventNameIs("SwapBuffers"), &events_gpu) > 0u); | |
| 348 LOG(INFO) << "Mode: " << (ran_on_gpu ? "GPU" : "Software"); | |
| 349 EXPECT_EQ(use_gpu_, ran_on_gpu); | |
| 350 | |
| 351 // Let the test run for a while. | |
| 352 LOG(INFO) << "Running test..."; | |
| 353 ASSERT_TRUE(tracing::BeginTracing("test_fps")); | |
| 354 Wait(run_time_ms_); | |
| 355 ASSERT_TRUE(tracing::EndTracing(&json_events)); | |
| 356 | |
| 357 // Search for frame ticks. We look for both SW and GPU frame ticks so that | |
| 358 // the test can verify that only one or the other are found. | |
| 359 analyzer.reset(TraceAnalyzer::Create(json_events)); | |
| 360 Query query_sw = Query::EventNameIs("TestFrameTickSW"); | |
| 361 Query query_gpu = Query::EventNameIs("TestFrameTickGPU"); | |
| 362 analyzer->FindEvents(query_sw, &events_sw); | |
| 363 analyzer->FindEvents(query_gpu, &events_gpu); | |
| 364 TraceEventVector* frames = NULL; | |
| 365 if (use_gpu_) { | |
| 366 frames = &events_gpu; | |
| 367 EXPECT_EQ(0u, events_sw.size()); | |
| 368 } else { | |
| 369 frames = &events_sw; | |
| 370 EXPECT_EQ(0u, events_gpu.size()); | |
| 371 } | |
| 372 if (!(flags & kIsFlaky)) { | |
| 373 ASSERT_GT(frames->size(), 20u); | |
| 374 } | |
| 375 // Cull a few leading and trailing events as they might be unreliable. | |
| 376 TraceEventVector rate_events(frames->begin() + kIgnoreSomeFrames, | |
| 377 frames->end() - kIgnoreSomeFrames); | |
| 378 trace_analyzer::RateStats stats; | |
| 379 ASSERT_TRUE(GetRateStats(rate_events, &stats, NULL)); | |
| 380 LOG(INFO) << "FPS = " << 1000000.0 / stats.mean_us; | |
| 381 | |
| 382 // Print perf results. | |
| 383 double mean_ms = stats.mean_us / 1000.0; | |
| 384 double std_dev_ms = stats.standard_deviation_us / 1000.0; | |
| 385 std::string trace_name = use_compositor_thread_? "gpu_thread" : | |
| 386 ran_on_gpu ? "gpu" : "software"; | |
| 387 std::string mean_and_error = base::StringPrintf("%f,%f", mean_ms, | |
| 388 std_dev_ms); | |
| 389 perf_test::PrintResultMeanAndError(test_name, | |
| 390 std::string(), | |
| 391 trace_name, | |
| 392 mean_and_error, | |
| 393 "frame_time", | |
| 394 true); | |
| 395 | |
| 396 if (flags & kAllowExternalDNS) | |
| 397 ResetAllowExternalDNS(); | |
| 398 | |
| 399 // Close the tab so that we can quit without timing out during the | |
| 400 // wait-for-idle stage in browser_test framework. | |
| 401 browser()->tab_strip_model()->GetActiveWebContents()->Close(); | |
| 402 } | |
| 403 | |
| 404 private: | |
| 405 // WaitPixel checks a color against the color at the given pixel coordinates | |
| 406 // of an SkBitmap. | |
| 407 class WaitPixel { | |
| 408 enum Operator { | |
| 409 EQUAL, | |
| 410 NOT_EQUAL | |
| 411 }; | |
| 412 public: | |
| 413 WaitPixel(int x, int y, int r, int g, int b, const std::string& op) : | |
| 414 x_(x), y_(y), r_(r), g_(g), b_(b) { | |
| 415 if (op == "!=") | |
| 416 op_ = EQUAL; | |
| 417 else if (op == "==") | |
| 418 op_ = NOT_EQUAL; | |
| 419 else | |
| 420 CHECK(false) << "op value \"" << op << "\" is not supported"; | |
| 421 } | |
| 422 bool IsDone(const SkBitmap& bitmap) { | |
| 423 SkColor color = bitmap.getColor(x_, y_); | |
| 424 int r = SkColorGetR(color); | |
| 425 int g = SkColorGetG(color); | |
| 426 int b = SkColorGetB(color); | |
| 427 LOG(INFO) << "color(" << x_ << "," << y_ << "): " << | |
| 428 r << "," << g << "," << b; | |
| 429 switch (op_) { | |
| 430 case EQUAL: | |
| 431 return r != r_ || g != g_ || b != b_; | |
| 432 case NOT_EQUAL: | |
| 433 return r == r_ && g == g_ && b == b_; | |
| 434 default: | |
| 435 return false; | |
| 436 } | |
| 437 } | |
| 438 private: | |
| 439 int x_; | |
| 440 int y_; | |
| 441 int r_; | |
| 442 int g_; | |
| 443 int b_; | |
| 444 Operator op_; | |
| 445 }; | |
| 446 | |
| 447 bool use_gpu_; | |
| 448 bool use_compositor_thread_; | |
| 449 int spinup_time_ms_; | |
| 450 int run_time_ms_; | |
| 451 base::FilePath local_cache_path_; | |
| 452 GURL gurl_; | |
| 453 scoped_ptr<net::ScopedDefaultHostResolverProc> host_resolver_override_; | |
| 454 scoped_ptr<WaitPixel> wait_for_pixel_; | |
| 455 }; | |
| 456 | |
| 457 // For running tests on GPU: | |
| 458 class ThroughputTestGPU : public ThroughputTest { | |
| 459 public: | |
| 460 ThroughputTestGPU() : ThroughputTest(kGPU) {} | |
| 461 }; | |
| 462 | |
| 463 // For running tests on GPU with the compositor thread: | |
| 464 class ThroughputTestThread : public ThroughputTest { | |
| 465 public: | |
| 466 ThroughputTestThread() : ThroughputTest(kGPU | kCompositorThread) {} | |
| 467 }; | |
| 468 | |
| 469 // For running tests on Software: | |
| 470 class ThroughputTestSW : public ThroughputTest { | |
| 471 public: | |
| 472 ThroughputTestSW() : ThroughputTest(kSW) {} | |
| 473 }; | |
| 474 | |
| 475 //////////////////////////////////////////////////////////////////////////////// | |
| 476 /// Tests | |
| 477 | |
| 478 #if defined(OS_WIN) && defined(USE_AURA) | |
| 479 // crbug.com/292897 | |
| 480 #define MAYBE(x) DISABLED_ ## x | |
| 481 #else | |
| 482 #define MAYBE(x) x | |
| 483 #endif | |
| 484 | |
| 485 // Run this test with a URL on the command line: | |
| 486 // performance_browser_tests --gtest_also_run_disabled_tests --enable-gpu | |
| 487 // --gtest_filter=ThroughputTest*URL --extra-chrome-flags=http://... | |
| 488 // or, specify a json file with a list of tests, and the index of the test: | |
| 489 // --extra-chrome-flags=path/to/tests.json:0 | |
| 490 // The json format is an array of tests, for example: | |
| 491 // [ | |
| 492 // {"url":"http://...", | |
| 493 // "spinup_time":5, | |
| 494 // "run_time":10, | |
| 495 // "local_path":"path/to/disk-cache-dir", | |
| 496 // "wait_pixel":{"x":10,"y":10,"op":"!=","color":[24,24,24]}}, | |
| 497 // {"url":"http://..."} | |
| 498 // ] | |
| 499 // The only required argument is url. If local_path is set, the test goes into | |
| 500 // playback-mode and only loads files from the specified cache. If wait_pixel is | |
| 501 // specified, then after spinup_time the test waits for the color at the | |
| 502 // specified pixel coordinate to match the given color with the given operator. | |
| 503 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, DISABLED_TestURL) { | |
| 504 RunTestWithURL(kAllowExternalDNS); | |
| 505 } | |
| 506 | |
| 507 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, DISABLED_TestURL) { | |
| 508 RunTestWithURL(kAllowExternalDNS); | |
| 509 } | |
| 510 | |
| 511 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(Particles)) { | |
| 512 RunTest("particles", kInternal); | |
| 513 } | |
| 514 | |
| 515 IN_PROC_BROWSER_TEST_F(ThroughputTestThread, MAYBE(Particles)) { | |
| 516 RunTest("particles", kInternal); | |
| 517 } | |
| 518 | |
| 519 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, MAYBE(CanvasDemoSW)) { | |
| 520 RunTest("canvas-demo", kInternal); | |
| 521 } | |
| 522 | |
| 523 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(CanvasDemoGPU)) { | |
| 524 RunTest("canvas-demo", kInternal | kIsGpuCanvasTest); | |
| 525 } | |
| 526 | |
| 527 IN_PROC_BROWSER_TEST_F(ThroughputTestThread, MAYBE(CanvasDemoGPU)) { | |
| 528 RunTest("canvas-demo", kInternal | kIsGpuCanvasTest); | |
| 529 } | |
| 530 | |
| 531 // CompositingHugeDivSW timed out on Mac Intel Release GPU bot | |
| 532 // See crbug.com/114781 | |
| 533 // Stopped producing results in SW: crbug.com/127621 | |
| 534 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, DISABLED_CompositingHugeDivSW) { | |
| 535 RunTest("compositing_huge_div", kNone); | |
| 536 } | |
| 537 | |
| 538 // Failing with insufficient frames: crbug.com/127595 | |
| 539 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, DISABLED_CompositingHugeDivGPU) { | |
| 540 RunTest("compositing_huge_div", kNone); | |
| 541 } | |
| 542 | |
| 543 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, MAYBE(DrawImageShadowSW)) { | |
| 544 RunTest("canvas2d_balls_with_shadow", kNone); | |
| 545 } | |
| 546 | |
| 547 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(DrawImageShadowGPU)) { | |
| 548 // TODO(junov): Fix test flakiness crbug.com/272383 | |
| 549 RunTest("canvas2d_balls_with_shadow", kNone | kIsGpuCanvasTest | kIsFlaky); | |
| 550 } | |
| 551 | |
| 552 // Intermittent failure, should be fixed by converting to telemetry. | |
| 553 // See crbug.com/276500 for more details. | |
| 554 IN_PROC_BROWSER_TEST_F(ThroughputTestThread, DISABLED_DrawImageShadowGPU) { | |
| 555 // TODO(junov): Fix test flakiness crbug.com/272383 | |
| 556 RunTest("canvas2d_balls_with_shadow", kNone | kIsGpuCanvasTest | kIsFlaky); | |
| 557 } | |
| 558 | |
| 559 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, MAYBE(CanvasToCanvasDrawSW)) { | |
| 560 if (IsGpuAvailable() && | |
| 561 gpu::GPUTestBotConfig::CurrentConfigMatches("MAC AMD")) | |
| 562 return; | |
| 563 RunTest("canvas2d_balls_draw_from_canvas", kNone); | |
| 564 } | |
| 565 | |
| 566 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(CanvasToCanvasDrawGPU)) { | |
| 567 if (IsGpuAvailable() && | |
| 568 gpu::GPUTestBotConfig::CurrentConfigMatches("MAC AMD")) | |
| 569 return; | |
| 570 RunTest("canvas2d_balls_draw_from_canvas", kNone | kIsGpuCanvasTest); | |
| 571 } | |
| 572 | |
| 573 // Failing on windows GPU bots: crbug.com/255192 | |
| 574 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, DISABLED_CanvasTextSW) { | |
| 575 if (IsGpuAvailable() && | |
| 576 gpu::GPUTestBotConfig::CurrentConfigMatches("MAC AMD")) | |
| 577 return; | |
| 578 RunTest("canvas2d_balls_text", kNone); | |
| 579 } | |
| 580 | |
| 581 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(CanvasTextGPU)) { | |
| 582 RunTest("canvas2d_balls_text", kNone | kIsGpuCanvasTest); | |
| 583 } | |
| 584 | |
| 585 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, MAYBE(CanvasFillPathSW)) { | |
| 586 RunTest("canvas2d_balls_fill_path", kNone); | |
| 587 } | |
| 588 | |
| 589 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(CanvasFillPathGPU)) { | |
| 590 RunTest("canvas2d_balls_fill_path", kNone | kIsGpuCanvasTest); | |
| 591 } | |
| 592 | |
| 593 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, MAYBE(CanvasSingleImageSW)) { | |
| 594 RunCanvasBenchTest("single_image", kNone); | |
| 595 } | |
| 596 | |
| 597 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(CanvasSingleImageGPU)) { | |
| 598 if (IsGpuAvailable() && | |
| 599 gpu::GPUTestBotConfig::CurrentConfigMatches("MAC AMD")) | |
| 600 return; | |
| 601 RunCanvasBenchTest("single_image", kNone | kIsGpuCanvasTest); | |
| 602 } | |
| 603 | |
| 604 IN_PROC_BROWSER_TEST_F(ThroughputTestSW, MAYBE(CanvasManyImagesSW)) { | |
| 605 RunCanvasBenchTest("many_images", kNone); | |
| 606 } | |
| 607 | |
| 608 IN_PROC_BROWSER_TEST_F(ThroughputTestGPU, MAYBE(CanvasManyImagesGPU)) { | |
| 609 RunCanvasBenchTest("many_images", kNone | kIsGpuCanvasTest); | |
| 610 } | |
| 611 | |
| 612 IN_PROC_BROWSER_TEST_F(ThroughputTestThread, MAYBE(CanvasManyImagesGPU)) { | |
| 613 RunCanvasBenchTest("many_images", kNone | kIsGpuCanvasTest); | |
| 614 } | |
| 615 | |
| 616 } // namespace | |
| OLD | NEW |