| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ | |
| 6 #define COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ | |
| 7 | |
| 8 #include "base/atomicops.h" | |
| 9 #include "base/macros.h" | |
| 10 #include "base/synchronization/lock.h" | |
| 11 #include "components/scheduler/base/pollable_thread_safe_flag.h" | |
| 12 #include "components/scheduler/base/queueing_time_estimator.h" | |
| 13 #include "components/scheduler/base/task_time_tracker.h" | |
| 14 #include "components/scheduler/child/idle_helper.h" | |
| 15 #include "components/scheduler/child/scheduler_helper.h" | |
| 16 #include "components/scheduler/renderer/deadline_task_runner.h" | |
| 17 #include "components/scheduler/renderer/idle_time_estimator.h" | |
| 18 #include "components/scheduler/renderer/render_widget_signals.h" | |
| 19 #include "components/scheduler/renderer/renderer_scheduler.h" | |
| 20 #include "components/scheduler/renderer/task_cost_estimator.h" | |
| 21 #include "components/scheduler/renderer/throttling_helper.h" | |
| 22 #include "components/scheduler/renderer/user_model.h" | |
| 23 #include "components/scheduler/renderer/web_view_scheduler_impl.h" | |
| 24 #include "components/scheduler/scheduler_export.h" | |
| 25 | |
| 26 namespace base { | |
| 27 namespace trace_event { | |
| 28 class ConvertableToTraceFormat; | |
| 29 } | |
| 30 } | |
| 31 | |
| 32 namespace scheduler { | |
| 33 class RenderWidgetSchedulingState; | |
| 34 class WebViewSchedulerImpl; | |
| 35 class ThrottlingHelper; | |
| 36 | |
| 37 class SCHEDULER_EXPORT RendererSchedulerImpl | |
| 38 : public RendererScheduler, | |
| 39 public IdleHelper::Delegate, | |
| 40 public SchedulerHelper::Observer, | |
| 41 public RenderWidgetSignals::Observer, | |
| 42 public TaskTimeTracker, | |
| 43 public QueueingTimeEstimator::Client { | |
| 44 public: | |
| 45 // Keep RendererScheduler::UseCaseToString in sync with this enum. | |
| 46 enum class UseCase { | |
| 47 // No active use case detected. | |
| 48 NONE, | |
| 49 // A continuous gesture (e.g., scroll, pinch) which is being driven by the | |
| 50 // compositor thread. | |
| 51 COMPOSITOR_GESTURE, | |
| 52 // An unspecified touch gesture which is being handled by the main thread. | |
| 53 // Note that since we don't have a full view of the use case, we should be | |
| 54 // careful to prioritize all work equally. | |
| 55 MAIN_THREAD_CUSTOM_INPUT_HANDLING, | |
| 56 // A continuous gesture (e.g., scroll, pinch) which is being driven by the | |
| 57 // compositor thread but also observed by the main thread. An example is | |
| 58 // synchronized scrolling where a scroll listener on the main thread changes | |
| 59 // page layout based on the current scroll position. | |
| 60 SYNCHRONIZED_GESTURE, | |
| 61 // A gesture has recently started and we are about to run main thread touch | |
| 62 // listeners to find out the actual gesture type. To minimize touch latency, | |
| 63 // only input handling work should run in this state. | |
| 64 TOUCHSTART, | |
| 65 // The page is loading. | |
| 66 LOADING, | |
| 67 // A continuous gesture (e.g., scroll) which is being handled by the main | |
| 68 // thread. | |
| 69 MAIN_THREAD_GESTURE, | |
| 70 // Must be the last entry. | |
| 71 USE_CASE_COUNT, | |
| 72 FIRST_USE_CASE = NONE, | |
| 73 }; | |
| 74 static const char* UseCaseToString(UseCase use_case); | |
| 75 static const char* RAILModeToString(v8::RAILMode rail_mode); | |
| 76 | |
| 77 RendererSchedulerImpl(scoped_refptr<SchedulerTqmDelegate> main_task_runner); | |
| 78 ~RendererSchedulerImpl() override; | |
| 79 | |
| 80 // RendererScheduler implementation: | |
| 81 std::unique_ptr<blink::WebThread> CreateMainThread() override; | |
| 82 scoped_refptr<TaskQueue> DefaultTaskRunner() override; | |
| 83 scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override; | |
| 84 scoped_refptr<TaskQueue> CompositorTaskRunner() override; | |
| 85 scoped_refptr<TaskQueue> LoadingTaskRunner() override; | |
| 86 scoped_refptr<TaskQueue> TimerTaskRunner() override; | |
| 87 scoped_refptr<TaskQueue> NewLoadingTaskRunner(const char* name) override; | |
| 88 scoped_refptr<TaskQueue> NewTimerTaskRunner(const char* name) override; | |
| 89 scoped_refptr<TaskQueue> NewUnthrottledTaskRunner(const char* name) override; | |
| 90 std::unique_ptr<RenderWidgetSchedulingState> NewRenderWidgetSchedulingState() | |
| 91 override; | |
| 92 void WillBeginFrame(const cc::BeginFrameArgs& args) override; | |
| 93 void BeginFrameNotExpectedSoon() override; | |
| 94 void DidCommitFrameToCompositor() override; | |
| 95 void DidHandleInputEventOnCompositorThread( | |
| 96 const blink::WebInputEvent& web_input_event, | |
| 97 InputEventState event_state) override; | |
| 98 void DidHandleInputEventOnMainThread( | |
| 99 const blink::WebInputEvent& web_input_event) override; | |
| 100 void DidAnimateForInputOnCompositorThread() override; | |
| 101 void OnRendererBackgrounded() override; | |
| 102 void OnRendererForegrounded() override; | |
| 103 void SuspendRenderer() override; | |
| 104 void AddPendingNavigation( | |
| 105 blink::WebScheduler::NavigatingFrameType type) override; | |
| 106 void RemovePendingNavigation( | |
| 107 blink::WebScheduler::NavigatingFrameType type) override; | |
| 108 void OnNavigationStarted() override; | |
| 109 bool IsHighPriorityWorkAnticipated() override; | |
| 110 bool ShouldYieldForHighPriorityWork() override; | |
| 111 bool CanExceedIdleDeadlineIfRequired() const override; | |
| 112 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override; | |
| 113 void RemoveTaskObserver( | |
| 114 base::MessageLoop::TaskObserver* task_observer) override; | |
| 115 void Shutdown() override; | |
| 116 void SuspendTimerQueue() override; | |
| 117 void ResumeTimerQueue() override; | |
| 118 void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) override; | |
| 119 void SetTopLevelBlameContext( | |
| 120 base::trace_event::BlameContext* blame_context) override; | |
| 121 void SetRAILModeObserver(RAILModeObserver* observer) override; | |
| 122 | |
| 123 // RenderWidgetSignals::Observer implementation: | |
| 124 void SetAllRenderWidgetsHidden(bool hidden) override; | |
| 125 void SetHasVisibleRenderWidgetWithTouchHandler( | |
| 126 bool has_visible_render_widget_with_touch_handler) override; | |
| 127 | |
| 128 // SchedulerHelper::Observer implementation: | |
| 129 void OnUnregisterTaskQueue(const scoped_refptr<TaskQueue>& queue) override; | |
| 130 void OnTriedToExecuteBlockedTask(const TaskQueue& queue, | |
| 131 const base::PendingTask& task) override; | |
| 132 | |
| 133 // TaskTimeTracker implementation: | |
| 134 void ReportTaskTime(base::TimeTicks start_time, | |
| 135 base::TimeTicks end_time) override; | |
| 136 | |
| 137 // QueueingTimeEstimator::Client implementation: | |
| 138 void OnQueueingTimeForWindowEstimated(base::TimeDelta queueing_time) override; | |
| 139 | |
| 140 // Returns a task runner where tasks run at the highest possible priority. | |
| 141 scoped_refptr<TaskQueue> ControlTaskRunner(); | |
| 142 | |
| 143 void RegisterTimeDomain(TimeDomain* time_domain); | |
| 144 void UnregisterTimeDomain(TimeDomain* time_domain); | |
| 145 | |
| 146 void SetExpensiveTaskBlockingAllowed(bool allowed); | |
| 147 | |
| 148 void AddWebViewScheduler(WebViewSchedulerImpl* web_view_scheduler); | |
| 149 void RemoveWebViewScheduler(WebViewSchedulerImpl* web_view_scheduler); | |
| 150 | |
| 151 // Test helpers. | |
| 152 SchedulerHelper* GetSchedulerHelperForTesting(); | |
| 153 TaskCostEstimator* GetLoadingTaskCostEstimatorForTesting(); | |
| 154 TaskCostEstimator* GetTimerTaskCostEstimatorForTesting(); | |
| 155 IdleTimeEstimator* GetIdleTimeEstimatorForTesting(); | |
| 156 base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; | |
| 157 void RunIdleTasksForTesting(const base::Closure& callback); | |
| 158 void EndIdlePeriodForTesting(const base::Closure& callback, | |
| 159 base::TimeTicks time_remaining); | |
| 160 bool PolicyNeedsUpdateForTesting(); | |
| 161 | |
| 162 base::TickClock* tick_clock() const; | |
| 163 | |
| 164 RealTimeDomain* real_time_domain() const { | |
| 165 return helper_.real_time_domain(); | |
| 166 } | |
| 167 | |
| 168 ThrottlingHelper* throttling_helper() { return throttling_helper_.get(); } | |
| 169 | |
| 170 private: | |
| 171 friend class RendererSchedulerImplTest; | |
| 172 friend class RendererSchedulerImplForTest; | |
| 173 friend class RenderWidgetSchedulingState; | |
| 174 | |
| 175 enum class ExpensiveTaskPolicy { RUN, BLOCK, THROTTLE }; | |
| 176 | |
| 177 enum class TimeDomainType { | |
| 178 REAL, | |
| 179 THROTTLED, | |
| 180 }; | |
| 181 | |
| 182 struct TaskQueuePolicy { | |
| 183 TaskQueuePolicy() | |
| 184 : is_enabled(true), | |
| 185 priority(TaskQueue::NORMAL_PRIORITY), | |
| 186 time_domain_type(TimeDomainType::REAL) {} | |
| 187 | |
| 188 bool is_enabled; | |
| 189 TaskQueue::QueuePriority priority; | |
| 190 TimeDomainType time_domain_type; | |
| 191 | |
| 192 bool operator==(const TaskQueuePolicy& other) const { | |
| 193 return is_enabled == other.is_enabled && priority == other.priority && | |
| 194 time_domain_type == other.time_domain_type; | |
| 195 } | |
| 196 }; | |
| 197 | |
| 198 struct Policy { | |
| 199 TaskQueuePolicy compositor_queue_policy; | |
| 200 TaskQueuePolicy loading_queue_policy; | |
| 201 TaskQueuePolicy timer_queue_policy; | |
| 202 TaskQueuePolicy default_queue_policy; | |
| 203 v8::RAILMode rail_mode = v8::PERFORMANCE_ANIMATION; | |
| 204 | |
| 205 bool operator==(const Policy& other) const { | |
| 206 return compositor_queue_policy == other.compositor_queue_policy && | |
| 207 loading_queue_policy == other.loading_queue_policy && | |
| 208 timer_queue_policy == other.timer_queue_policy && | |
| 209 default_queue_policy == other.default_queue_policy && | |
| 210 rail_mode == other.rail_mode; | |
| 211 } | |
| 212 }; | |
| 213 | |
| 214 class PollableNeedsUpdateFlag { | |
| 215 public: | |
| 216 PollableNeedsUpdateFlag(base::Lock* write_lock); | |
| 217 ~PollableNeedsUpdateFlag(); | |
| 218 | |
| 219 // Set the flag. May only be called if |write_lock| is held. | |
| 220 void SetWhileLocked(bool value); | |
| 221 | |
| 222 // Returns true iff the flag is set to true. | |
| 223 bool IsSet() const; | |
| 224 | |
| 225 private: | |
| 226 base::subtle::Atomic32 flag_; | |
| 227 base::Lock* write_lock_; // Not owned. | |
| 228 | |
| 229 DISALLOW_COPY_AND_ASSIGN(PollableNeedsUpdateFlag); | |
| 230 }; | |
| 231 | |
| 232 // IdleHelper::Delegate implementation: | |
| 233 bool CanEnterLongIdlePeriod( | |
| 234 base::TimeTicks now, | |
| 235 base::TimeDelta* next_long_idle_period_delay_out) override; | |
| 236 void IsNotQuiescent() override {} | |
| 237 void OnIdlePeriodStarted() override; | |
| 238 void OnIdlePeriodEnded() override; | |
| 239 | |
| 240 void EndIdlePeriod(); | |
| 241 | |
| 242 // Returns the serialized scheduler state for tracing. | |
| 243 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue( | |
| 244 base::TimeTicks optional_now) const; | |
| 245 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked( | |
| 246 base::TimeTicks optional_now) const; | |
| 247 | |
| 248 static bool ShouldPrioritizeInputEvent( | |
| 249 const blink::WebInputEvent& web_input_event); | |
| 250 | |
| 251 // The amount of time which idle periods can continue being scheduled when the | |
| 252 // renderer has been hidden, before going to sleep for good. | |
| 253 static const int kEndIdleWhenHiddenDelayMillis = 10000; | |
| 254 | |
| 255 // The amount of time for which loading tasks will be prioritized over | |
| 256 // other tasks during the initial page load. | |
| 257 static const int kRailsInitialLoadingPrioritizationMillis = 1000; | |
| 258 | |
| 259 // The amount of time in milliseconds we have to respond to user input as | |
| 260 // defined by RAILS. | |
| 261 static const int kRailsResponseTimeMillis = 50; | |
| 262 | |
| 263 // For the purposes of deciding whether or not it's safe to turn timers and | |
| 264 // loading tasks on only in idle periods, we regard the system as being as | |
| 265 // being "idle period" starved if there hasn't been an idle period in the last | |
| 266 // 10 seconds. This was chosen to be long enough to cover most anticipated | |
| 267 // user gestures. | |
| 268 static const int kIdlePeriodStarvationThresholdMillis = 10000; | |
| 269 | |
| 270 // The amount of time to wait before suspending shared timers after the | |
| 271 // renderer has been backgrounded. This is used only if background suspension | |
| 272 // of shared timers is enabled. | |
| 273 static const int kSuspendTimersWhenBackgroundedDelayMillis = 5 * 60 * 1000; | |
| 274 | |
| 275 // The time we should stay in a priority-escalated mode after a call to | |
| 276 // DidAnimateForInputOnCompositorThread(). | |
| 277 static const int kFlingEscalationLimitMillis = 100; | |
| 278 | |
| 279 // Schedules an immediate PolicyUpdate, if there isn't one already pending and | |
| 280 // sets |policy_may_need_update_|. Note |any_thread_lock_| must be | |
| 281 // locked. | |
| 282 void EnsureUrgentPolicyUpdatePostedOnMainThread( | |
| 283 const tracked_objects::Location& from_here); | |
| 284 | |
| 285 // Update the policy if a new signal has arrived. Must be called from the main | |
| 286 // thread. | |
| 287 void MaybeUpdatePolicy(); | |
| 288 | |
| 289 // Locks |any_thread_lock_| and updates the scheduler policy. May early | |
| 290 // out if the policy is unchanged. Must be called from the main thread. | |
| 291 void UpdatePolicy(); | |
| 292 | |
| 293 // Like UpdatePolicy, except it doesn't early out. | |
| 294 void ForceUpdatePolicy(); | |
| 295 | |
| 296 enum class UpdateType { | |
| 297 MAY_EARLY_OUT_IF_POLICY_UNCHANGED, | |
| 298 FORCE_UPDATE, | |
| 299 }; | |
| 300 | |
| 301 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to | |
| 302 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED. | |
| 303 virtual void UpdatePolicyLocked(UpdateType update_type); | |
| 304 | |
| 305 // Helper for computing the use case. |expected_usecase_duration| will be | |
| 306 // filled with the amount of time after which the use case should be updated | |
| 307 // again. If the duration is zero, a new use case update should not be | |
| 308 // scheduled. Must be called with |any_thread_lock_| held. Can be called from | |
| 309 // any thread. | |
| 310 UseCase ComputeCurrentUseCase( | |
| 311 base::TimeTicks now, | |
| 312 base::TimeDelta* expected_use_case_duration) const; | |
| 313 | |
| 314 // An input event of some sort happened, the policy may need updating. | |
| 315 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, | |
| 316 InputEventState input_event_state); | |
| 317 | |
| 318 // Returns true if there has been at least one idle period in the last | |
| 319 // |kIdlePeriodStarvationThresholdMillis|. | |
| 320 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; | |
| 321 | |
| 322 // Helpers for safely suspending/resuming the timer queue after a | |
| 323 // background/foreground signal. | |
| 324 void SuspendTimerQueueWhenBackgrounded(); | |
| 325 void ResumeTimerQueueWhenForegrounded(); | |
| 326 | |
| 327 // The task cost estimators and the UserModel need to be reset upon page | |
| 328 // nagigation. This function does that. Must be called from the main thread. | |
| 329 void ResetForNavigationLocked(); | |
| 330 | |
| 331 // Estimates the maximum task length that won't cause a jank based on the | |
| 332 // current system state. Must be called from the main thread. | |
| 333 base::TimeDelta EstimateLongestJankFreeTaskDuration() const; | |
| 334 | |
| 335 // Log a console warning message to all WebViews in this process. | |
| 336 void BroadcastConsoleWarning(const std::string& message); | |
| 337 | |
| 338 void ApplyTaskQueuePolicy(TaskQueue* task_queue, | |
| 339 const TaskQueuePolicy& old_task_queue_policy, | |
| 340 const TaskQueuePolicy& new_task_queue_policy) const; | |
| 341 | |
| 342 static const char* ExpensiveTaskPolicyToString( | |
| 343 ExpensiveTaskPolicy expensive_task_policy); | |
| 344 | |
| 345 SchedulerHelper helper_; | |
| 346 IdleHelper idle_helper_; | |
| 347 std::unique_ptr<ThrottlingHelper> throttling_helper_; | |
| 348 RenderWidgetSignals render_widget_scheduler_signals_; | |
| 349 | |
| 350 const scoped_refptr<TaskQueue> control_task_runner_; | |
| 351 const scoped_refptr<TaskQueue> compositor_task_runner_; | |
| 352 std::set<scoped_refptr<TaskQueue>> loading_task_runners_; | |
| 353 std::set<scoped_refptr<TaskQueue>> timer_task_runners_; | |
| 354 scoped_refptr<TaskQueue> default_loading_task_runner_; | |
| 355 scoped_refptr<TaskQueue> default_timer_task_runner_; | |
| 356 | |
| 357 base::Closure update_policy_closure_; | |
| 358 DeadlineTaskRunner delayed_update_policy_runner_; | |
| 359 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; | |
| 360 CancelableClosureHolder suspend_timers_when_backgrounded_closure_; | |
| 361 | |
| 362 // We have decided to improve thread safety at the cost of some boilerplate | |
| 363 // (the accessors) for the following data members. | |
| 364 | |
| 365 struct MainThreadOnly { | |
| 366 MainThreadOnly(RendererSchedulerImpl* renderer_scheduler_impl, | |
| 367 const scoped_refptr<TaskQueue>& compositor_task_runner, | |
| 368 base::TickClock* time_source); | |
| 369 ~MainThreadOnly(); | |
| 370 | |
| 371 TaskCostEstimator loading_task_cost_estimator; | |
| 372 TaskCostEstimator timer_task_cost_estimator; | |
| 373 QueueingTimeEstimator queueing_time_estimator; | |
| 374 IdleTimeEstimator idle_time_estimator; | |
| 375 UseCase current_use_case; | |
| 376 Policy current_policy; | |
| 377 base::TimeTicks current_policy_expiration_time; | |
| 378 base::TimeTicks estimated_next_frame_begin; | |
| 379 base::TimeDelta compositor_frame_interval; | |
| 380 base::TimeDelta longest_jank_free_task_duration; | |
| 381 int timer_queue_suspend_count; // TIMER_TASK_QUEUE suspended if non-zero. | |
| 382 int navigation_task_expected_count; | |
| 383 ExpensiveTaskPolicy expensive_task_policy; | |
| 384 bool renderer_hidden; | |
| 385 bool renderer_backgrounded; | |
| 386 bool renderer_suspended; | |
| 387 bool timer_queue_suspension_when_backgrounded_enabled; | |
| 388 bool timer_queue_suspended_when_backgrounded; | |
| 389 bool was_shutdown; | |
| 390 bool loading_tasks_seem_expensive; | |
| 391 bool timer_tasks_seem_expensive; | |
| 392 bool touchstart_expected_soon; | |
| 393 bool have_seen_a_begin_main_frame; | |
| 394 bool have_reported_blocking_intervention_in_current_policy; | |
| 395 bool have_reported_blocking_intervention_since_navigation; | |
| 396 bool has_visible_render_widget_with_touch_handler; | |
| 397 bool begin_frame_not_expected_soon; | |
| 398 bool expensive_task_blocking_allowed; | |
| 399 bool in_idle_period_for_testing; | |
| 400 std::set<WebViewSchedulerImpl*> web_view_schedulers; // Not owned. | |
| 401 RAILModeObserver* rail_mode_observer; // Not owned. | |
| 402 }; | |
| 403 | |
| 404 struct AnyThread { | |
| 405 AnyThread(); | |
| 406 ~AnyThread(); | |
| 407 | |
| 408 base::TimeTicks last_idle_period_end_time; | |
| 409 base::TimeTicks rails_loading_priority_deadline; | |
| 410 base::TimeTicks fling_compositor_escalation_deadline; | |
| 411 UserModel user_model; | |
| 412 bool awaiting_touch_start_response; | |
| 413 bool in_idle_period; | |
| 414 bool begin_main_frame_on_critical_path; | |
| 415 bool last_gesture_was_compositor_driven; | |
| 416 bool default_gesture_prevented; | |
| 417 bool have_seen_touchstart; | |
| 418 }; | |
| 419 | |
| 420 struct CompositorThreadOnly { | |
| 421 CompositorThreadOnly(); | |
| 422 ~CompositorThreadOnly(); | |
| 423 | |
| 424 blink::WebInputEvent::Type last_input_type; | |
| 425 std::unique_ptr<base::ThreadChecker> compositor_thread_checker; | |
| 426 | |
| 427 void CheckOnValidThread() { | |
| 428 #if DCHECK_IS_ON() | |
| 429 // We don't actually care which thread this called from, just so long as | |
| 430 // its consistent. | |
| 431 if (!compositor_thread_checker) | |
| 432 compositor_thread_checker.reset(new base::ThreadChecker()); | |
| 433 DCHECK(compositor_thread_checker->CalledOnValidThread()); | |
| 434 #endif | |
| 435 } | |
| 436 }; | |
| 437 | |
| 438 // Don't access main_thread_only_, instead use MainThreadOnly(). | |
| 439 MainThreadOnly main_thread_only_; | |
| 440 MainThreadOnly& MainThreadOnly() { | |
| 441 helper_.CheckOnValidThread(); | |
| 442 return main_thread_only_; | |
| 443 } | |
| 444 const struct MainThreadOnly& MainThreadOnly() const { | |
| 445 helper_.CheckOnValidThread(); | |
| 446 return main_thread_only_; | |
| 447 } | |
| 448 | |
| 449 mutable base::Lock any_thread_lock_; | |
| 450 // Don't access any_thread_, instead use AnyThread(). | |
| 451 AnyThread any_thread_; | |
| 452 AnyThread& AnyThread() { | |
| 453 any_thread_lock_.AssertAcquired(); | |
| 454 return any_thread_; | |
| 455 } | |
| 456 const struct AnyThread& AnyThread() const { | |
| 457 any_thread_lock_.AssertAcquired(); | |
| 458 return any_thread_; | |
| 459 } | |
| 460 | |
| 461 // Don't access compositor_thread_only_, instead use CompositorThreadOnly(). | |
| 462 CompositorThreadOnly compositor_thread_only_; | |
| 463 CompositorThreadOnly& CompositorThreadOnly() { | |
| 464 compositor_thread_only_.CheckOnValidThread(); | |
| 465 return compositor_thread_only_; | |
| 466 } | |
| 467 | |
| 468 PollableThreadSafeFlag policy_may_need_update_; | |
| 469 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; | |
| 470 | |
| 471 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); | |
| 472 }; | |
| 473 | |
| 474 } // namespace scheduler | |
| 475 | |
| 476 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ | |
| OLD | NEW |