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

Side by Side Diff: mc/scheduler/timer.cc

Issue 731893002: Add a simple scheduler for animation frames (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Fix math Created 6 years, 1 month 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
« no previous file with comments | « mc/scheduler/timer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include "mc/scheduler/timer.h"
6
7 #include <cstdlib>
8
9 #include "base/bind.h"
10 #include "base/tracked_objects.h"
11
12 namespace mc {
13
14 // We're willing to slop around 1/4 of a tick duration to avoid trashing our
15 // client with irregular ticks.
16 static const int64 kTickSlop = 4;
17
18 Timer::Client::~Client() {
19 }
20
21 Timer::Timer(Client* client,
22 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
23 : client_(client),
24 task_runner_(task_runner),
25 enabled_(false),
26 weak_factory_(this) {
27 DCHECK(client_);
28 }
29
30 Timer::~Timer() {
31 }
32
33 void Timer::SetEnabled(bool enabled) {
34 enabled_ = enabled;
35
36 if (enabled_ && current_target_.is_null())
37 ScheduleNextTick(base::TimeTicks::Now());
38 }
39
40 void Timer::SetInterval(const TimeInterval& interval) {
41 interval_ = interval;
42
43 // We don't have a tick scheduled, so there's no need to reschedule it.
44 if (current_target_.is_null())
45 return;
46
47 base::TimeTicks now = base::TimeTicks::Now();
48
49 base::TimeTicks new_target = NextTickTarget(now);
50 base::TimeDelta delta = base::TimeDelta::FromInternalValue(
51 std::abs((new_target - current_target_).ToInternalValue()));
52
53 if (delta * kTickSlop < interval_.duration)
54 return;
55
56 current_target_ = base::TimeTicks();
57 weak_factory_.InvalidateWeakPtrs();
58 PostTickTask(now, new_target);
59 }
60
61 base::TimeTicks Timer::NextTickTarget(base::TimeTicks now) {
62 base::TimeTicks target = interval_.NextAfter(now);
63
64 // If we're targeting a time that's too soon since the last tick, we push out
65 // the target to the next tick.
66 if ((target - last_tick_) * kTickSlop < interval_.duration)
67 target += interval_.duration;
68
69 return target;
70 }
71
72 void Timer::ScheduleNextTick(base::TimeTicks now) {
73 PostTickTask(now, NextTickTarget(now));
74 }
75
76 void Timer::PostTickTask(base::TimeTicks now, base::TimeTicks target) {
77 DCHECK(current_target_.is_null());
78 current_target_ = target;
79 task_runner_->PostDelayedTask(
80 FROM_HERE, base::Bind(&Timer::OnTimerFired, weak_factory_.GetWeakPtr()),
81 current_target_ - now);
82 }
83
84 void Timer::OnTimerFired() {
85 current_target_ = base::TimeTicks();
86 if (!enabled_)
87 return;
88 base::TimeTicks now = base::TimeTicks::Now();
89 ScheduleNextTick(now);
90 last_tick_ = now;
91 client_->OnTimerTick(now);
92 // We might be deleted here.
93 }
94 }
OLDNEW
« no previous file with comments | « mc/scheduler/timer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698