| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
| 7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 // Don't analyze end frames that may be inaccurate. | 105 // Don't analyze end frames that may be inaccurate. |
| 106 const int kIgnoreEndFrames = 4; | 106 const int kIgnoreEndFrames = 4; |
| 107 // Minimum frames to produce an answer. | 107 // Minimum frames to produce an answer. |
| 108 const int kMinimumFramesForAnalysis = 5; | 108 const int kMinimumFramesForAnalysis = 5; |
| 109 | 109 |
| 110 class LatencyTest | 110 class LatencyTest |
| 111 : public BrowserPerfTest, | 111 : public BrowserPerfTest, |
| 112 public ::testing::WithParamInterface<int> { | 112 public ::testing::WithParamInterface<int> { |
| 113 public: | 113 public: |
| 114 explicit LatencyTest(LatencyTestMode mode) : | 114 explicit LatencyTest(LatencyTestMode mode) : |
| 115 query_instant_(Query::EventPhase() == | 115 query_instant_(Query::EventPhaseIs(TRACE_EVENT_PHASE_INSTANT)), |
| 116 Query::Phase(TRACE_EVENT_PHASE_INSTANT)), | |
| 117 // These queries are initialized in RunTest. | 116 // These queries are initialized in RunTest. |
| 118 query_begin_swaps_(Query::Bool(false)), | 117 query_begin_swaps_(Query::Bool(false)), |
| 119 query_end_swaps_(Query::Bool(false)), | 118 query_end_swaps_(Query::Bool(false)), |
| 120 query_inputs_(Query::Bool(false)), | 119 query_inputs_(Query::Bool(false)), |
| 121 query_blits_(Query::Bool(false)), | 120 query_blits_(Query::Bool(false)), |
| 122 query_clears_(Query::Bool(false)), | 121 query_clears_(Query::Bool(false)), |
| 123 mouse_x_(0), | 122 mouse_x_(0), |
| 124 tab_width_(0), | 123 tab_width_(0), |
| 125 mode_(mode), | 124 mode_(mode), |
| 126 delay_time_us_(0), | 125 delay_time_us_(0), |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 272 |
| 274 #if defined(OS_WIN) | 273 #if defined(OS_WIN) |
| 275 // Latency test doesn't work on WinXP. crbug.com/128066 | 274 // Latency test doesn't work on WinXP. crbug.com/128066 |
| 276 if (base::win::OSInfo::GetInstance()->version() == base::win::VERSION_XP) | 275 if (base::win::OSInfo::GetInstance()->version() == base::win::VERSION_XP) |
| 277 return; | 276 return; |
| 278 #endif | 277 #endif |
| 279 | 278 |
| 280 // Construct queries for searching trace events via TraceAnalyzer. | 279 // Construct queries for searching trace events via TraceAnalyzer. |
| 281 if (use_gpu_) { | 280 if (use_gpu_) { |
| 282 query_begin_swaps_ = query_instant_ && | 281 query_begin_swaps_ = query_instant_ && |
| 283 Query::EventName() == Query::String("SwapBuffersLatency") && | 282 Query::EventNameIs("SwapBuffersLatency") && |
| 284 Query::EventArg("width") != Query::Int(kWebGLCanvasWidth); | 283 Query::EventArg("width") != Query::Int(kWebGLCanvasWidth); |
| 285 query_end_swaps_ = query_instant_ && | 284 query_end_swaps_ = query_instant_ && |
| 286 Query::EventName() == Query::String("CompositorSwapBuffersComplete"); | 285 Query::EventNameIs("CompositorSwapBuffersComplete"); |
| 287 } else if (mode_ == kSoftware) { | 286 } else if (mode_ == kSoftware) { |
| 288 // Software updates need to have x=0 and y=0 to contain the input color. | 287 // Software updates need to have x=0 and y=0 to contain the input color. |
| 289 query_begin_swaps_ = query_instant_ && | 288 query_begin_swaps_ = query_instant_ && |
| 290 Query::EventName() == Query::String("UpdateRect") && | 289 Query::EventNameIs("UpdateRect") && |
| 291 Query::EventArg("x+y") == Query::Int(0); | 290 Query::EventArg("x+y") == Query::Int(0); |
| 292 query_end_swaps_ = query_instant_ && | 291 query_end_swaps_ = query_instant_ && |
| 293 Query::EventName() == Query::String("UpdateRectComplete") && | 292 Query::EventNameIs("UpdateRectComplete") && |
| 294 Query::EventArg("x+y") == Query::Int(0); | 293 Query::EventArg("x+y") == Query::Int(0); |
| 295 } | 294 } |
| 296 query_inputs_ = query_instant_ && | 295 query_inputs_ = query_instant_ && |
| 297 Query::EventName() == Query::String("MouseEventBegin"); | 296 Query::EventNameIs("MouseEventBegin"); |
| 298 query_blits_ = query_instant_ && | 297 query_blits_ = query_instant_ && |
| 299 Query::EventName() == Query::String("DoBlit") && | 298 Query::EventNameIs("DoBlit") && |
| 300 Query::EventArg("width") == Query::Int(kWebGLCanvasWidth); | 299 Query::EventArg("width") == Query::Int(kWebGLCanvasWidth); |
| 301 query_clears_ = query_instant_ && | 300 query_clears_ = query_instant_ && |
| 302 Query::EventName() == Query::String("DoClear") && | 301 Query::EventNameIs("DoClear") && |
| 303 Query::EventArg("green") == Query::Int(kClearColorGreen); | 302 Query::EventArg("green") == Query::Int(kClearColorGreen); |
| 304 Query query_width_swaps = Query::Bool(false); | 303 Query query_width_swaps = Query::Bool(false); |
| 305 if (use_gpu_) { | 304 if (use_gpu_) { |
| 306 query_width_swaps = query_begin_swaps_; | 305 query_width_swaps = query_begin_swaps_; |
| 307 } else if (mode_ == kSoftware) { | 306 } else if (mode_ == kSoftware) { |
| 308 query_width_swaps = query_instant_ && | 307 query_width_swaps = query_instant_ && |
| 309 Query::EventName() == Query::String("UpdateRectWidth") && | 308 Query::EventNameIs("UpdateRectWidth") && |
| 310 Query::EventArg("width") > Query::Int(kWebGLCanvasWidth); | 309 Query::EventArg("width") > Query::Int(kWebGLCanvasWidth); |
| 311 } | 310 } |
| 312 | 311 |
| 313 // Set path to test html. | 312 // Set path to test html. |
| 314 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_path_)); | 313 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_path_)); |
| 315 test_path_ = test_path_.Append(FILE_PATH_LITERAL("perf")); | 314 test_path_ = test_path_.Append(FILE_PATH_LITERAL("perf")); |
| 316 test_path_ = test_path_.Append(FILE_PATH_LITERAL("latency_suite.html")); | 315 test_path_ = test_path_.Append(FILE_PATH_LITERAL("latency_suite.html")); |
| 317 ASSERT_TRUE(file_util::PathExists(test_path_)) | 316 ASSERT_TRUE(file_util::PathExists(test_path_)) |
| 318 << "Missing test file: " << test_path_.value(); | 317 << "Missing test file: " << test_path_.value(); |
| 319 | 318 |
| 320 // Run once with defaults to measure the frame times. | 319 // Run once with defaults to measure the frame times. |
| 321 delay_time_us_ = 0; | 320 delay_time_us_ = 0; |
| 322 // kNumFrames may be very high, but we only need a few frames to measure | 321 // kNumFrames may be very high, but we only need a few frames to measure |
| 323 // average frame times. | 322 // average frame times. |
| 324 num_frames_ = 30; | 323 num_frames_ = 30; |
| 325 int initial_flags = 0; | 324 int initial_flags = 0; |
| 326 if (mode_ == kSoftware) { | 325 if (mode_ == kSoftware) { |
| 327 // For the first run, run software with kPaintHeavy (which toggles the | 326 // For the first run, run software with kPaintHeavy (which toggles the |
| 328 // background color every frame) to force an update each RAF. Otherwise it | 327 // background color every frame) to force an update each RAF. Otherwise it |
| 329 // won't trigger an UpdateRect each frame and we won't be able to measure | 328 // won't trigger an UpdateRect each frame and we won't be able to measure |
| 330 // framerate, because there are no inputs during the first run. | 329 // framerate, because there are no inputs during the first run. |
| 331 initial_flags = static_cast<int>(kPaintHeavy); | 330 initial_flags = static_cast<int>(kPaintHeavy); |
| 332 } | 331 } |
| 333 RunTestInternal(GetUrl(initial_flags), false, 0); | 332 RunTestInternal(GetUrl(initial_flags), false, 0); |
| 334 | 333 |
| 335 // Get width of tab so that we know the limit of x coordinates for the | 334 // Get width of tab so that we know the limit of x coordinates for the |
| 336 // injected mouse inputs. | 335 // injected mouse inputs. |
| 337 const TraceEvent* swap_event = analyzer_->FindOneEvent(query_width_swaps); | 336 const TraceEvent* swap_event = analyzer_->FindFirstOf(query_width_swaps); |
| 338 ASSERT_TRUE(swap_event); | 337 ASSERT_TRUE(swap_event); |
| 339 tab_width_ = swap_event->GetKnownArgAsInt("width"); | 338 tab_width_ = swap_event->GetKnownArgAsInt("width"); |
| 340 // Keep printf output clean by limiting input coords to three digits: | 339 // Keep printf output clean by limiting input coords to three digits: |
| 341 tab_width_ = (tab_width_ < 1000) ? tab_width_ : 999; | 340 tab_width_ = (tab_width_ < 1000) ? tab_width_ : 999; |
| 342 // Sanity check the tab_width -- it should be more than 100 pixels. | 341 // Sanity check the tab_width -- it should be more than 100 pixels. |
| 343 EXPECT_GT(tab_width_, 100); | 342 EXPECT_GT(tab_width_, 100); |
| 344 | 343 |
| 345 int mean_frame_time_us = 0; | 344 int mean_frame_time_us = 0; |
| 346 GetMeanFrameTimeMicros(&mean_frame_time_us); | 345 GetMeanFrameTimeMicros(&mean_frame_time_us); |
| 347 if (verbose_) | 346 if (verbose_) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 365 printf("Mode: %s\n", GetUrlModeString(i).c_str()); | 364 printf("Mode: %s\n", GetUrlModeString(i).c_str()); |
| 366 printf("URL: %s\n", url.c_str()); | 365 printf("URL: %s\n", url.c_str()); |
| 367 | 366 |
| 368 // Do the actual test with input events. | 367 // Do the actual test with input events. |
| 369 RunTestInternal(url, true, delay_us); | 368 RunTestInternal(url, true, delay_us); |
| 370 latencies_[test_flags_] = CalculateLatency(); | 369 latencies_[test_flags_] = CalculateLatency(); |
| 371 | 370 |
| 372 if (mode_ == kWebGLThread) { | 371 if (mode_ == kWebGLThread) { |
| 373 // Print vsync info when in threaded mode. | 372 // Print vsync info when in threaded mode. |
| 374 Query query_vsync = | 373 Query query_vsync = |
| 375 Query::EventName() == | 374 Query::EventNameIs("CCThreadProxy::onVSyncParametersChanged") && |
| 376 Query::String("CCThreadProxy::onVSyncParametersChanged") && | |
| 377 Query::EventHasNumberArg("monotonicTimebase") && | 375 Query::EventHasNumberArg("monotonicTimebase") && |
| 378 Query::EventHasNumberArg("intervalInSeconds"); | 376 Query::EventHasNumberArg("intervalInSeconds"); |
| 379 | 377 |
| 380 const TraceEvent* vsync_info = analyzer_->FindOneEvent(query_vsync); | 378 const TraceEvent* vsync_info = analyzer_->FindFirstOf(query_vsync); |
| 381 if (vsync_info) { | 379 if (vsync_info) { |
| 382 double timebase = vsync_info->GetKnownArgAsDouble("monotonicTimebase"); | 380 double timebase = vsync_info->GetKnownArgAsDouble("monotonicTimebase"); |
| 383 double interval = vsync_info->GetKnownArgAsDouble("intervalInSeconds"); | 381 double interval = vsync_info->GetKnownArgAsDouble("intervalInSeconds"); |
| 384 printf("VSync scheduling: timebase = %f; interval = %f\n", | 382 printf("VSync scheduling: timebase = %f; interval = %f\n", |
| 385 timebase, interval); | 383 timebase, interval); |
| 386 } | 384 } |
| 387 } | 385 } |
| 388 } | 386 } |
| 389 | 387 |
| 390 // Print summary if more than 1 behavior was tested in this run. This is only | 388 // Print summary if more than 1 behavior was tested in this run. This is only |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 kInputHeavy | kInputDirty | kRafHeavy, \ | 720 kInputHeavy | kInputDirty | kRafHeavy, \ |
| 723 kInputHeavy | kInputDirty | kRafHeavy | kPaintHeavy, \ | 721 kInputHeavy | kInputDirty | kRafHeavy | kPaintHeavy, \ |
| 724 kInputDirty | kPaintHeavy, \ | 722 kInputDirty | kPaintHeavy, \ |
| 725 kInputDirty | kRafHeavy | kPaintHeavy) | 723 kInputDirty | kRafHeavy | kPaintHeavy) |
| 726 | 724 |
| 727 INSTANTIATE_TEST_CASE_P(, LatencyTestWebGL, LATENCY_SUITE_MODES()); | 725 INSTANTIATE_TEST_CASE_P(, LatencyTestWebGL, LATENCY_SUITE_MODES()); |
| 728 INSTANTIATE_TEST_CASE_P(, LatencyTestWebGLThread, LATENCY_SUITE_MODES()); | 726 INSTANTIATE_TEST_CASE_P(, LatencyTestWebGLThread, LATENCY_SUITE_MODES()); |
| 729 INSTANTIATE_TEST_CASE_P(, LatencyTestSW, LATENCY_SUITE_MODES()); | 727 INSTANTIATE_TEST_CASE_P(, LatencyTestSW, LATENCY_SUITE_MODES()); |
| 730 | 728 |
| 731 } // namespace | 729 } // namespace |
| OLD | NEW |