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

Unified Diff: cc/scheduler/begin_frame_source.cc

Issue 2150533004: cc: Send all begin frames using a PostTask. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@scheduler_unittest_no_deadline
Patch Set: Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: cc/scheduler/begin_frame_source.cc
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc
index 3421ce978d4811b225c053f93039a8c9cd6b3d5e..dabf485d6491dd356483278a0e103eea1ff845e7 100644
--- a/cc/scheduler/begin_frame_source.cc
+++ b/cc/scheduler/begin_frame_source.cc
@@ -14,7 +14,6 @@
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
-#include "cc/scheduler/delay_based_time_source.h"
#include "cc/scheduler/scheduler.h"
namespace cc {
@@ -27,8 +26,7 @@ static const double kDoubleTickDivisor = 2.0;
// BeginFrameObserverBase -----------------------------------------------
BeginFrameObserverBase::BeginFrameObserverBase()
- : last_begin_frame_args_(), dropped_begin_frame_args_(0) {
-}
+ : last_begin_frame_args_(), dropped_begin_frame_args_(0) {}
const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const {
return last_begin_frame_args_;
@@ -49,13 +47,13 @@ SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default;
// BackToBackBeginFrameSource --------------------------------------------
BackToBackBeginFrameSource::BackToBackBeginFrameSource(
- std::unique_ptr<DelayBasedTimeSource> time_source)
- : time_source_(std::move(time_source)), weak_factory_(this) {
- time_source_->SetClient(this);
- // The time_source_ ticks immediately, so we SetActive(true) for a single
- // tick when we need it, and keep it as SetActive(false) otherwise.
- time_source_->SetTimebaseAndInterval(base::TimeTicks(), base::TimeDelta());
-}
+ base::SingleThreadTaskRunner* task_runner)
+ : BackToBackBeginFrameSource(task_runner, nullptr) {}
+
+BackToBackBeginFrameSource::BackToBackBeginFrameSource(
+ base::SingleThreadTaskRunner* task_runner,
+ base::TickClock* clock)
+ : task_runner_(task_runner), clock_(clock), weak_factory_(this) {}
BackToBackBeginFrameSource::~BackToBackBeginFrameSource() = default;
@@ -63,48 +61,68 @@ void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
DCHECK(obs);
DCHECK(observers_.find(obs) == observers_.end());
observers_.insert(obs);
- pending_begin_frame_observers_.insert(obs);
+ if (pending_observers_.empty()) {
+ DCHECK(begin_frame_callback_.IsCancelled());
+ begin_frame_callback_.Reset(
+ base::Bind(&BackToBackBeginFrameSource::SendBeginFrame,
+ weak_factory_.GetWeakPtr()));
+ task_runner_->PostTask(FROM_HERE, begin_frame_callback_.callback());
+ }
+ pending_observers_.insert(obs);
obs->OnBeginFrameSourcePausedChanged(false);
- time_source_->SetActive(true);
}
void BackToBackBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) {
DCHECK(obs);
DCHECK(observers_.find(obs) != observers_.end());
observers_.erase(obs);
- pending_begin_frame_observers_.erase(obs);
- if (observers_.empty())
- time_source_->SetActive(false);
+ pending_observers_.erase(obs);
+ if (pending_observers_.empty())
+ begin_frame_callback_.Cancel();
}
void BackToBackBeginFrameSource::DidFinishFrame(BeginFrameObserver* obs,
size_t remaining_frames) {
if (remaining_frames == 0 && observers_.find(obs) != observers_.end()) {
- pending_begin_frame_observers_.insert(obs);
- time_source_->SetActive(true);
+ if (pending_observers_.empty()) {
+ DCHECK(begin_frame_callback_.IsCancelled());
+ begin_frame_callback_.Reset(
+ base::Bind(&BackToBackBeginFrameSource::SendBeginFrame,
+ weak_factory_.GetWeakPtr()));
+ task_runner_->PostTask(FROM_HERE, begin_frame_callback_.callback());
+ }
+ pending_observers_.insert(obs);
}
}
-void BackToBackBeginFrameSource::OnTimerTick() {
- base::TimeTicks frame_time = time_source_->LastTickTime();
+void BackToBackBeginFrameSource::SendBeginFrame() {
+ DCHECK(!pending_observers_.empty());
+ begin_frame_callback_.Cancel();
+ std::unordered_set<BeginFrameObserver*> pending_observers;
+ pending_observers.swap(pending_observers_);
+
+ base::TimeTicks frame_time =
+ clock_ ? clock_->NowTicks() : base::TimeTicks::Now();
brianderson 2016/07/13 21:14:49 Maybe use a base::DefaultTickClock instead of chec
sunnyps 2016/07/13 21:24:53 I tried that but then DelayBasedTimeSource ended u
base::TimeDelta default_interval = BeginFrameArgs::DefaultInterval();
BeginFrameArgs args = BeginFrameArgs::Create(
BEGINFRAME_FROM_HERE, frame_time, frame_time + default_interval,
default_interval, BeginFrameArgs::NORMAL);
- // This must happen after getting the LastTickTime() from the time source.
- time_source_->SetActive(false);
-
- std::unordered_set<BeginFrameObserver*> pending_observers;
- pending_observers.swap(pending_begin_frame_observers_);
for (BeginFrameObserver* obs : pending_observers)
obs->OnBeginFrame(args);
}
// DelayBasedBeginFrameSource ---------------------------------------------
DelayBasedBeginFrameSource::DelayBasedBeginFrameSource(
- std::unique_ptr<DelayBasedTimeSource> time_source)
- : time_source_(std::move(time_source)) {
+ base::SingleThreadTaskRunner* task_runner)
+ : DelayBasedBeginFrameSource(task_runner, nullptr) {}
+
+DelayBasedBeginFrameSource::DelayBasedBeginFrameSource(
+ base::SingleThreadTaskRunner* task_runner,
+ base::TickClock* clock)
+ : time_source_(new DelayBasedTimeSource(task_runner, clock)),
+ task_runner_(task_runner),
+ weak_factory_(this) {
time_source_->SetClient(this);
}
@@ -145,27 +163,31 @@ void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
observers_.insert(obs);
obs->OnBeginFrameSourcePausedChanged(false);
time_source_->SetActive(true);
- BeginFrameArgs args = CreateBeginFrameArgs(
- time_source_->NextTickTime() - time_source_->Interval(),
- BeginFrameArgs::MISSED);
- BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
- if (!last_args.IsValid() ||
- (args.frame_time >
- last_args.frame_time + args.interval / kDoubleTickDivisor)) {
- obs->OnBeginFrame(args);
+
+ if (missed_frame_observers_.empty()) {
+ DCHECK(missed_frame_callback_.IsCancelled());
+ missed_frame_callback_.Reset(
+ base::Bind(&DelayBasedBeginFrameSource::SendMissedBeginFrame,
+ weak_factory_.GetWeakPtr()));
+ task_runner_->PostTask(FROM_HERE, missed_frame_callback_.callback());
}
+ missed_frame_observers_.insert(obs);
}
void DelayBasedBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) {
DCHECK(obs);
DCHECK(observers_.find(obs) != observers_.end());
-
+ missed_frame_observers_.erase(obs);
+ if (missed_frame_observers_.empty())
+ missed_frame_callback_.Cancel();
observers_.erase(obs);
if (observers_.empty())
time_source_->SetActive(false);
}
void DelayBasedBeginFrameSource::OnTimerTick() {
+ missed_frame_callback_.Cancel();
+ missed_frame_observers_.clear();
BeginFrameArgs args = CreateBeginFrameArgs(time_source_->LastTickTime(),
BeginFrameArgs::NORMAL);
std::unordered_set<BeginFrameObserver*> observers(observers_);
@@ -178,4 +200,24 @@ void DelayBasedBeginFrameSource::OnTimerTick() {
}
}
+void DelayBasedBeginFrameSource::SendMissedBeginFrame() {
+ DCHECK(!missed_frame_observers_.empty());
+ missed_frame_callback_.Cancel();
+ std::unordered_set<BeginFrameObserver*> missed_frame_observers;
+ missed_frame_observers.swap(missed_frame_observers_);
+
+ BeginFrameArgs args = CreateBeginFrameArgs(
+ time_source_->NextTickTime() - time_source_->Interval(),
+ BeginFrameArgs::MISSED);
+
+ for (BeginFrameObserver* obs : missed_frame_observers) {
+ BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
+ if (!last_args.IsValid() ||
+ (args.frame_time >
+ last_args.frame_time + args.interval / kDoubleTickDivisor)) {
+ obs->OnBeginFrame(args);
+ }
+ }
+}
+
} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698