OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <map> | 5 #include <map> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #if defined(OS_MACOSX) | 10 #if defined(OS_MACOSX) |
11 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
12 #endif | 12 #endif |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 #include "base/test/trace_event_analyzer.h" | 14 #include "base/test/trace_event_analyzer.h" |
15 #include "base/time/default_tick_clock.h" | |
15 #include "base/win/windows_version.h" | 16 #include "base/win/windows_version.h" |
16 #include "chrome/browser/extensions/extension_apitest.h" | 17 #include "chrome/browser/extensions/extension_apitest.h" |
17 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
18 #include "chrome/browser/extensions/extension_test_message_listener.h" | 19 #include "chrome/browser/extensions/extension_test_message_listener.h" |
19 #include "chrome/browser/extensions/tab_helper.h" | 20 #include "chrome/browser/extensions/tab_helper.h" |
20 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
21 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" | 22 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" |
22 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
23 #include "chrome/common/chrome_version_info.h" | 24 #include "chrome/common/chrome_version_info.h" |
24 #include "chrome/test/base/test_launcher_utils.h" | 25 #include "chrome/test/base/test_launcher_utils.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 // on the command line. This is required for | 66 // on the command line. This is required for |
66 // tests that run on GPU. | 67 // tests that run on GPU. |
67 kDisableVsync = 1 << 1, // Do not limit framerate to vertical refresh. | 68 kDisableVsync = 1 << 1, // Do not limit framerate to vertical refresh. |
68 // when on GPU, nor to 60hz when not on GPU. | 69 // when on GPU, nor to 60hz when not on GPU. |
69 kSmallWindow = 1 << 2, // 1 = 800x600, 0 = 2000x1000 | 70 kSmallWindow = 1 << 2, // 1 = 800x600, 0 = 2000x1000 |
70 k24fps = 1 << 3, // use 24 fps video | 71 k24fps = 1 << 3, // use 24 fps video |
71 k30fps = 1 << 4, // use 30 fps video | 72 k30fps = 1 << 4, // use 30 fps video |
72 k60fps = 1 << 5, // use 60 fps video | 73 k60fps = 1 << 5, // use 60 fps video |
73 kProxyWifi = 1 << 6, // Run UDP through UDPProxy wifi profile | 74 kProxyWifi = 1 << 6, // Run UDP through UDPProxy wifi profile |
74 kProxyEvil = 1 << 7, // Run UDP through UDPProxy evil profile | 75 kProxyEvil = 1 << 7, // Run UDP through UDPProxy evil profile |
76 kSlowClock = 1 << 8, // Receiver clock is 10 seconds slow | |
77 kFastClock = 1 << 9, // Receiver clock is 10 seconds fast | |
78 }; | |
79 | |
80 class SkewedTickClock : public base::DefaultTickClock { | |
81 public: | |
82 explicit SkewedTickClock(const base::TimeDelta& delta) : delta_(delta) { | |
83 } | |
84 virtual base::TimeTicks NowTicks() OVERRIDE { | |
85 return DefaultTickClock::NowTicks() + delta_; | |
86 } | |
87 private: | |
88 base::TimeDelta delta_; | |
75 }; | 89 }; |
76 | 90 |
77 // We log one of these for each call to OnAudioFrame/OnVideoFrame. | 91 // We log one of these for each call to OnAudioFrame/OnVideoFrame. |
78 struct TimeData { | 92 struct TimeData { |
79 TimeData(uint16 frame_no_, base::TimeTicks render_time_) : | 93 TimeData(uint16 frame_no_, base::TimeTicks render_time_) : |
80 frame_no(frame_no_), | 94 frame_no(frame_no_), |
81 render_time(render_time_) { | 95 render_time(render_time_) { |
82 } | 96 } |
83 // The unit here is video frames, for audio data there can be duplicates. | 97 // The unit here is video frames, for audio data there can be duplicates. |
84 // This was decoded from the actual audio/video data. | 98 // This was decoded from the actual audio/video data. |
(...skipping 30 matching lines...) Expand all Loading... | |
115 const std::string& unit) { | 129 const std::string& unit) { |
116 if (num_values >= 20) { | 130 if (num_values >= 20) { |
117 perf_test::PrintResultMeanAndError(measurement, | 131 perf_test::PrintResultMeanAndError(measurement, |
118 modifier, | 132 modifier, |
119 trace, | 133 trace, |
120 AsString(), | 134 AsString(), |
121 unit, | 135 unit, |
122 true); | 136 true); |
123 } else { | 137 } else { |
124 LOG(ERROR) << "Not enough events for " | 138 LOG(ERROR) << "Not enough events for " |
125 << measurement << " " << modifier << " " << trace; | 139 << measurement << modifier << " " << trace; |
126 } | 140 } |
127 } | 141 } |
128 | 142 |
129 size_t num_values; | 143 size_t num_values; |
130 double mean; | 144 double mean; |
131 double std_dev; | 145 double std_dev; |
132 }; | 146 }; |
133 | 147 |
134 // This function checks how smooth the data in |data| is. | 148 // This function checks how smooth the data in |data| is. |
135 // It computes the average error of deltas and the average delta. | 149 // It computes the average error of deltas and the average delta. |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 if (HasFlag(k24fps)) | 298 if (HasFlag(k24fps)) |
285 suffix += "_24fps"; | 299 suffix += "_24fps"; |
286 if (HasFlag(k30fps)) | 300 if (HasFlag(k30fps)) |
287 suffix += "_30fps"; | 301 suffix += "_30fps"; |
288 if (HasFlag(k60fps)) | 302 if (HasFlag(k60fps)) |
289 suffix += "_60fps"; | 303 suffix += "_60fps"; |
290 if (HasFlag(kProxyWifi)) | 304 if (HasFlag(kProxyWifi)) |
291 suffix += "_wifi"; | 305 suffix += "_wifi"; |
292 if (HasFlag(kProxyEvil)) | 306 if (HasFlag(kProxyEvil)) |
293 suffix += "_evil"; | 307 suffix += "_evil"; |
308 if (HasFlag(kSlowClock)) | |
309 suffix += "_slow"; | |
310 if (HasFlag(kFastClock)) | |
311 suffix += "_fast"; | |
294 return suffix; | 312 return suffix; |
295 } | 313 } |
296 | 314 |
297 int getfps() { | 315 int getfps() { |
298 if (HasFlag(k24fps)) | 316 if (HasFlag(k24fps)) |
299 return 24; | 317 return 24; |
300 if (HasFlag(k30fps)) | 318 if (HasFlag(k30fps)) |
301 return 30; | 319 return 30; |
302 if (HasFlag(k60fps)) | 320 if (HasFlag(k60fps)) |
303 return 60; | 321 return 60; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 } | 378 } |
361 | 379 |
362 void GetTraceEvents(trace_analyzer::TraceAnalyzer* analyzer, | 380 void GetTraceEvents(trace_analyzer::TraceAnalyzer* analyzer, |
363 const std::string& event_name, | 381 const std::string& event_name, |
364 trace_analyzer::TraceEventVector* events) { | 382 trace_analyzer::TraceEventVector* events) { |
365 trace_analyzer::Query query = | 383 trace_analyzer::Query query = |
366 trace_analyzer::Query::EventNameIs(event_name) && | 384 trace_analyzer::Query::EventNameIs(event_name) && |
367 (trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_BEGIN) || | 385 (trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_BEGIN) || |
368 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_BEGIN) || | 386 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_ASYNC_BEGIN) || |
369 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_FLOW_BEGIN) || | 387 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_FLOW_BEGIN) || |
370 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_INSTANT)); | 388 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_INSTANT) || |
389 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_COMPLETE)); | |
371 analyzer->FindEvents(query, events); | 390 analyzer->FindEvents(query, events); |
372 } | 391 } |
373 | 392 |
374 // The key contains the name of the argument and the argument. | 393 // The key contains the name of the argument and the argument. |
375 typedef std::pair<std::string, double> EventMapKey; | 394 typedef std::pair<std::string, double> EventMapKey; |
376 typedef std::map<EventMapKey, const trace_analyzer::TraceEvent*> EventMap; | 395 typedef std::map<EventMapKey, const trace_analyzer::TraceEvent*> EventMap; |
377 | 396 |
378 // Make events findable by their arguments, for instance, if an | 397 // Make events findable by their arguments, for instance, if an |
379 // event has a "timestamp": 238724 argument, the map will contain | 398 // event has a "timestamp": 238724 argument, the map will contain |
380 // pair<"timestamp", 238724> -> &event. All arguments are indexed. | 399 // pair<"timestamp", 238724> -> &event. All arguments are indexed. |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
547 | 566 |
548 ASSERT_EQ(1, | 567 ASSERT_EQ(1, |
549 (HasFlag(k24fps) ? 1 : 0) + | 568 (HasFlag(k24fps) ? 1 : 0) + |
550 (HasFlag(k30fps) ? 1 : 0) + | 569 (HasFlag(k30fps) ? 1 : 0) + |
551 (HasFlag(k60fps) ? 1 : 0)); | 570 (HasFlag(k60fps) ? 1 : 0)); |
552 | 571 |
553 net::IPEndPoint receiver_end_point = GetFreeLocalPort(); | 572 net::IPEndPoint receiver_end_point = GetFreeLocalPort(); |
554 | 573 |
555 // Start the in-process receiver that examines audio/video for the expected | 574 // Start the in-process receiver that examines audio/video for the expected |
556 // test patterns. | 575 // test patterns. |
576 base::TimeDelta delta = base::TimeDelta::FromSeconds(0); | |
577 if (HasFlag(kFastClock)) { | |
578 delta = base::TimeDelta::FromSeconds(10); | |
579 } | |
580 if (HasFlag(kSlowClock)) { | |
581 delta = base::TimeDelta::FromSeconds(-10); | |
582 } | |
557 scoped_refptr<media::cast::StandaloneCastEnvironment> cast_environment( | 583 scoped_refptr<media::cast::StandaloneCastEnvironment> cast_environment( |
558 new media::cast::StandaloneCastEnvironment); | 584 new media::cast::StandaloneCastEnvironment( |
585 make_scoped_ptr<base::TickClock>(new SkewedTickClock(delta)))); | |
559 TestPatternReceiver* const receiver = | 586 TestPatternReceiver* const receiver = |
560 new TestPatternReceiver(cast_environment, receiver_end_point); | 587 new TestPatternReceiver(cast_environment, receiver_end_point); |
561 receiver->Start(); | 588 receiver->Start(); |
562 | 589 |
563 scoped_ptr<media::cast::test::UDPProxy> udp_proxy; | 590 scoped_ptr<media::cast::test::UDPProxy> udp_proxy; |
564 if (HasFlag(kProxyWifi) || HasFlag(kProxyEvil)) { | 591 if (HasFlag(kProxyWifi) || HasFlag(kProxyEvil)) { |
565 net::IPEndPoint proxy_end_point = GetFreeLocalPort(); | 592 net::IPEndPoint proxy_end_point = GetFreeLocalPort(); |
566 if (HasFlag(kProxyWifi)) { | 593 if (HasFlag(kProxyWifi)) { |
567 udp_proxy = media::cast::test::UDPProxy::Create( | 594 udp_proxy = media::cast::test::UDPProxy::Create( |
568 proxy_end_point, | 595 proxy_end_point, |
569 receiver_end_point, | 596 receiver_end_point, |
570 media::cast::test::WifiNetwork().Pass(), | 597 media::cast::test::WifiNetwork().Pass(), |
571 media::cast::test::WifiNetwork().Pass(), | 598 media::cast::test::WifiNetwork().Pass(), |
572 NULL); | 599 NULL); |
573 } else if (HasFlag(kProxyEvil)) { | 600 } else if (HasFlag(kProxyEvil)) { |
574 udp_proxy = media::cast::test::UDPProxy::Create( | 601 udp_proxy = media::cast::test::UDPProxy::Create( |
575 proxy_end_point, | 602 proxy_end_point, |
576 receiver_end_point, | 603 receiver_end_point, |
577 media::cast::test::EvilNetwork().Pass(), | 604 media::cast::test::EvilNetwork().Pass(), |
578 media::cast::test::EvilNetwork().Pass(), | 605 media::cast::test::EvilNetwork().Pass(), |
579 NULL); | 606 NULL); |
580 } | 607 } |
581 receiver_end_point = proxy_end_point; | 608 receiver_end_point = proxy_end_point; |
582 } | 609 } |
583 | 610 |
584 std::string json_events; | 611 std::string json_events; |
585 ASSERT_TRUE(tracing::BeginTracing("test_fps,mirroring,cast_perf_test")); | 612 ASSERT_TRUE(tracing::BeginTracing( |
613 "renderer_host,mirroring,cast_perf_test")); | |
586 const std::string page_url = base::StringPrintf( | 614 const std::string page_url = base::StringPrintf( |
587 "performance%d.html?port=%d", | 615 "performance%d.html?port=%d", |
588 getfps(), | 616 getfps(), |
589 receiver_end_point.port()); | 617 receiver_end_point.port()); |
590 ASSERT_TRUE(RunExtensionSubtest("cast_streaming", page_url)) << message_; | 618 ASSERT_TRUE(RunExtensionSubtest("cast_streaming", page_url)) << message_; |
591 ASSERT_TRUE(tracing::EndTracing(&json_events)); | 619 ASSERT_TRUE(tracing::EndTracing(&json_events)); |
592 receiver->Stop(); | 620 receiver->Stop(); |
593 | 621 |
594 // Stop all threads, removes the need for synchronization when analyzing | 622 // Stop all threads, removes the need for synchronization when analyzing |
595 // the data. | 623 // the data. |
596 cast_environment->Shutdown(); | 624 cast_environment->Shutdown(); |
597 scoped_ptr<trace_analyzer::TraceAnalyzer> analyzer; | 625 scoped_ptr<trace_analyzer::TraceAnalyzer> analyzer; |
598 analyzer.reset(trace_analyzer::TraceAnalyzer::Create(json_events)); | 626 analyzer.reset(trace_analyzer::TraceAnalyzer::Create(json_events)); |
599 analyzer->AssociateAsyncBeginEndEvents(); | 627 analyzer->AssociateAsyncBeginEndEvents(); |
600 | 628 |
601 // Only one of these PrintResults should actually print something. | 629 // Only one of these PrintResults should actually print something. |
602 // The printed result will be the average time between frames in the | 630 // The printed result will be the average time between frames in the |
603 // browser window. | 631 // browser window. |
604 MeanAndError sw_frame_data = AnalyzeTraceDistance(analyzer.get(), | 632 MeanAndError frame_data = AnalyzeTraceDistance( |
605 "TestFrameTickSW"); | 633 analyzer.get(), |
606 MeanAndError frame_data = AnalyzeTraceDistance(analyzer.get(), | 634 #ifdef OS_MACOSX |
607 "TestFrameTickGPU"); | 635 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped" |
608 if (frame_data.num_values == 0) { | 636 #else |
609 frame_data = sw_frame_data; | 637 "RenderWidgetHostImpl::OnSwapCompositorFrame" |
610 } | 638 #endif |
piman
2014/04/08 22:46:03
This hardcodes the knowledge that "on mac we don't
hubbe
2014/04/08 22:58:29
Now uses a special trace event which is normally O
| |
639 ); | |
611 EXPECT_GT(frame_data.num_values, 0UL); | 640 EXPECT_GT(frame_data.num_values, 0UL); |
612 // Lower is better. | 641 // Lower is better. |
613 frame_data.Print(test_name, | 642 frame_data.Print(test_name, |
614 GetSuffixForTestFlags(), | 643 GetSuffixForTestFlags(), |
615 "time_between_frames", | 644 "time_between_frames", |
616 "ms"); | 645 "ms"); |
617 | 646 |
618 // This prints out the average time between capture events. | 647 // This prints out the average time between capture events. |
619 // As the capture frame rate is capped at 30fps, this score | 648 // As the capture frame rate is capped at 30fps, this score |
620 // cannot get any better than (lower) 33.33 ms. | 649 // cannot get any better than (lower) 33.33 ms. |
(...skipping 20 matching lines...) Expand all Loading... | |
641 // (it's a prefix for the generated test cases) | 670 // (it's a prefix for the generated test cases) |
642 INSTANTIATE_TEST_CASE_P( | 671 INSTANTIATE_TEST_CASE_P( |
643 , | 672 , |
644 CastV2PerformanceTest, | 673 CastV2PerformanceTest, |
645 testing::Values( | 674 testing::Values( |
646 kUseGpu | k24fps, | 675 kUseGpu | k24fps, |
647 kUseGpu | k30fps, | 676 kUseGpu | k30fps, |
648 kUseGpu | k60fps, | 677 kUseGpu | k60fps, |
649 kUseGpu | k24fps | kDisableVsync, | 678 kUseGpu | k24fps | kDisableVsync, |
650 kUseGpu | k30fps | kProxyWifi, | 679 kUseGpu | k30fps | kProxyWifi, |
651 kUseGpu | k30fps | kProxyEvil)); | 680 kUseGpu | k30fps | kProxyEvil, |
681 kUseGpu | k30fps | kSlowClock, | |
682 kUseGpu | k30fps | kFastClock)); | |
OLD | NEW |