OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 #include "blimp/engine/renderer/scheduler.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "blimp/engine/renderer/scheduler_client.h" | |
9 | |
10 namespace blimp { | |
11 namespace engine { | |
12 namespace { | |
13 // This is the temporary frame delay to keep pages which make animation requests | |
14 // but don't mutate the state on the engine from running main frames | |
15 // back-to-back. We need smarter throttling of engine updates. See | |
16 // crbug.com/597829. | |
17 const base::TimeDelta kDefaultFrameDelay = | |
Wez
2016/10/13 16:53:52
Is TimeDelta POD? I thought it had a ctor/dtor, s
Khushal
2016/10/13 18:47:27
Its POD, doesn't have a dtor.
Found an example of
Wez
2016/10/18 01:49:42
Oh, OK; I'm surprised that assigning it a value us
Wez
2016/10/19 22:01:34
Aha, looks like From*() are all constexpr!
| |
18 base::TimeDelta::FromMilliseconds(30); | |
19 } // namespace | |
20 | |
21 Scheduler::Scheduler(scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
22 SchedulerClient* client) | |
23 : Scheduler(kDefaultFrameDelay, std::move(task_runner), client) {} | |
24 | |
25 Scheduler::Scheduler(base::TimeDelta frame_delay, | |
26 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
27 SchedulerClient* client) | |
28 : next_frame_time_(base::TimeTicks::Now()), | |
29 frame_delay_(frame_delay), | |
30 client_(client), | |
31 weak_ptr_factory_(this) { | |
32 DCHECK(client_); | |
33 frame_tick_timer_.SetTaskRunner(std::move(task_runner)); | |
34 } | |
35 | |
36 Scheduler::~Scheduler() = default; | |
37 | |
38 void Scheduler::SetNeedsMainFrame() { | |
39 if (needs_main_frame_) | |
40 return; | |
41 | |
42 needs_main_frame_ = true; | |
43 ScheduleMainFrameIfNecessary(); | |
44 } | |
45 | |
46 void Scheduler::DidSendFrameUpdateToClient() { | |
47 DCHECK(!frame_ack_pending_) << "We can have only frame update in flight"; | |
48 | |
49 frame_ack_pending_ = true; | |
50 ScheduleMainFrameIfNecessary(); | |
51 } | |
52 | |
53 void Scheduler::DidReceiveFrameUpdateAck() { | |
54 DCHECK(frame_ack_pending_); | |
55 | |
56 frame_ack_pending_ = false; | |
57 ScheduleMainFrameIfNecessary(); | |
58 } | |
59 | |
60 void Scheduler::ScheduleMainFrameIfNecessary() { | |
61 // If we can't produce main frame updates right now, don't schedule a task. | |
62 if (!CanProduceMainFrames()) { | |
63 return; | |
64 } | |
65 | |
66 // If a task has already been scheduled, we don't need to schedule again. | |
67 if (frame_tick_timer_.IsRunning()) | |
68 return; | |
69 | |
70 base::TimeDelta delay = next_frame_time_ - base::TimeTicks::Now(); | |
71 frame_tick_timer_.Start( | |
72 FROM_HERE, delay, | |
73 base::Bind(&Scheduler::StartMainFrame, weak_ptr_factory_.GetWeakPtr())); | |
Wez
2016/10/13 16:53:52
Take a WeakPtr at construction time, rather than c
Khushal
2016/10/13 18:47:27
The class is created/destroyed and lives on the sa
| |
74 } | |
75 | |
76 bool Scheduler::CanProduceMainFrames() const { | |
77 return needs_main_frame_ && !frame_ack_pending_; | |
78 } | |
79 | |
80 void Scheduler::StartMainFrame() { | |
81 DCHECK(needs_main_frame_); | |
82 | |
83 // If an update was sent to the client since this request, we can not start | |
84 // another frame. Early out here, we'll come back when an Ack is received from | |
85 // the client. | |
86 if (frame_ack_pending_) | |
87 return; | |
88 | |
89 needs_main_frame_ = false; | |
90 next_frame_time_ = base::TimeTicks::Now() + frame_delay_; | |
91 client_->StartMainFrameUpdate(); | |
92 } | |
93 | |
94 } // namespace engine | |
95 } // namespace blimp | |
OLD | NEW |