Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: cc/scheduler/compositor_timing_history.cc

Issue 2258253002: cc: Add a Scheduling.SwapAckWasFast UMA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "cc/scheduler/compositor_timing_history.h" 5 #include "cc/scheduler/compositor_timing_history.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 19 matching lines...) Expand all
30 base::TimeDelta duration) = 0; 30 base::TimeDelta duration) = 0;
31 virtual void AddBeginMainFrameQueueDurationNotCriticalDuration( 31 virtual void AddBeginMainFrameQueueDurationNotCriticalDuration(
32 base::TimeDelta duration) = 0; 32 base::TimeDelta duration) = 0;
33 virtual void AddBeginMainFrameStartToCommitDuration( 33 virtual void AddBeginMainFrameStartToCommitDuration(
34 base::TimeDelta duration) = 0; 34 base::TimeDelta duration) = 0;
35 virtual void AddCommitToReadyToActivateDuration(base::TimeDelta duration) = 0; 35 virtual void AddCommitToReadyToActivateDuration(base::TimeDelta duration) = 0;
36 virtual void AddPrepareTilesDuration(base::TimeDelta duration) = 0; 36 virtual void AddPrepareTilesDuration(base::TimeDelta duration) = 0;
37 virtual void AddActivateDuration(base::TimeDelta duration) = 0; 37 virtual void AddActivateDuration(base::TimeDelta duration) = 0;
38 virtual void AddDrawDuration(base::TimeDelta duration) = 0; 38 virtual void AddDrawDuration(base::TimeDelta duration) = 0;
39 virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0; 39 virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0;
40 virtual void AddSwapAckWasFast(bool was_fast) = 0;
40 41
41 // Synchronization measurements 42 // Synchronization measurements
42 virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0; 43 virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0;
43 }; 44 };
44 45
45 namespace { 46 namespace {
46 47
47 // Using the 90th percentile will disable latency recovery 48 // Using the 90th percentile will disable latency recovery
48 // if we are missing the deadline approximately ~6 times per 49 // if we are missing the deadline approximately ~6 times per
49 // second. 50 // second.
50 // TODO(brianderson): Fine tune the percentiles below. 51 // TODO(brianderson): Fine tune the percentiles below.
51 const size_t kDurationHistorySize = 60; 52 const size_t kDurationHistorySize = 60;
52 const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0; 53 const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0;
53 const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0; 54 const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0;
54 const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0; 55 const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0;
55 const double kBeginMainFrameStartToCommitEstimationPercentile = 90.0; 56 const double kBeginMainFrameStartToCommitEstimationPercentile = 90.0;
56 const double kCommitToReadyToActivateEstimationPercentile = 90.0; 57 const double kCommitToReadyToActivateEstimationPercentile = 90.0;
57 const double kPrepareTilesEstimationPercentile = 90.0; 58 const double kPrepareTilesEstimationPercentile = 90.0;
58 const double kActivateEstimationPercentile = 90.0; 59 const double kActivateEstimationPercentile = 90.0;
59 const double kDrawEstimationPercentile = 90.0; 60 const double kDrawEstimationPercentile = 90.0;
60 61
62 // The watchdog uses a combination of BeginImplFrame counts and
63 // actual timestamps to avoid calling Now() too often or adding
sunnyps 2016/08/30 18:31:04 Is this optimization really needed? Even without t
brianderson 2016/08/30 22:30:32 A few years ago, we were especially concerned abou
64 // unnecessary idle wakeups.
65 // This will break if we aren't receiving BeginFrames, but this
66 // is primarily for crbug.com/602486, where we are receiving them.
67 const int kSwapAckWatchdogBeginImplFrameCount = 8 * 61;
68 const int kSwapAckWatchdogBeginImplFrameReCount = 60;
69 const base::TimeDelta kSwapAckWatchdogTimeout =
70 base::TimeDelta::FromMicroseconds(8000000);
71
61 const int kUmaDurationMinMicros = 1; 72 const int kUmaDurationMinMicros = 1;
62 const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5; 73 const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5;
63 const int kUmaDurationBucketCount = 100; 74 const int kUmaDurationBucketCount = 100;
64 75
65 // This macro is deprecated since its bucket count uses too much bandwidth. 76 // This macro is deprecated since its bucket count uses too much bandwidth.
66 // It also has sub-optimal range and bucket distribution. 77 // It also has sub-optimal range and bucket distribution.
67 // TODO(brianderson): Delete this macro and associated UMAs once there is 78 // TODO(brianderson): Delete this macro and associated UMAs once there is
68 // sufficient overlap with the re-bucketed UMAs. 79 // sufficient overlap with the re-bucketed UMAs.
69 #define UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample) \ 80 #define UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample) \
70 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample.InMicroseconds(), \ 81 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample.InMicroseconds(), \
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 void AddDrawDuration(base::TimeDelta duration) override { 195 void AddDrawDuration(base::TimeDelta duration) override {
185 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.DrawDuration", 196 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.DrawDuration",
186 duration); 197 duration);
187 } 198 }
188 199
189 void AddSwapToAckLatency(base::TimeDelta duration) override { 200 void AddSwapToAckLatency(base::TimeDelta duration) override {
190 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.SwapToAckLatency", 201 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.SwapToAckLatency",
191 duration); 202 duration);
192 } 203 }
193 204
205 void AddSwapAckWasFast(bool was_fast) override {
206 UMA_HISTOGRAM_BOOLEAN("Scheduling.Renderer.SwapAckWasFast", was_fast);
207 }
208
194 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { 209 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {
195 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED( 210 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
196 "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta); 211 "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta);
197 } 212 }
198 }; 213 };
199 214
200 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { 215 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter {
201 public: 216 public:
202 ~BrowserUMAReporter() override {} 217 ~BrowserUMAReporter() override {}
203 218
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 void AddDrawDuration(base::TimeDelta duration) override { 272 void AddDrawDuration(base::TimeDelta duration) override {
258 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.DrawDuration", 273 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.DrawDuration",
259 duration); 274 duration);
260 } 275 }
261 276
262 void AddSwapToAckLatency(base::TimeDelta duration) override { 277 void AddSwapToAckLatency(base::TimeDelta duration) override {
263 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.SwapToAckLatency", 278 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.SwapToAckLatency",
264 duration); 279 duration);
265 } 280 }
266 281
282 void AddSwapAckWasFast(bool was_fast) override {
283 UMA_HISTOGRAM_BOOLEAN("Scheduling.Browser.SwapAckWasFast", was_fast);
284 }
285
267 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { 286 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {
268 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED( 287 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
269 "Scheduling.Browser.MainAndImplFrameTimeDelta", delta); 288 "Scheduling.Browser.MainAndImplFrameTimeDelta", delta);
270 } 289 }
271 }; 290 };
272 291
273 class NullUMAReporter : public CompositorTimingHistory::UMAReporter { 292 class NullUMAReporter : public CompositorTimingHistory::UMAReporter {
274 public: 293 public:
275 ~NullUMAReporter() override {} 294 ~NullUMAReporter() override {}
276 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {} 295 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {}
277 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override { 296 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override {
278 } 297 }
279 void AddCommitInterval(base::TimeDelta interval) override {} 298 void AddCommitInterval(base::TimeDelta interval) override {}
280 void AddDrawInterval(base::TimeDelta interval) override {} 299 void AddDrawInterval(base::TimeDelta interval) override {}
281 void AddBeginMainFrameQueueDurationCriticalDuration( 300 void AddBeginMainFrameQueueDurationCriticalDuration(
282 base::TimeDelta duration) override {} 301 base::TimeDelta duration) override {}
283 void AddBeginMainFrameQueueDurationNotCriticalDuration( 302 void AddBeginMainFrameQueueDurationNotCriticalDuration(
284 base::TimeDelta duration) override {} 303 base::TimeDelta duration) override {}
285 void AddBeginMainFrameStartToCommitDuration( 304 void AddBeginMainFrameStartToCommitDuration(
286 base::TimeDelta duration) override {} 305 base::TimeDelta duration) override {}
287 void AddCommitToReadyToActivateDuration(base::TimeDelta duration) override {} 306 void AddCommitToReadyToActivateDuration(base::TimeDelta duration) override {}
288 void AddPrepareTilesDuration(base::TimeDelta duration) override {} 307 void AddPrepareTilesDuration(base::TimeDelta duration) override {}
289 void AddActivateDuration(base::TimeDelta duration) override {} 308 void AddActivateDuration(base::TimeDelta duration) override {}
290 void AddDrawDuration(base::TimeDelta duration) override {} 309 void AddDrawDuration(base::TimeDelta duration) override {}
291 void AddSwapToAckLatency(base::TimeDelta duration) override {} 310 void AddSwapToAckLatency(base::TimeDelta duration) override {}
311 void AddSwapAckWasFast(bool was_fast) override {}
292 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {} 312 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {}
293 }; 313 };
294 314
295 } // namespace 315 } // namespace
296 316
297 CompositorTimingHistory::CompositorTimingHistory( 317 CompositorTimingHistory::CompositorTimingHistory(
298 bool using_synchronous_renderer_compositor, 318 bool using_synchronous_renderer_compositor,
299 UMACategory uma_category, 319 UMACategory uma_category,
300 RenderingStatsInstrumentation* rendering_stats_instrumentation) 320 RenderingStatsInstrumentation* rendering_stats_instrumentation)
301 : using_synchronous_renderer_compositor_( 321 : using_synchronous_renderer_compositor_(
302 using_synchronous_renderer_compositor), 322 using_synchronous_renderer_compositor),
303 enabled_(false), 323 enabled_(false),
304 did_send_begin_main_frame_(false), 324 did_send_begin_main_frame_(false),
305 begin_main_frame_needed_continuously_(false), 325 begin_main_frame_needed_continuously_(false),
306 begin_main_frame_committing_continuously_(false), 326 begin_main_frame_committing_continuously_(false),
307 compositor_drawing_continuously_(false), 327 compositor_drawing_continuously_(false),
308 begin_main_frame_queue_duration_history_(kDurationHistorySize), 328 begin_main_frame_queue_duration_history_(kDurationHistorySize),
309 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize), 329 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize),
310 begin_main_frame_queue_duration_not_critical_history_( 330 begin_main_frame_queue_duration_not_critical_history_(
311 kDurationHistorySize), 331 kDurationHistorySize),
312 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize), 332 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize),
313 commit_to_ready_to_activate_duration_history_(kDurationHistorySize), 333 commit_to_ready_to_activate_duration_history_(kDurationHistorySize),
314 prepare_tiles_duration_history_(kDurationHistorySize), 334 prepare_tiles_duration_history_(kDurationHistorySize),
315 activate_duration_history_(kDurationHistorySize), 335 activate_duration_history_(kDurationHistorySize),
316 draw_duration_history_(kDurationHistorySize), 336 draw_duration_history_(kDurationHistorySize),
317 begin_main_frame_on_critical_path_(false), 337 begin_main_frame_on_critical_path_(false),
338 swap_ack_watchdog_enabled_(false),
339 swap_ack_watchdog_begin_impl_frame_count_(0),
318 uma_reporter_(CreateUMAReporter(uma_category)), 340 uma_reporter_(CreateUMAReporter(uma_category)),
319 rendering_stats_instrumentation_(rendering_stats_instrumentation) {} 341 rendering_stats_instrumentation_(rendering_stats_instrumentation) {}
320 342
321 CompositorTimingHistory::~CompositorTimingHistory() { 343 CompositorTimingHistory::~CompositorTimingHistory() {
322 } 344 }
323 345
324 std::unique_ptr<CompositorTimingHistory::UMAReporter> 346 std::unique_ptr<CompositorTimingHistory::UMAReporter>
325 CompositorTimingHistory::CreateUMAReporter(UMACategory category) { 347 CompositorTimingHistory::CreateUMAReporter(UMACategory category) {
326 switch (category) { 348 switch (category) {
327 case RENDERER_UMA: 349 case RENDERER_UMA:
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 } 458 }
437 459
438 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { 460 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const {
439 return draw_duration_history_.Percentile(kDrawEstimationPercentile); 461 return draw_duration_history_.Percentile(kDrawEstimationPercentile);
440 } 462 }
441 463
442 void CompositorTimingHistory::DidCreateAndInitializeOutputSurface() { 464 void CompositorTimingHistory::DidCreateAndInitializeOutputSurface() {
443 // After we get a new output surface, we won't get a spurious 465 // After we get a new output surface, we won't get a spurious
444 // swap ack from the old output surface. 466 // swap ack from the old output surface.
445 swap_start_time_ = base::TimeTicks(); 467 swap_start_time_ = base::TimeTicks();
468 swap_ack_watchdog_enabled_ = false;
469 swap_ack_watchdog_begin_impl_frame_count_ = 0;
446 } 470 }
447 471
448 void CompositorTimingHistory::WillBeginImplFrame( 472 void CompositorTimingHistory::WillBeginImplFrame(
449 bool new_active_tree_is_likely) { 473 bool new_active_tree_is_likely) {
450 // The check for whether a BeginMainFrame was sent anytime between two 474 // The check for whether a BeginMainFrame was sent anytime between two
451 // BeginImplFrames protects us from not detecting a fast main thread that 475 // BeginImplFrames protects us from not detecting a fast main thread that
452 // does all it's work and goes idle in between BeginImplFrames. 476 // does all it's work and goes idle in between BeginImplFrames.
453 // For example, this may happen if an animation is being driven with 477 // For example, this may happen if an animation is being driven with
454 // setInterval(17) or if input events just happen to arrive in the 478 // setInterval(17) or if input events just happen to arrive in the
455 // middle of every frame. 479 // middle of every frame.
456 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) { 480 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) {
457 SetBeginMainFrameNeededContinuously(false); 481 SetBeginMainFrameNeededContinuously(false);
458 SetBeginMainFrameCommittingContinuously(false); 482 SetBeginMainFrameCommittingContinuously(false);
459 } 483 }
460 484
485 // After N BeginImplFrames, check if the swap ack is taking too long.
486 // Otherwise, check again in M BeginImplFrames.
487 if (swap_ack_watchdog_enabled_) {
488 swap_ack_watchdog_begin_impl_frame_count_++;
489 if (swap_ack_watchdog_begin_impl_frame_count_ ==
490 kSwapAckWatchdogBeginImplFrameCount) {
491 base::TimeDelta swap_not_acked_time_ = Now() - swap_start_time_;
492 if (swap_not_acked_time_ > kSwapAckWatchdogTimeout) {
493 uma_reporter_->AddSwapAckWasFast(false);
494 // Only record this UMA once per swap.
495 swap_ack_watchdog_enabled_ = false;
496 } else {
497 swap_ack_watchdog_begin_impl_frame_count_ -=
498 kSwapAckWatchdogBeginImplFrameReCount;
499 }
500 }
501 }
502
461 did_send_begin_main_frame_ = false; 503 did_send_begin_main_frame_ = false;
462 } 504 }
463 505
464 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { 506 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) {
465 if (!needs_redraw) 507 if (!needs_redraw)
466 SetCompositorDrawingContinuously(false); 508 SetCompositorDrawingContinuously(false);
467 } 509 }
468 510
469 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { 511 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() {
470 SetBeginMainFrameNeededContinuously(false); 512 SetBeginMainFrameNeededContinuously(false);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 new_active_tree_draw_end_time_prev_ = draw_end_time; 732 new_active_tree_draw_end_time_prev_ = draw_end_time;
691 } 733 }
692 } 734 }
693 735
694 draw_start_time_ = base::TimeTicks(); 736 draw_start_time_ = base::TimeTicks();
695 } 737 }
696 738
697 void CompositorTimingHistory::DidSwapBuffers() { 739 void CompositorTimingHistory::DidSwapBuffers() {
698 DCHECK_EQ(base::TimeTicks(), swap_start_time_); 740 DCHECK_EQ(base::TimeTicks(), swap_start_time_);
699 swap_start_time_ = Now(); 741 swap_start_time_ = Now();
742 swap_ack_watchdog_enabled_ = true;
743 swap_ack_watchdog_begin_impl_frame_count_ = 0;
700 } 744 }
701 745
702 void CompositorTimingHistory::DidSwapBuffersComplete() { 746 void CompositorTimingHistory::DidSwapBuffersComplete() {
703 DCHECK_NE(base::TimeTicks(), swap_start_time_); 747 DCHECK_NE(base::TimeTicks(), swap_start_time_);
704 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; 748 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_;
705 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); 749 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration);
750 if (swap_ack_watchdog_enabled_) {
751 uma_reporter_->AddSwapAckWasFast(true);
752 swap_ack_watchdog_enabled_ = false;
753 }
706 swap_start_time_ = base::TimeTicks(); 754 swap_start_time_ = base::TimeTicks();
707 } 755 }
708 756
709 } // namespace cc 757 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698