OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "platform/scheduler/renderer/web_view_scheduler_impl.h" | 5 #include "platform/scheduler/renderer/web_view_scheduler_impl.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "platform/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
10 #include "platform/WebFrameScheduler.h" | 10 #include "platform/WebFrameScheduler.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 // Given that we already align timers to 1Hz, do not report throttling if | 23 // Given that we already align timers to 1Hz, do not report throttling if |
24 // it is under 3s. | 24 // it is under 3s. |
25 constexpr base::TimeDelta kMinimalBackgroundThrottlingDurationToReport = | 25 constexpr base::TimeDelta kMinimalBackgroundThrottlingDurationToReport = |
26 base::TimeDelta::FromSeconds(3); | 26 base::TimeDelta::FromSeconds(3); |
27 constexpr base::TimeDelta kDefaultMaxBackgroundBudgetLevel = | 27 constexpr base::TimeDelta kDefaultMaxBackgroundBudgetLevel = |
28 base::TimeDelta::FromSeconds(3); | 28 base::TimeDelta::FromSeconds(3); |
29 constexpr base::TimeDelta kDefaultMaxBackgroundThrottlingDelay = | 29 constexpr base::TimeDelta kDefaultMaxBackgroundThrottlingDelay = |
30 base::TimeDelta::FromMinutes(1); | 30 base::TimeDelta::FromMinutes(1); |
31 constexpr base::TimeDelta kDefaultInitialBackgroundBudget = | 31 constexpr base::TimeDelta kDefaultInitialBackgroundBudget = |
32 base::TimeDelta::FromSeconds(1); | 32 base::TimeDelta::FromSeconds(1); |
33 constexpr base::TimeDelta kBackgroundBudgetThrottlingGracePeriod = | 33 constexpr base::TimeDelta kBackgroundThrottlingGracePeriod = |
34 base::TimeDelta::FromSeconds(10); | 34 base::TimeDelta::FromSeconds(10); |
35 | 35 |
36 // Values coming from WebViewSchedulerSettings are interpreted as follows: | 36 // Values coming from WebViewSchedulerSettings are interpreted as follows: |
37 // -1 is "not set". Scheduler should use a reasonable default. | 37 // -1 is "not set". Scheduler should use a reasonable default. |
38 // 0 is "none". base::nullopt will be used if value is optional. | 38 // 0 is "none". base::nullopt will be used if value is optional. |
39 // other values are left without changes. | 39 // other values are left without changes. |
40 | 40 |
41 double GetBackgroundBudgetRecoveryRate( | 41 double GetBackgroundBudgetRecoveryRate( |
42 WebViewScheduler::WebViewSchedulerSettings* settings) { | 42 WebViewScheduler::WebViewSchedulerSettings* settings) { |
43 if (!settings) | 43 if (!settings) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 WebViewSchedulerImpl::WebViewSchedulerImpl( | 94 WebViewSchedulerImpl::WebViewSchedulerImpl( |
95 WebScheduler::InterventionReporter* intervention_reporter, | 95 WebScheduler::InterventionReporter* intervention_reporter, |
96 WebViewScheduler::WebViewSchedulerSettings* settings, | 96 WebViewScheduler::WebViewSchedulerSettings* settings, |
97 RendererSchedulerImpl* renderer_scheduler, | 97 RendererSchedulerImpl* renderer_scheduler, |
98 bool disable_background_timer_throttling) | 98 bool disable_background_timer_throttling) |
99 : intervention_reporter_(intervention_reporter), | 99 : intervention_reporter_(intervention_reporter), |
100 renderer_scheduler_(renderer_scheduler), | 100 renderer_scheduler_(renderer_scheduler), |
101 virtual_time_policy_(VirtualTimePolicy::ADVANCE), | 101 virtual_time_policy_(VirtualTimePolicy::ADVANCE), |
102 background_parser_count_(0), | 102 background_parser_count_(0), |
103 page_visible_(true), | 103 page_visible_(true), |
| 104 should_throttle_frames_(false), |
104 disable_background_timer_throttling_(disable_background_timer_throttling), | 105 disable_background_timer_throttling_(disable_background_timer_throttling), |
105 allow_virtual_time_to_advance_(true), | 106 allow_virtual_time_to_advance_(true), |
106 have_seen_loading_task_(false), | 107 have_seen_loading_task_(false), |
107 virtual_time_(false), | 108 virtual_time_(false), |
108 is_audio_playing_(false), | 109 is_audio_playing_(false), |
109 reported_background_throttling_since_navigation_(false), | 110 reported_background_throttling_since_navigation_(false), |
110 background_time_budget_pool_(nullptr), | 111 background_time_budget_pool_(nullptr), |
111 settings_(settings) { | 112 settings_(settings) { |
112 renderer_scheduler->AddWebViewScheduler(this); | 113 renderer_scheduler->AddWebViewScheduler(this); |
113 | 114 |
114 delayed_background_budget_throttling_enabler_.Reset( | 115 delayed_background_throttling_enabler_.Reset( |
115 base::Bind(&WebViewSchedulerImpl::EnableBackgroundBudgetThrottling, | 116 base::Bind(&WebViewSchedulerImpl::EnableBackgroundThrottling, |
116 base::Unretained(this))); | 117 base::Unretained(this))); |
117 } | 118 } |
118 | 119 |
119 WebViewSchedulerImpl::~WebViewSchedulerImpl() { | 120 WebViewSchedulerImpl::~WebViewSchedulerImpl() { |
120 // TODO(alexclarke): Find out why we can't rely on the web view outliving the | 121 // TODO(alexclarke): Find out why we can't rely on the web view outliving the |
121 // frame. | 122 // frame. |
122 for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { | 123 for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { |
123 frame_scheduler->DetachFromWebViewScheduler(); | 124 frame_scheduler->DetachFromWebViewScheduler(); |
124 } | 125 } |
125 renderer_scheduler_->RemoveWebViewScheduler(this); | 126 renderer_scheduler_->RemoveWebViewScheduler(this); |
126 | 127 |
127 if (background_time_budget_pool_) | 128 if (background_time_budget_pool_) |
128 background_time_budget_pool_->Close(); | 129 background_time_budget_pool_->Close(); |
129 } | 130 } |
130 | 131 |
131 void WebViewSchedulerImpl::setPageVisible(bool page_visible) { | 132 void WebViewSchedulerImpl::setPageVisible(bool page_visible) { |
132 if (disable_background_timer_throttling_ || page_visible_ == page_visible) | 133 if (disable_background_timer_throttling_ || page_visible_ == page_visible) |
133 return; | 134 return; |
134 | 135 |
135 page_visible_ = page_visible; | 136 page_visible_ = page_visible; |
136 | 137 |
137 for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { | 138 UpdateBackgroundThrottlingState(); |
138 frame_scheduler->setPageVisible(page_visible_); | |
139 } | |
140 | |
141 UpdateBackgroundBudgetThrottlingState(); | |
142 } | 139 } |
143 | 140 |
144 std::unique_ptr<WebFrameSchedulerImpl> | 141 std::unique_ptr<WebFrameSchedulerImpl> |
145 WebViewSchedulerImpl::createWebFrameSchedulerImpl( | 142 WebViewSchedulerImpl::createWebFrameSchedulerImpl( |
146 base::trace_event::BlameContext* blame_context) { | 143 base::trace_event::BlameContext* blame_context) { |
147 MaybeInitializeBackgroundTimeBudgetPool(); | 144 MaybeInitializeBackgroundTimeBudgetPool(); |
148 std::unique_ptr<WebFrameSchedulerImpl> frame_scheduler( | 145 std::unique_ptr<WebFrameSchedulerImpl> frame_scheduler( |
149 new WebFrameSchedulerImpl(renderer_scheduler_, this, blame_context)); | 146 new WebFrameSchedulerImpl(renderer_scheduler_, this, blame_context)); |
150 frame_scheduler->setPageVisible(page_visible_); | 147 frame_scheduler->setPageThrottled(should_throttle_frames_); |
151 frame_schedulers_.insert(frame_scheduler.get()); | 148 frame_schedulers_.insert(frame_scheduler.get()); |
152 return frame_scheduler; | 149 return frame_scheduler; |
153 } | 150 } |
154 | 151 |
155 std::unique_ptr<blink::WebFrameScheduler> | 152 std::unique_ptr<blink::WebFrameScheduler> |
156 WebViewSchedulerImpl::createFrameScheduler(blink::BlameContext* blame_context) { | 153 WebViewSchedulerImpl::createFrameScheduler(blink::BlameContext* blame_context) { |
157 return createWebFrameSchedulerImpl(blame_context); | 154 return createWebFrameSchedulerImpl(blame_context); |
158 } | 155 } |
159 | 156 |
160 void WebViewSchedulerImpl::Unregister(WebFrameSchedulerImpl* frame_scheduler) { | 157 void WebViewSchedulerImpl::Unregister(WebFrameSchedulerImpl* frame_scheduler) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 return; | 292 return; |
296 | 293 |
297 if (!RuntimeEnabledFeatures::expensiveBackgroundTimerThrottlingEnabled()) | 294 if (!RuntimeEnabledFeatures::expensiveBackgroundTimerThrottlingEnabled()) |
298 return; | 295 return; |
299 | 296 |
300 background_time_budget_pool_ = | 297 background_time_budget_pool_ = |
301 renderer_scheduler_->task_queue_throttler()->CreateTimeBudgetPool( | 298 renderer_scheduler_->task_queue_throttler()->CreateTimeBudgetPool( |
302 "background", GetMaxBudgetLevel(settings_), | 299 "background", GetMaxBudgetLevel(settings_), |
303 GetMaxThrottlingDelay(settings_)); | 300 GetMaxThrottlingDelay(settings_)); |
304 | 301 |
305 UpdateBackgroundBudgetThrottlingState(); | 302 UpdateBackgroundThrottlingState(); |
306 | 303 |
307 LazyNow lazy_now(renderer_scheduler_->tick_clock()); | 304 LazyNow lazy_now(renderer_scheduler_->tick_clock()); |
308 | 305 |
309 background_time_budget_pool_->SetTimeBudgetRecoveryRate( | 306 background_time_budget_pool_->SetTimeBudgetRecoveryRate( |
310 lazy_now.Now(), GetBackgroundBudgetRecoveryRate(settings_)); | 307 lazy_now.Now(), GetBackgroundBudgetRecoveryRate(settings_)); |
311 | 308 |
312 background_time_budget_pool_->GrantAdditionalBudget( | 309 background_time_budget_pool_->GrantAdditionalBudget( |
313 lazy_now.Now(), GetInitialBudget(settings_)); | 310 lazy_now.Now(), GetInitialBudget(settings_)); |
314 } | 311 } |
315 | 312 |
(...skipping 10 matching lines...) Expand all Loading... |
326 "Timer tasks have taken too much time while the page was in the " | 323 "Timer tasks have taken too much time while the page was in the " |
327 "background. " | 324 "background. " |
328 "As a result, they have been deferred for %.3f seconds. " | 325 "As a result, they have been deferred for %.3f seconds. " |
329 "See https://www.chromestatus.com/feature/6172836527865856 " | 326 "See https://www.chromestatus.com/feature/6172836527865856 " |
330 "for more details", | 327 "for more details", |
331 throttling_duration.InSecondsF()); | 328 throttling_duration.InSecondsF()); |
332 | 329 |
333 intervention_reporter_->ReportIntervention(WebString::fromUTF8(message)); | 330 intervention_reporter_->ReportIntervention(WebString::fromUTF8(message)); |
334 } | 331 } |
335 | 332 |
336 void WebViewSchedulerImpl::EnableBackgroundBudgetThrottling() { | 333 void WebViewSchedulerImpl::EnableBackgroundThrottling() { |
337 if (!background_time_budget_pool_) | 334 should_throttle_frames_ = true; |
338 return; | 335 for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { |
339 | 336 frame_scheduler->setPageThrottled(true); |
340 LazyNow lazy_now(renderer_scheduler_->tick_clock()); | 337 } |
341 | 338 if (background_time_budget_pool_) { |
342 background_time_budget_pool_->EnableThrottling(&lazy_now); | 339 LazyNow lazy_now(renderer_scheduler_->tick_clock()); |
| 340 background_time_budget_pool_->EnableThrottling(&lazy_now); |
| 341 } |
343 } | 342 } |
344 | 343 |
345 void WebViewSchedulerImpl::UpdateBackgroundBudgetThrottlingState() { | 344 void WebViewSchedulerImpl::UpdateBackgroundThrottlingState() { |
346 if (!background_time_budget_pool_) | 345 delayed_background_throttling_enabler_.Cancel(); |
347 return; | |
348 | |
349 delayed_background_budget_throttling_enabler_.Cancel(); | |
350 | |
351 LazyNow lazy_now(renderer_scheduler_->tick_clock()); | |
352 | 346 |
353 if (page_visible_) { | 347 if (page_visible_) { |
354 background_time_budget_pool_->DisableThrottling(&lazy_now); | 348 should_throttle_frames_ = false; |
| 349 for (WebFrameSchedulerImpl* frame_scheduler : frame_schedulers_) { |
| 350 frame_scheduler->setPageThrottled(false); |
| 351 } |
| 352 if (background_time_budget_pool_) { |
| 353 LazyNow lazy_now(renderer_scheduler_->tick_clock()); |
| 354 background_time_budget_pool_->DisableThrottling(&lazy_now); |
| 355 } |
355 } else { | 356 } else { |
356 // TODO(altimin): Consider moving this logic into PumpThrottledTasks. | 357 // TODO(altimin): Consider moving this logic into PumpThrottledTasks. |
357 renderer_scheduler_->ControlTaskRunner()->PostDelayedTask( | 358 renderer_scheduler_->ControlTaskRunner()->PostDelayedTask( |
358 FROM_HERE, delayed_background_budget_throttling_enabler_.callback(), | 359 FROM_HERE, delayed_background_throttling_enabler_.callback(), |
359 kBackgroundBudgetThrottlingGracePeriod); | 360 kBackgroundThrottlingGracePeriod); |
360 } | 361 } |
361 } | 362 } |
362 | 363 |
363 // static | 364 // static |
364 const char* WebViewSchedulerImpl::VirtualTimePolicyToString( | 365 const char* WebViewSchedulerImpl::VirtualTimePolicyToString( |
365 VirtualTimePolicy virtual_time_policy) { | 366 VirtualTimePolicy virtual_time_policy) { |
366 switch (virtual_time_policy) { | 367 switch (virtual_time_policy) { |
367 case VirtualTimePolicy::ADVANCE: | 368 case VirtualTimePolicy::ADVANCE: |
368 return "ADVANCE"; | 369 return "ADVANCE"; |
369 case VirtualTimePolicy::PAUSE: | 370 case VirtualTimePolicy::PAUSE: |
370 return "PAUSE"; | 371 return "PAUSE"; |
371 case VirtualTimePolicy::DETERMINISTIC_LOADING: | 372 case VirtualTimePolicy::DETERMINISTIC_LOADING: |
372 return "DETERMINISTIC_LOADING"; | 373 return "DETERMINISTIC_LOADING"; |
373 default: | 374 default: |
374 NOTREACHED(); | 375 NOTREACHED(); |
375 return nullptr; | 376 return nullptr; |
376 } | 377 } |
377 } | 378 } |
378 | 379 |
379 } // namespace scheduler | 380 } // namespace scheduler |
380 } // namespace blink | 381 } // namespace blink |
OLD | NEW |