summaryrefslogtreecommitdiffstats
path: root/cc/scheduler
diff options
context:
space:
mode:
authorsunnyps <sunnyps@chromium.org>2016-02-02 12:53:54 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-02 20:54:44 +0000
commit6ab38e4f06caa13bbcdfaa652109d114576c1cbe (patch)
treef4598dab99df0df2f41b317c85e15129e91d236b /cc/scheduler
parentf6ce6c613ba8ea75fe56125dc67bac6f22454738 (diff)
downloadchromium_src-6ab38e4f06caa13bbcdfaa652109d114576c1cbe.zip
chromium_src-6ab38e4f06caa13bbcdfaa652109d114576c1cbe.tar.gz
chromium_src-6ab38e4f06caa13bbcdfaa652109d114576c1cbe.tar.bz2
cc: Add support for multiple observers to BeginFrameSource.
Multiple observers can be added to BeginFrameSource. The SetNeedsBeginFrames method was removed because it doesn't make sense with multiple observers. BeginFrameSources are expected to produce BeginFrames as long as there are registered observers. There are helper methods in BeginFrameSourceBase to make this easy. Changes had to be made to DelayBasedTimeSource as its MISSED BeginFrame logic was moved to SyntheticBFS for dealing with multiple observers. BUG=580352 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1611633004 Cr-Commit-Position: refs/heads/master@{#373031}
Diffstat (limited to 'cc/scheduler')
-rw-r--r--cc/scheduler/begin_frame_source.cc300
-rw-r--r--cc/scheduler/begin_frame_source.h64
-rw-r--r--cc/scheduler/begin_frame_source_unittest.cc375
-rw-r--r--cc/scheduler/delay_based_time_source.cc66
-rw-r--r--cc/scheduler/delay_based_time_source.h5
-rw-r--r--cc/scheduler/delay_based_time_source_unittest.cc61
-rw-r--r--cc/scheduler/scheduler.cc28
-rw-r--r--cc/scheduler/scheduler.h1
-rw-r--r--cc/scheduler/scheduler_unittest.cc281
9 files changed, 634 insertions, 547 deletions
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc
index d96ef4e..5447086 100644
--- a/cc/scheduler/begin_frame_source.cc
+++ b/cc/scheduler/begin_frame_source.cc
@@ -10,6 +10,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
+#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"
@@ -17,12 +18,18 @@
namespace cc {
+namespace {
+// kDoubleTickDivisor prevents the SyntheticBFS from sending BeginFrames too
+// often to an observer.
+static const double kDoubleTickDivisor = 2.0;
+}
+
// BeginFrameObserverBase -----------------------------------------------
BeginFrameObserverBase::BeginFrameObserverBase()
: last_begin_frame_args_(), dropped_begin_frame_args_(0) {
}
-const BeginFrameArgs BeginFrameObserverBase::LastUsedBeginFrameArgs() const {
+const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const {
return last_begin_frame_args_;
}
void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) {
@@ -51,69 +58,49 @@ void BeginFrameObserverBase::AsValueInto(
// BeginFrameSourceBase ------------------------------------------------------
BeginFrameSourceBase::BeginFrameSourceBase()
- : observer_(NULL),
- needs_begin_frames_(false),
- paused_(false),
- inside_as_value_into_(false) {
- DCHECK(!observer_);
- DCHECK_EQ(inside_as_value_into_, false);
-}
-
-bool BeginFrameSourceBase::NeedsBeginFrames() const {
- return needs_begin_frames_;
-}
-
-void BeginFrameSourceBase::SetNeedsBeginFrames(bool needs_begin_frames) {
- DEBUG_FRAMES("BeginFrameSourceBase::SetNeedsBeginFrames",
- "current state",
- needs_begin_frames_,
- "new state",
- needs_begin_frames);
- if (needs_begin_frames_ != needs_begin_frames) {
- needs_begin_frames_ = needs_begin_frames;
- OnNeedsBeginFramesChange(needs_begin_frames);
- }
-}
+ : paused_(false), inside_as_value_into_(false) {}
+
+BeginFrameSourceBase::~BeginFrameSourceBase() {}
void BeginFrameSourceBase::AddObserver(BeginFrameObserver* obs) {
- DEBUG_FRAMES("BeginFrameSourceBase::AddObserver",
- "current observer",
- observer_,
- "to add observer",
- obs);
- DCHECK(!observer_);
- observer_ = obs;
- if (observer_)
- return observer_->OnBeginFrameSourcePausedChanged(paused_);
+ DEBUG_FRAMES("BeginFrameSourceBase::AddObserver", "num observers",
+ observers_.size(), "to add observer", obs);
+ DCHECK(obs);
+ DCHECK(observers_.find(obs) == observers_.end())
+ << "AddObserver cannot be called with an observer that was already added";
+ bool observers_was_empty = observers_.empty();
+ observers_.insert(obs);
+ if (observers_was_empty)
+ OnNeedsBeginFramesChanged(true);
+ obs->OnBeginFrameSourcePausedChanged(paused_);
}
void BeginFrameSourceBase::RemoveObserver(BeginFrameObserver* obs) {
- DEBUG_FRAMES("BeginFrameSourceBase::RemoveObserver",
- "current observer",
- observer_,
- "to remove observer",
- obs);
- DCHECK_EQ(observer_, obs);
- observer_ = NULL;
+ DEBUG_FRAMES("BeginFrameSourceBase::RemoveObserver", "num observers",
+ observers_.size(), "removed observer", obs);
+ DCHECK(obs);
+ DCHECK(observers_.find(obs) != observers_.end())
+ << "RemoveObserver cannot be called with an observer that wasn't added";
+ observers_.erase(obs);
+ if (observers_.empty())
+ OnNeedsBeginFramesChanged(false);
}
void BeginFrameSourceBase::CallOnBeginFrame(const BeginFrameArgs& args) {
- DEBUG_FRAMES("BeginFrameSourceBase::CallOnBeginFrame",
- "current observer",
- observer_,
- "args",
- args.AsValue());
- if (observer_) {
- return observer_->OnBeginFrame(args);
- }
+ DEBUG_FRAMES("BeginFrameSourceBase::CallOnBeginFrame", "num observers",
+ observers_.size(), "args", args.AsValue());
+ std::set<BeginFrameObserver*> observers(observers_);
+ for (auto& it : observers)
+ it->OnBeginFrame(args);
}
void BeginFrameSourceBase::SetBeginFrameSourcePaused(bool paused) {
if (paused_ == paused)
return;
paused_ = paused;
- if (observer_)
- return observer_->OnBeginFrameSourcePausedChanged(paused_);
+ std::set<BeginFrameObserver*> observers(observers_);
+ for (auto& it : observers)
+ it->OnBeginFrameSourcePausedChanged(paused_);
}
// Tracing support
@@ -126,16 +113,17 @@ void BeginFrameSourceBase::AsValueInto(
return;
}
- if (observer_) {
+ {
base::AutoReset<bool> prevent_loops(
const_cast<bool*>(&inside_as_value_into_), true);
- dict->BeginDictionary("observer");
- observer_->AsValueInto(dict);
- dict->EndDictionary();
- } else {
- dict->SetString("observer", "NULL");
+ dict->BeginArray("observers");
+ for (const auto& it : observers_) {
+ dict->BeginDictionary();
+ it->AsValueInto(dict);
+ dict->EndDictionary();
+ }
+ dict->EndArray();
}
- dict->SetBoolean("needs_begin_frames", NeedsBeginFrames());
}
// BackToBackBeginFrameSource --------------------------------------------
@@ -148,11 +136,8 @@ BackToBackBeginFrameSource::BackToBackBeginFrameSource(
base::SingleThreadTaskRunner* task_runner)
: BeginFrameSourceBase(),
task_runner_(task_runner),
- send_begin_frame_posted_(false),
weak_factory_(this) {
DCHECK(task_runner);
- DCHECK_EQ(needs_begin_frames_, false);
- DCHECK_EQ(send_begin_frame_posted_, false);
}
BackToBackBeginFrameSource::~BackToBackBeginFrameSource() {
@@ -162,26 +147,33 @@ base::TimeTicks BackToBackBeginFrameSource::Now() {
return base::TimeTicks::Now();
}
-void BackToBackBeginFrameSource::OnNeedsBeginFramesChange(
- bool needs_begin_frames) {
- if (!needs_begin_frames)
- return;
+// BeginFrameSourceBase support
+void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
+ DCHECK(observers_.empty())
+ << "BackToBackBeginFrameSource only supports a single observer";
+ BeginFrameSourceBase::AddObserver(obs);
+}
- if (send_begin_frame_posted_)
- return;
+void BackToBackBeginFrameSource::OnNeedsBeginFramesChanged(
+ bool needs_begin_frames) {
+ if (needs_begin_frames) {
+ PostBeginFrame();
+ } else {
+ begin_frame_task_.Cancel();
+ }
+}
- send_begin_frame_posted_ = true;
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&BackToBackBeginFrameSource::BeginFrame,
- weak_factory_.GetWeakPtr()));
+void BackToBackBeginFrameSource::PostBeginFrame() {
+ DCHECK(needs_begin_frames());
+ begin_frame_task_.Reset(base::Bind(&BackToBackBeginFrameSource::BeginFrame,
+ weak_factory_.GetWeakPtr()));
+ task_runner_->PostTask(FROM_HERE, begin_frame_task_.callback());
}
void BackToBackBeginFrameSource::BeginFrame() {
- send_begin_frame_posted_ = false;
-
- if (!needs_begin_frames_)
- return;
-
+ DCHECK(needs_begin_frames());
+ DCHECK(!begin_frame_task_.IsCancelled());
+ begin_frame_task_.Cancel();
base::TimeTicks now = Now();
BeginFrameArgs args = BeginFrameArgs::Create(
BEGINFRAME_FROM_HERE, now, now + BeginFrameArgs::DefaultInterval(),
@@ -189,12 +181,10 @@ void BackToBackBeginFrameSource::BeginFrame() {
CallOnBeginFrame(args);
}
-// BeginFrameSource support
-
void BackToBackBeginFrameSource::DidFinishFrame(size_t remaining_frames) {
- if (remaining_frames == 0) {
- OnNeedsBeginFramesChange(NeedsBeginFrames());
- }
+ BeginFrameSourceBase::DidFinishFrame(remaining_frames);
+ if (needs_begin_frames() && remaining_frames == 0)
+ PostBeginFrame();
}
// Tracing support
@@ -202,7 +192,6 @@ void BackToBackBeginFrameSource::AsValueInto(
base::trace_event::TracedValue* dict) const {
dict->SetString("type", "BackToBackBeginFrameSource");
BeginFrameSourceBase::AsValueInto(dict);
- dict->SetBoolean("send_begin_frame_posted_", send_begin_frame_posted_);
}
// SyntheticBeginFrameSource ---------------------------------------------
@@ -217,13 +206,10 @@ scoped_ptr<SyntheticBeginFrameSource> SyntheticBeginFrameSource::Create(
SyntheticBeginFrameSource::SyntheticBeginFrameSource(
scoped_ptr<DelayBasedTimeSource> time_source)
: BeginFrameSourceBase(), time_source_(std::move(time_source)) {
- time_source_->SetActive(false);
time_source_->SetClient(this);
}
-SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {
- time_source_->SetActive(false);
-}
+SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {}
void SyntheticBeginFrameSource::OnUpdateVSyncParameters(
base::TimeTicks new_vsync_timebase,
@@ -234,26 +220,42 @@ void SyntheticBeginFrameSource::OnUpdateVSyncParameters(
BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs(
base::TimeTicks frame_time,
BeginFrameArgs::BeginFrameArgsType type) {
- base::TimeTicks deadline = time_source_->NextTickTime();
- return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
+ return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time,
+ time_source_->NextTickTime(),
time_source_->Interval(), type);
}
-// DelayBasedTimeSourceClient support
-void SyntheticBeginFrameSource::OnTimerTick() {
- CallOnBeginFrame(CreateBeginFrameArgs(time_source_->LastTickTime(),
- BeginFrameArgs::NORMAL));
+// BeginFrameSource support
+void SyntheticBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
+ BeginFrameSourceBase::AddObserver(obs);
+ 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);
+ }
}
-// BeginFrameSourceBase support
-void SyntheticBeginFrameSource::OnNeedsBeginFramesChange(
+void SyntheticBeginFrameSource::OnNeedsBeginFramesChanged(
bool needs_begin_frames) {
- base::TimeTicks missed_tick_time =
- time_source_->SetActive(needs_begin_frames);
- if (!missed_tick_time.is_null()) {
- DCHECK(needs_begin_frames);
- CallOnBeginFrame(
- CreateBeginFrameArgs(missed_tick_time, BeginFrameArgs::MISSED));
+ time_source_->SetActive(needs_begin_frames);
+}
+
+// DelayBasedTimeSourceClient support
+void SyntheticBeginFrameSource::OnTimerTick() {
+ BeginFrameArgs args = CreateBeginFrameArgs(time_source_->LastTickTime(),
+ BeginFrameArgs::NORMAL);
+ std::set<BeginFrameObserver*> observers(observers_);
+ for (auto& it : observers) {
+ BeginFrameArgs last_args = it->LastUsedBeginFrameArgs();
+ if (!last_args.IsValid() ||
+ (args.frame_time >
+ last_args.frame_time + args.interval / kDoubleTickDivisor)) {
+ it->OnBeginFrame(args);
+ }
}
}
@@ -275,24 +277,18 @@ scoped_ptr<BeginFrameSourceMultiplexer> BeginFrameSourceMultiplexer::Create() {
BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer()
: BeginFrameSourceBase(),
- minimum_interval_(base::TimeDelta()),
- active_source_(NULL),
- source_list_() {
-}
+ active_source_(nullptr),
+ inside_add_observer_(false) {}
BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer(
base::TimeDelta minimum_interval)
: BeginFrameSourceBase(),
- minimum_interval_(minimum_interval),
- active_source_(NULL),
- source_list_() {
-}
+ active_source_(nullptr),
+ inside_add_observer_(false) {}
BeginFrameSourceMultiplexer::~BeginFrameSourceMultiplexer() {
- if (active_source_) {
- active_source_->SetNeedsBeginFrames(false);
+ if (active_source_ && needs_begin_frames())
active_source_->RemoveObserver(this);
- }
}
void BeginFrameSourceMultiplexer::SetMinimumInterval(
@@ -337,29 +333,18 @@ void BeginFrameSourceMultiplexer::SetActiveSource(
"to become active",
new_source);
- DCHECK(HasSource(new_source) || new_source == NULL);
+ DCHECK(HasSource(new_source) || new_source == nullptr);
- bool needs_begin_frames = NeedsBeginFrames();
- if (active_source_) {
- if (needs_begin_frames)
- SetNeedsBeginFrames(false);
+ if (active_source_ == new_source)
+ return;
- // Technically we shouldn't need to remove observation, but this prevents
- // the case where SetNeedsBeginFrames message gets to the source after a
- // message has already been sent.
+ if (active_source_ && needs_begin_frames())
active_source_->RemoveObserver(this);
- active_source_ = NULL;
- }
- DCHECK(!active_source_);
+
active_source_ = new_source;
- if (active_source_) {
+ if (active_source_ && needs_begin_frames())
active_source_->AddObserver(this);
-
- if (needs_begin_frames) {
- SetNeedsBeginFrames(true);
- }
- }
}
const BeginFrameSource* BeginFrameSourceMultiplexer::ActiveSource() {
@@ -381,42 +366,50 @@ void BeginFrameSourceMultiplexer::OnBeginFrame(const BeginFrameArgs& args) {
"using",
"new args",
args.AsValue());
+ last_begin_frame_args_ = args;
CallOnBeginFrame(args);
}
-const BeginFrameArgs BeginFrameSourceMultiplexer::LastUsedBeginFrameArgs()
+const BeginFrameArgs& BeginFrameSourceMultiplexer::LastUsedBeginFrameArgs()
const {
- if (observer_)
- return observer_->LastUsedBeginFrameArgs();
- else
- return BeginFrameArgs();
+ return last_begin_frame_args_;
}
void BeginFrameSourceMultiplexer::OnBeginFrameSourcePausedChanged(bool paused) {
- BeginFrameSourceBase::SetBeginFrameSourcePaused(paused);
-}
-
-// BeginFrameSource support
-void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange(
- bool needs_begin_frames) {
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange",
- "active_source", active_source_, "needs_begin_frames",
- needs_begin_frames);
- if (active_source_) {
- active_source_->SetNeedsBeginFrames(needs_begin_frames);
- } else {
- DCHECK(!needs_begin_frames);
+ if (paused_ == paused)
+ return;
+ paused_ = paused;
+ if (!inside_add_observer_) {
+ std::set<BeginFrameObserver*> observers(observers_);
+ for (auto& it : observers)
+ it->OnBeginFrameSourcePausedChanged(paused);
}
}
+// BeginFrameSource support
void BeginFrameSourceMultiplexer::DidFinishFrame(size_t remaining_frames) {
DEBUG_FRAMES("BeginFrameSourceMultiplexer::DidFinishFrame",
"active_source",
active_source_,
"remaining_frames",
remaining_frames);
- if (active_source_) {
+ if (active_source_)
active_source_->DidFinishFrame(remaining_frames);
+}
+
+void BeginFrameSourceMultiplexer::AddObserver(BeginFrameObserver* obs) {
+ base::AutoReset<bool> reset(&inside_add_observer_, true);
+ BeginFrameSourceBase::AddObserver(obs);
+}
+
+void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChanged(
+ bool needs_begin_frames) {
+ if (!active_source_)
+ return;
+ if (needs_begin_frames) {
+ active_source_->AddObserver(this);
+ } else {
+ active_source_->RemoveObserver(this);
}
}
@@ -426,11 +419,10 @@ void BeginFrameSourceMultiplexer::AsValueInto(
dict->SetString("type", "BeginFrameSourceMultiplexer");
dict->SetInteger("minimum_interval_us", minimum_interval_.InMicroseconds());
- if (observer_) {
- dict->BeginDictionary("last_begin_frame_args");
- observer_->LastUsedBeginFrameArgs().AsValueInto(dict);
- dict->EndDictionary();
- }
+
+ dict->BeginDictionary("last_begin_frame_args");
+ last_begin_frame_args_.AsValueInto(dict);
+ dict->EndDictionary();
if (active_source_) {
dict->BeginDictionary("active_source");
@@ -458,17 +450,15 @@ bool BeginFrameSourceMultiplexer::HasSource(BeginFrameSource* source) {
bool BeginFrameSourceMultiplexer::IsIncreasing(const BeginFrameArgs& args) {
DCHECK(args.IsValid());
- if (!observer_)
- return false;
// If the last begin frame is invalid, then any new begin frame is valid.
- if (!observer_->LastUsedBeginFrameArgs().IsValid())
+ if (!last_begin_frame_args_.IsValid())
return true;
// Only allow new args have a *strictly bigger* frame_time value and statisfy
// minimum interval requirement.
return (args.frame_time >=
- observer_->LastUsedBeginFrameArgs().frame_time + minimum_interval_);
+ last_begin_frame_args_.frame_time + minimum_interval_);
}
} // namespace cc
diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h
index a77d546..0850884 100644
--- a/cc/scheduler/begin_frame_source.h
+++ b/cc/scheduler/begin_frame_source.h
@@ -58,7 +58,7 @@ class CC_EXPORT BeginFrameObserver {
// These requirements are designed to allow chaining and nesting of
// BeginFrameObservers which filter the incoming BeginFrame messages while
// preventing "double dropping" and other bad side effects.
- virtual const BeginFrameArgs LastUsedBeginFrameArgs() const = 0;
+ virtual const BeginFrameArgs& LastUsedBeginFrameArgs() const = 0;
virtual void OnBeginFrameSourcePausedChanged(bool paused) = 0;
@@ -85,7 +85,7 @@ class CC_EXPORT BeginFrameObserverBase : public BeginFrameObserver {
// OnBeginFrameDerivedImpl and updates the last_begin_frame_args_ value on
// true.
void OnBeginFrame(const BeginFrameArgs& args) override;
- const BeginFrameArgs LastUsedBeginFrameArgs() const override;
+ const BeginFrameArgs& LastUsedBeginFrameArgs() const override;
// Outputs last_begin_frame_args_
void AsValueInto(base::trace_event::TracedValue* dict) const override;
@@ -115,21 +115,14 @@ class CC_EXPORT BeginFrameSource {
public:
virtual ~BeginFrameSource() {}
- // SetNeedsBeginFrames is the on/off "switch" for the BeginFrameSource. When
- // set to false no more BeginFrame messages should be sent to observer.
- virtual bool NeedsBeginFrames() const = 0;
- virtual void SetNeedsBeginFrames(bool needs_begin_frames) = 0;
-
// DidFinishFrame provides back pressure to a frame source about frame
// processing (rather than toggling SetNeedsBeginFrames every frame). It is
// used by systems like the BackToBackFrameSource to make sure only one frame
// is pending at a time.
virtual void DidFinishFrame(size_t remaining_frames) = 0;
- // Add/Remove an observer from the source.
- // *At the moment* only a single observer can be added to the source, however
- // in the future this may be extended to allow multiple observers.
- // If making this change, please use base::ObserverList to do so.
+ // Add/Remove an observer from the source. When no observers are added the BFS
+ // should shut down its timers, disable vsync, etc.
virtual void AddObserver(BeginFrameObserver* obs) = 0;
virtual void RemoveObserver(BeginFrameObserver* obs) = 0;
@@ -150,14 +143,12 @@ class CC_EXPORT BeginFrameSource {
// in their own AsValueInto implementation.
class CC_EXPORT BeginFrameSourceBase : public BeginFrameSource {
public:
- ~BeginFrameSourceBase() override {}
+ ~BeginFrameSourceBase() override;
// BeginFrameSource
- bool NeedsBeginFrames() const final;
- void SetNeedsBeginFrames(bool needs_begin_frames) final;
void DidFinishFrame(size_t remaining_frames) override {}
- void AddObserver(BeginFrameObserver* obs) final;
- void RemoveObserver(BeginFrameObserver* obs) final;
+ void AddObserver(BeginFrameObserver* obs) override;
+ void RemoveObserver(BeginFrameObserver* obs) override;
void SetClientReady() override {}
// Tracing support - Recommend (but not required) to call this implementation
@@ -172,12 +163,13 @@ class CC_EXPORT BeginFrameSourceBase : public BeginFrameSource {
void CallOnBeginFrame(const BeginFrameArgs& args);
void SetBeginFrameSourcePaused(bool paused);
- // This method should be overridden if you want to change some behaviour on
- // needs_begin_frames change.
- virtual void OnNeedsBeginFramesChange(bool needs_begin_frames) {}
+ // This notifies that the subclass that it must turn on or off its mechnanism
+ // for producing BeginFrames.
+ virtual void OnNeedsBeginFramesChanged(bool needs_begin_frames) {}
+
+ bool needs_begin_frames() const { return !observers_.empty(); }
- BeginFrameObserver* observer_;
- bool needs_begin_frames_;
+ std::set<BeginFrameObserver*> observers_;
bool paused_;
private:
@@ -197,6 +189,10 @@ class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSourceBase {
// BeginFrameSource
void DidFinishFrame(size_t remaining_frames) override;
+ // BeginFrameSourceBase
+ void AddObserver(BeginFrameObserver* obs) override;
+ void OnNeedsBeginFramesChanged(bool needs_begin_frames) override;
+
// Tracing
void AsValueInto(base::trace_event::TracedValue* dict) const override;
@@ -206,12 +202,9 @@ class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSourceBase {
virtual base::TimeTicks Now(); // Now overridable for testing
base::SingleThreadTaskRunner* task_runner_;
+ base::CancelableClosure begin_frame_task_;
- bool send_begin_frame_posted_;
-
- // BeginFrameSourceBase
- void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
-
+ void PostBeginFrame();
void BeginFrame();
private:
@@ -233,6 +226,10 @@ class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSourceBase,
void OnUpdateVSyncParameters(base::TimeTicks new_vsync_timebase,
base::TimeDelta new_vsync_interval);
+ // BeginFrameSourceBase
+ void AddObserver(BeginFrameObserver* obs) override;
+ void OnNeedsBeginFramesChanged(bool needs_begin_frames) override;
+
// Tracing
void AsValueInto(base::trace_event::TracedValue* dict) const override;
@@ -246,9 +243,6 @@ class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSourceBase,
BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time,
BeginFrameArgs::BeginFrameArgsType type);
- // BeginFrameSourceBase
- void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
-
scoped_ptr<DelayBasedTimeSource> time_source_;
private:
@@ -276,14 +270,13 @@ class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSourceBase,
// calls to preserve the monotonicity of the BeginFrameArgs when switching
// sources.
void OnBeginFrame(const BeginFrameArgs& args) override;
- const BeginFrameArgs LastUsedBeginFrameArgs() const override;
+ const BeginFrameArgs& LastUsedBeginFrameArgs() const override;
void OnBeginFrameSourcePausedChanged(bool paused) override;
- // BeginFrameSource
- void DidFinishFrame(size_t remaining_frames) override;
-
// BeginFrameSourceBase
- void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
+ void DidFinishFrame(size_t remaining_frames) override;
+ void AddObserver(BeginFrameObserver* obs) override;
+ void OnNeedsBeginFramesChanged(bool needs_begin_frames) override;
// Tracing
void AsValueInto(base::trace_event::TracedValue* dict) const override;
@@ -300,6 +293,9 @@ class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSourceBase,
BeginFrameSource* active_source_;
std::set<BeginFrameSource*> source_list_;
+ BeginFrameArgs last_begin_frame_args_;
+ bool inside_add_observer_;
+
private:
DISALLOW_COPY_AND_ASSIGN(BeginFrameSourceMultiplexer);
};
diff --git a/cc/scheduler/begin_frame_source_unittest.cc b/cc/scheduler/begin_frame_source_unittest.cc
index 4591559c..16640ee 100644
--- a/cc/scheduler/begin_frame_source_unittest.cc
+++ b/cc/scheduler/begin_frame_source_unittest.cc
@@ -14,6 +14,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using testing::Mock;
+using testing::StrictMock;
namespace cc {
namespace {
@@ -78,28 +79,32 @@ TEST(BeginFrameSourceBaseTest, ObserverManipulation) {
EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
source.AddObserver(&obs);
- EXPECT_EQ(&obs, source.GetObserver());
+ EXPECT_TRUE(source.has_observers());
#ifndef NDEBUG
- // Adding an observer when an observer already exists should DCHECK fail.
- EXPECT_DEATH({ source.AddObserver(&otherObs); }, "");
+ // Adding an observer when it already exists should DCHECK fail.
+ EXPECT_DEATH({ source.AddObserver(&obs); }, "");
// Removing wrong observer should DCHECK fail.
EXPECT_DEATH({ source.RemoveObserver(&otherObs); }, "");
// Removing an observer when there is no observer should DCHECK fail.
- EXPECT_DEATH({
- source.RemoveObserver(&obs);
- source.RemoveObserver(&obs);
- },
- "");
+ EXPECT_DEATH(
+ {
+ source.RemoveObserver(&obs);
+ source.RemoveObserver(&obs);
+ },
+ "");
#endif
+
source.RemoveObserver(&obs);
+ EXPECT_FALSE(source.has_observers());
EXPECT_BEGIN_FRAME_SOURCE_PAUSED(otherObs, false);
source.AddObserver(&otherObs);
- EXPECT_EQ(&otherObs, source.GetObserver());
+ EXPECT_TRUE(source.has_observers());
source.RemoveObserver(&otherObs);
+ EXPECT_FALSE(source.has_observers());
}
TEST(BeginFrameSourceBaseTest, Observer) {
@@ -123,15 +128,6 @@ TEST(BeginFrameSourceBaseTest, NoObserver) {
SEND_BEGIN_FRAME_DROP(source, 100, 200, 300);
}
-TEST(BeginFrameSourceBaseTest, NeedsBeginFrames) {
- FakeBeginFrameSource source;
- EXPECT_FALSE(source.NeedsBeginFrames());
- source.SetNeedsBeginFrames(true);
- EXPECT_TRUE(source.NeedsBeginFrames());
- source.SetNeedsBeginFrames(false);
- EXPECT_FALSE(source.NeedsBeginFrames());
-}
-
TEST(BeginFrameSourceBaseTest, SetBeginFrameSourcePaused) {
FakeBeginFrameSource source;
MockBeginFrameObserver obs;
@@ -144,6 +140,38 @@ TEST(BeginFrameSourceBaseTest, SetBeginFrameSourcePaused) {
source.SetBeginFrameSourcePaused(false);
}
+TEST(BeginFrameSourceBaseTest, MultipleObservers) {
+ FakeBeginFrameSource source;
+ StrictMock<MockBeginFrameObserver> obs1, obs2;
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
+ source.AddObserver(&obs1);
+
+ EXPECT_BEGIN_FRAME_USED(obs1, 100, 200, 100);
+ SEND_BEGIN_FRAME_USED(source, 100, 200, 100);
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
+ source.AddObserver(&obs2);
+
+ EXPECT_BEGIN_FRAME_USED(obs1, 200, 300, 100);
+ EXPECT_BEGIN_FRAME_USED(obs2, 200, 300, 100);
+ SEND_BEGIN_FRAME_USED(source, 200, 300, 100);
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, true);
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, true);
+ source.SetBeginFrameSourcePaused(true);
+
+ source.RemoveObserver(&obs1);
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
+ source.SetBeginFrameSourcePaused(false);
+
+ EXPECT_BEGIN_FRAME_USED(obs2, 300, 400, 100);
+ SEND_BEGIN_FRAME_USED(source, 300, 400, 100);
+
+ source.RemoveObserver(&obs2);
+}
+
class LoopingBeginFrameObserver : public BeginFrameObserverBase {
public:
BeginFrameSource* source_;
@@ -212,12 +240,9 @@ class BackToBackBeginFrameSourceTest : public ::testing::Test {
now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
task_runner_ =
make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_.get(), false));
- task_runner_->SetRunTaskLimit(1);
source_ = TestBackToBackBeginFrameSource::Create(now_src_.get(),
task_runner_.get());
obs_ = make_scoped_ptr(new ::testing::StrictMock<MockBeginFrameObserver>());
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
- source_->AddObserver(obs_.get());
}
void TearDown() override { obs_.reset(); }
@@ -229,94 +254,106 @@ const int64_t BackToBackBeginFrameSourceTest::kDeadline =
const int64_t BackToBackBeginFrameSourceTest::kInterval =
BeginFrameArgs::DefaultInterval().ToInternalValue();
-TEST_F(BackToBackBeginFrameSourceTest, SetNeedsBeginFramesSendsBeginFrame) {
- EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- source_->SetNeedsBeginFrames(true);
+TEST_F(BackToBackBeginFrameSourceTest, AddObserverSendsBeginFrame) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_TRUE(task_runner_->HasPendingTasks());
- task_runner_->RunUntilIdle();
+ EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
+ task_runner_->RunPendingTasks();
EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
}
TEST_F(BackToBackBeginFrameSourceTest,
- DidFinishFrameThenSetNeedsBeginFramesProducesNoFrame) {
+ DidFinishFrameThenRemoveObserverProducesNoFrame) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- source_->SetNeedsBeginFrames(true);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
- source_->SetNeedsBeginFrames(false);
+ source_->RemoveObserver(obs_.get());
source_->DidFinishFrame(0);
EXPECT_FALSE(task_runner_->HasPendingTasks());
}
TEST_F(BackToBackBeginFrameSourceTest,
- SetNeedsBeginFramesThenDidFinishFrameProducesNoFrame) {
+ RemoveObserverThenDidFinishFrameProducesNoFrame) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- source_->SetNeedsBeginFrames(true);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
- source_->SetNeedsBeginFrames(false);
+ source_->RemoveObserver(obs_.get());
EXPECT_TRUE(task_runner_->HasPendingTasks());
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
}
TEST_F(BackToBackBeginFrameSourceTest,
- DidFinishFrameThenTogglingSetNeedsBeginFramesProducesCorrectFrame) {
+ TogglingObserverThenDidFinishFrameProducesCorrectFrame) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- source_->SetNeedsBeginFrames(true);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
+ source_->RemoveObserver(obs_.get());
- source_->SetNeedsBeginFrames(false);
now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
- source_->DidFinishFrame(0);
- now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
- source_->SetNeedsBeginFrames(false);
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
+
now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
- source_->SetNeedsBeginFrames(true);
+ source_->DidFinishFrame(0);
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
EXPECT_TRUE(task_runner_->HasPendingTasks());
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
}
TEST_F(BackToBackBeginFrameSourceTest,
- TogglingSetNeedsBeginFramesThenDidFinishFrameProducesCorrectFrame) {
+ DidFinishFrameThenTogglingObserverProducesCorrectFrame) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- source_->SetNeedsBeginFrames(true);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
+
now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
- source_->SetNeedsBeginFrames(false);
- now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
- source_->SetNeedsBeginFrames(true);
+ source_->RemoveObserver(obs_.get());
+
now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
+ now_src_->Advance(base::TimeDelta::FromMicroseconds(10));
EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
EXPECT_TRUE(task_runner_->HasPendingTasks());
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
}
-TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNeedsBeginFrameFalse) {
- source_->SetNeedsBeginFrames(false);
+TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNoObserver) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
+ source_->RemoveObserver(obs_.get());
source_->DidFinishFrame(0);
EXPECT_FALSE(task_runner_->RunPendingTasks());
}
TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- source_->SetNeedsBeginFrames(true);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
@@ -330,33 +367,35 @@ TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) {
EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
source_->DidFinishFrame(0);
EXPECT_EQ(base::TimeDelta(), task_runner_->DelayToNextTaskTime());
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
}
TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) {
- source_->SetNeedsBeginFrames(true);
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
source_->DidFinishFrame(0);
EXPECT_BEGIN_FRAME_USED(*obs_, 1200, 1200 + kDeadline, kInterval);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
}
TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
- source_->SetNeedsBeginFrames(true);
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
now_src_->Advance(base::TimeDelta::FromMicroseconds(100));
source_->DidFinishFrame(0);
@@ -364,7 +403,7 @@ TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
EXPECT_BEGIN_FRAME_USED(*obs_, 1150, 1150 + kDeadline, kInterval);
EXPECT_TRUE(task_runner_->HasPendingTasks());
- task_runner_->RunUntilIdle();
+ task_runner_->RunPendingTasks();
}
// SyntheticBeginFrameSource testing ------------------------------------------
@@ -384,26 +423,24 @@ class SyntheticBeginFrameSourceTest : public ::testing::Test {
now_src_.get(), task_runner_.get(),
base::TimeDelta::FromMicroseconds(10000));
obs_ = make_scoped_ptr(new MockBeginFrameObserver());
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
- source_->AddObserver(obs_.get());
}
void TearDown() override { obs_.reset(); }
};
TEST_F(SyntheticBeginFrameSourceTest,
- SetNeedsBeginFramesCallsOnBeginFrameWithMissedTick) {
+ AddObserverCallsOnBeginFrameWithMissedTick) {
now_src_->Advance(base::TimeDelta::FromMicroseconds(9010));
- EXPECT_CALL((*obs_), OnBeginFrame(CreateBeginFrameArgsForTesting(
- BEGINFRAME_FROM_HERE, 10000, 20000, 10000,
- BeginFrameArgs::MISSED)));
- source_->SetNeedsBeginFrames(true); // Should cause the last tick to be sent
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, 10000, 20000, 10000);
+ source_->AddObserver(obs_.get()); // Should cause the last tick to be sent
// No tasks should need to be run for this to occur.
}
-TEST_F(SyntheticBeginFrameSourceTest,
- SetNeedsBeginFramesCallsCausesOnBeginFrame) {
- source_->SetNeedsBeginFrames(true);
+TEST_F(SyntheticBeginFrameSourceTest, AddObserverCallsCausesOnBeginFrame) {
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, 0, 10000, 10000);
+ source_->AddObserver(obs_.get());
EXPECT_EQ(10000, task_runner_->NextTaskTime().ToInternalValue());
EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
@@ -414,20 +451,24 @@ TEST_F(SyntheticBeginFrameSourceTest,
TEST_F(SyntheticBeginFrameSourceTest, BasicOperation) {
task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- source_->SetNeedsBeginFrames(true);
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, 0, 10000, 10000);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
EXPECT_BEGIN_FRAME_USED(*obs_, 20000, 30000, 10000);
EXPECT_BEGIN_FRAME_USED(*obs_, 30000, 40000, 10000);
task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001));
- source_->SetNeedsBeginFrames(false);
+ source_->RemoveObserver(obs_.get());
// No new frames....
task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
}
TEST_F(SyntheticBeginFrameSourceTest, VSyncChanges) {
task_runner_->SetAutoAdvanceNowToPendingTasks(true);
- source_->SetNeedsBeginFrames(true);
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, 0, 10000, 10000);
+ source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
EXPECT_BEGIN_FRAME_USED(*obs_, 20000, 30000, 10000);
@@ -444,6 +485,87 @@ TEST_F(SyntheticBeginFrameSourceTest, VSyncChanges) {
task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
}
+TEST_F(SyntheticBeginFrameSourceTest, MultipleObservers) {
+ StrictMock<MockBeginFrameObserver> obs1, obs2;
+
+ // now_src_ starts off at 1000.
+ task_runner_->RunForPeriod(base::TimeDelta::FromMicroseconds(9010));
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(obs1, 10000, 20000, 10000);
+ source_->AddObserver(&obs1); // Should cause the last tick to be sent
+ // No tasks should need to be run for this to occur.
+
+ EXPECT_BEGIN_FRAME_USED(obs1, 20000, 30000, 10000);
+ task_runner_->RunForPeriod(base::TimeDelta::FromMicroseconds(10000));
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(obs2, 20000, 30000, 10000);
+ source_->AddObserver(&obs2); // Should cause the last tick to be sent
+ // No tasks should need to be run for this to occur.
+
+ EXPECT_BEGIN_FRAME_USED(obs1, 30000, 40000, 10000);
+ EXPECT_BEGIN_FRAME_USED(obs2, 30000, 40000, 10000);
+ task_runner_->RunForPeriod(base::TimeDelta::FromMicroseconds(10000));
+
+ source_->RemoveObserver(&obs1);
+
+ EXPECT_BEGIN_FRAME_USED(obs2, 40000, 50000, 10000);
+ task_runner_->RunForPeriod(base::TimeDelta::FromMicroseconds(10000));
+
+ source_->RemoveObserver(&obs2);
+ task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(50000));
+ EXPECT_FALSE(task_runner_->HasPendingTasks());
+}
+
+TEST_F(SyntheticBeginFrameSourceTest, DoubleTick) {
+ StrictMock<MockBeginFrameObserver> obs;
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(obs, 0, 10000, 10000);
+ source_->AddObserver(&obs);
+
+ source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(5000),
+ base::TimeDelta::FromInternalValue(10000));
+ now_src_->Advance(base::TimeDelta::FromInternalValue(4000));
+
+ // No begin frame received.
+ task_runner_->RunPendingTasks();
+
+ // Begin frame received.
+ source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(10000),
+ base::TimeDelta::FromInternalValue(10000));
+ now_src_->Advance(base::TimeDelta::FromInternalValue(5000));
+ EXPECT_BEGIN_FRAME_USED(obs, 10000, 20000, 10000);
+ task_runner_->RunPendingTasks();
+}
+
+TEST_F(SyntheticBeginFrameSourceTest, DoubleTickMissedFrame) {
+ StrictMock<MockBeginFrameObserver> obs;
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(obs, 0, 10000, 10000);
+ source_->AddObserver(&obs);
+ source_->RemoveObserver(&obs);
+
+ source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(5000),
+ base::TimeDelta::FromInternalValue(10000));
+ now_src_->Advance(base::TimeDelta::FromInternalValue(4000));
+
+ // No missed frame received.
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
+ source_->AddObserver(&obs);
+ source_->RemoveObserver(&obs);
+
+ // Missed frame received.
+ source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(10000),
+ base::TimeDelta::FromInternalValue(10000));
+ now_src_->Advance(base::TimeDelta::FromInternalValue(5000));
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
+ EXPECT_BEGIN_FRAME_USED_MISSED(obs, 10000, 20000, 10000);
+ source_->AddObserver(&obs);
+ source_->RemoveObserver(&obs);
+}
+
// BeginFrameSourceMultiplexer testing -----------------------------------
class BeginFrameSourceMultiplexerTest : public ::testing::Test {
protected:
@@ -511,33 +633,100 @@ TEST_F(BeginFrameSourceMultiplexerTest, SourcesManipulation) {
mux_->RemoveSource(source1_);
}
-TEST_F(BeginFrameSourceMultiplexerTest, NeedsBeginFrames) {
+TEST_F(BeginFrameSourceMultiplexerTest, SwitchActiveSource) {
+ mux_->AddSource(source1_);
+ mux_->AddSource(source2_);
+
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
+
+ MockBeginFrameObserver obs;
+ mux_->AddObserver(&obs);
+
+ mux_->SetActiveSource(source1_);
+ EXPECT_TRUE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
+
+ mux_->SetActiveSource(source2_);
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_TRUE(source2_->has_observers());
+}
+
+TEST_F(BeginFrameSourceMultiplexerTest, SingleObserver) {
mux_->AddSource(source1_);
mux_->AddSource(source2_);
mux_->SetActiveSource(source1_);
- EXPECT_EQ(source1_->NeedsBeginFrames(), false);
- EXPECT_EQ(source2_->NeedsBeginFrames(), false);
- // Check SetNeedsFrames works
- mux_->SetNeedsBeginFrames(true);
- EXPECT_EQ(source1_->NeedsBeginFrames(), true);
- EXPECT_EQ(source2_->NeedsBeginFrames(), false);
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
- mux_->SetNeedsBeginFrames(false);
- EXPECT_EQ(source1_->NeedsBeginFrames(), false);
- EXPECT_EQ(source2_->NeedsBeginFrames(), false);
+ MockBeginFrameObserver obs;
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
+ mux_->AddObserver(&obs);
+ EXPECT_TRUE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
+
+ EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 100);
+ SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 100);
+ SEND_BEGIN_FRAME_DROP(*source2_, 150, 250, 100);
- // Checking that switching the source makes SetNeedsFrames on the
- // subsources correctly.
- mux_->SetNeedsBeginFrames(true);
+ mux_->RemoveObserver(&obs);
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
+}
+TEST_F(BeginFrameSourceMultiplexerTest, MultipleObservers) {
+ mux_->AddSource(source1_);
+ mux_->AddSource(source2_);
mux_->SetActiveSource(source1_);
- EXPECT_EQ(source1_->NeedsBeginFrames(), true);
- EXPECT_EQ(source2_->NeedsBeginFrames(), false);
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
+
+ StrictMock<MockBeginFrameObserver> obs1, obs2;
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
+ mux_->AddObserver(&obs1);
+ EXPECT_TRUE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
+
+ EXPECT_BEGIN_FRAME_USED(obs1, 100, 200, 100);
+ SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 100);
+ SEND_BEGIN_FRAME_DROP(*source2_, 200, 300, 100);
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
+ mux_->AddObserver(&obs2);
+
+ EXPECT_BEGIN_FRAME_USED(obs1, 300, 400, 100);
+ EXPECT_BEGIN_FRAME_USED(obs2, 300, 400, 100);
+ SEND_BEGIN_FRAME_USED(*source1_, 300, 400, 100);
+ SEND_BEGIN_FRAME_DROP(*source2_, 400, 500, 100);
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, true);
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, true);
+ source1_->SetBeginFrameSourcePaused(true);
+
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
+ EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
mux_->SetActiveSource(source2_);
- EXPECT_EQ(source1_->NeedsBeginFrames(), false);
- EXPECT_EQ(source2_->NeedsBeginFrames(), true);
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_TRUE(source2_->has_observers());
+
+ EXPECT_BEGIN_FRAME_USED(obs1, 600, 700, 100);
+ EXPECT_BEGIN_FRAME_USED(obs2, 600, 700, 100);
+ SEND_BEGIN_FRAME_DROP(*source1_, 500, 600, 100);
+ SEND_BEGIN_FRAME_USED(*source2_, 600, 700, 100);
+
+ mux_->RemoveObserver(&obs1);
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_TRUE(source2_->has_observers());
+
+ EXPECT_BEGIN_FRAME_USED(obs2, 800, 900, 100);
+ SEND_BEGIN_FRAME_DROP(*source1_, 700, 800, 100);
+ SEND_BEGIN_FRAME_USED(*source2_, 800, 900, 100);
+
+ mux_->RemoveObserver(&obs2);
+ EXPECT_FALSE(source1_->has_observers());
+ EXPECT_FALSE(source2_->has_observers());
}
TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesSimple) {
diff --git a/cc/scheduler/delay_based_time_source.cc b/cc/scheduler/delay_based_time_source.cc
index 8e633ef..bc9c762 100644
--- a/cc/scheduler/delay_based_time_source.cc
+++ b/cc/scheduler/delay_based_time_source.cc
@@ -19,11 +19,6 @@ namespace cc {
namespace {
-// kDoubleTickDivisor prevents ticks from running within the specified
-// fraction of an interval. This helps account for jitter in the timebase as
-// well as quick timer reactivation.
-static const int kDoubleTickDivisor = 2;
-
// kIntervalChangeThreshold is the fraction of the interval that will trigger an
// immediate interval change. kPhaseChangeThreshold is the fraction of the
// interval that will trigger an immediate phase change. If the changes are
@@ -53,32 +48,21 @@ DelayBasedTimeSource::DelayBasedTimeSource(
DelayBasedTimeSource::~DelayBasedTimeSource() {}
-base::TimeTicks DelayBasedTimeSource::SetActive(bool active) {
+void DelayBasedTimeSource::SetActive(bool active) {
TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active);
if (active == active_)
- return base::TimeTicks();
+ return;
active_ = active;
- if (!active_) {
+ if (active_) {
+ PostNextTickTask(Now());
+ } else {
+ last_tick_time_ = base::TimeTicks();
next_tick_time_ = base::TimeTicks();
tick_closure_.Cancel();
- return base::TimeTicks();
- }
-
- ResetTickTask(Now());
-
- // Determine if there was a tick that was missed while not active.
- base::TimeTicks last_tick_time_if_always_active = next_tick_time_ - interval_;
- base::TimeTicks last_tick_time_threshold =
- last_tick_time_ + interval_ / kDoubleTickDivisor;
- if (last_tick_time_if_always_active > last_tick_time_threshold) {
- last_tick_time_ = last_tick_time_if_always_active;
- return last_tick_time_;
}
-
- return base::TimeTicks();
}
base::TimeDelta DelayBasedTimeSource::Interval() const {
@@ -134,7 +118,7 @@ void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase,
if (interval_change > kIntervalChangeThreshold) {
TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::IntervalChanged",
TRACE_EVENT_SCOPE_THREAD);
- ResetTickTask(Now());
+ PostNextTickTask(Now());
return;
}
@@ -150,7 +134,7 @@ void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase,
phase_change < (1.0 - kPhaseChangeThreshold)) {
TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::PhaseChanged",
TRACE_EVENT_SCOPE_THREAD);
- ResetTickTask(Now());
+ PostNextTickTask(Now());
return;
}
}
@@ -213,37 +197,15 @@ base::TimeTicks DelayBasedTimeSource::Now() const {
// is not reset.
// now=37 tick_target=16.667 new_target=50.000 -->
// tick(), PostDelayedTask(floor(50.000-37)) --> PostDelayedTask(13)
-base::TimeTicks DelayBasedTimeSource::NextTickTarget(
- base::TimeTicks now) const {
- base::TimeTicks next_tick_target =
- now.SnappedToNextTick(timebase_, interval_);
- DCHECK(now <= next_tick_target)
- << "now = " << now.ToInternalValue()
- << "; new_tick_target = " << next_tick_target.ToInternalValue()
- << "; new_interval = " << interval_.InMicroseconds()
- << "; new_timbase = " << timebase_.ToInternalValue();
-
- // Avoid double ticks when:
- // 1) Turning off the timer and turning it right back on.
- // 2) Jittery data is passed to SetTimebaseAndInterval().
- if (next_tick_target - last_tick_time_ <= interval_ / kDoubleTickDivisor)
- next_tick_target += interval_;
-
- return next_tick_target;
-}
-
void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) {
- next_tick_time_ = NextTickTarget(now);
- DCHECK(next_tick_time_ >= now);
- // Post another task *before* the tick and update state
- base::TimeDelta delay = next_tick_time_ - now;
- task_runner_->PostDelayedTask(FROM_HERE, tick_closure_.callback(), delay);
-}
-
-void DelayBasedTimeSource::ResetTickTask(base::TimeTicks now) {
+ next_tick_time_ = now.SnappedToNextTick(timebase_, interval_);
+ if (next_tick_time_ == now)
+ next_tick_time_ += interval_;
+ DCHECK_GT(next_tick_time_, now);
tick_closure_.Reset(base::Bind(&DelayBasedTimeSource::OnTimerTick,
weak_factory_.GetWeakPtr()));
- PostNextTickTask(now);
+ task_runner_->PostDelayedTask(FROM_HERE, tick_closure_.callback(),
+ next_tick_time_ - now);
}
std::string DelayBasedTimeSource::TypeString() const {
diff --git a/cc/scheduler/delay_based_time_source.h b/cc/scheduler/delay_based_time_source.h
index 7f97a91..1300661 100644
--- a/cc/scheduler/delay_based_time_source.h
+++ b/cc/scheduler/delay_based_time_source.h
@@ -49,8 +49,7 @@ class CC_EXPORT DelayBasedTimeSource {
base::TimeDelta Interval() const;
- // Returns the time for the last missed tick.
- base::TimeTicks SetActive(bool active);
+ void SetActive(bool active);
bool Active() const;
// Get the last and next tick times. NextTickTime() returns null when
@@ -69,8 +68,6 @@ class CC_EXPORT DelayBasedTimeSource {
virtual std::string TypeString() const;
private:
- base::TimeTicks NextTickTarget(base::TimeTicks now) const;
-
void PostNextTickTask(base::TimeTicks now);
void ResetTickTask(base::TimeTicks now);
diff --git a/cc/scheduler/delay_based_time_source_unittest.cc b/cc/scheduler/delay_based_time_source_unittest.cc
index 5e224e6..a905fed 100644
--- a/cc/scheduler/delay_based_time_source_unittest.cc
+++ b/cc/scheduler/delay_based_time_source_unittest.cc
@@ -123,7 +123,7 @@ TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenSlightlyAfterRequestedTime) {
}
// At 60Hz, when the tick returns at exactly 2*interval after the requested next
-// time, make sure a 0ms next delay is posted.
+// time, make sure we don't tick unnecessarily.
TEST(DelayBasedTimeSourceTest,
NextDelaySaneWhenExactlyTwiceAfterRequestedTime) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
@@ -141,7 +141,7 @@ TEST(DelayBasedTimeSourceTest,
timer->SetNow(timer->Now() + 2 * Interval());
task_runner->RunPendingTasks();
- EXPECT_EQ(0, task_runner->NextPendingTaskDelay().InMilliseconds());
+ EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
}
// At 60Hz, when the tick returns at 2*interval and a bit after the requested
@@ -189,39 +189,6 @@ TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenHalfAfterRequestedTime) {
EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds());
}
-// If the timebase and interval are updated with a jittery source, we want to
-// make sure we do not double tick.
-TEST(DelayBasedTimeSourceTest, SaneHandlingOfJitteryTimebase) {
- scoped_refptr<base::TestSimpleTaskRunner> task_runner =
- new base::TestSimpleTaskRunner;
- FakeDelayBasedTimeSourceClient client;
- scoped_ptr<FakeDelayBasedTimeSource> timer =
- FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
- timer->SetClient(&client);
- timer->SetActive(true);
- // Run the first tick.
- task_runner->RunPendingTasks();
-
- EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
- // Jitter timebase ~1ms late
- timer->SetNow(timer->Now() + Interval());
- timer->SetTimebaseAndInterval(
- timer->Now() + base::TimeDelta::FromMilliseconds(1), Interval());
- task_runner->RunPendingTasks();
-
- // Without double tick prevention, NextPendingTaskDelay would be 1.
- EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds());
-
- // Jitter timebase ~1ms early
- timer->SetNow(timer->Now() + Interval());
- timer->SetTimebaseAndInterval(
- timer->Now() - base::TimeDelta::FromMilliseconds(1), Interval());
- task_runner->RunPendingTasks();
-
- EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
TEST(DelayBasedTimeSourceTest, HandlesSignificantTimebaseChangesImmediately) {
scoped_refptr<base::TestSimpleTaskRunner> task_runner =
new base::TestSimpleTaskRunner;
@@ -249,7 +216,7 @@ TEST(DelayBasedTimeSourceTest, HandlesSignificantTimebaseChangesImmediately) {
timer->SetTimebaseAndInterval(timer->Now() + jitter, Interval());
EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled.
- EXPECT_EQ(16 + 7, task_runner->NextPendingTaskDelay().InMilliseconds());
+ EXPECT_EQ(7, task_runner->NextPendingTaskDelay().InMilliseconds());
// Tick, then shift timebase by -7ms.
timer->SetNow(timer->Now() + Interval() + jitter);
@@ -345,7 +312,7 @@ TEST(DelayBasedTimeSourceTest, JitteryRuntimeWithFutureTimebases) {
timer->SetTimebaseAndInterval(future_timebase, Interval());
timer->SetNow(timer->Now() + Interval() - jitter1);
task_runner->RunPendingTasks();
- EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds());
+ EXPECT_EQ(1, task_runner->NextPendingTaskDelay().InMilliseconds());
// Tick with 0ms of jitter
future_timebase += Interval();
@@ -376,7 +343,7 @@ TEST(DelayBasedTimeSourceTest, JitteryRuntimeWithFutureTimebases) {
timer->SetTimebaseAndInterval(future_timebase, Interval());
timer->SetNow(timer->Now() + Interval() - jitter8);
task_runner->RunPendingTasks();
- EXPECT_EQ(24, task_runner->NextPendingTaskDelay().InMilliseconds());
+ EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds());
// Tick with 0ms of jitter
future_timebase += Interval();
@@ -407,7 +374,7 @@ TEST(DelayBasedTimeSourceTest, JitteryRuntimeWithFutureTimebases) {
timer->SetTimebaseAndInterval(future_timebase, Interval());
timer->SetNow(timer->Now() + Interval() - jitter15);
task_runner->RunPendingTasks();
- EXPECT_EQ(31, task_runner->NextPendingTaskDelay().InMilliseconds());
+ EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds());
// Tick with 0ms of jitter
future_timebase += Interval();
@@ -509,21 +476,5 @@ TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateAfterNextTickTime) {
EXPECT_EQ(13, task_runner->NextPendingTaskDelay().InMilliseconds());
}
-TEST(DelayBasedTimeSourceTest, TestReturnValueWhenTimerIsDeActivated) {
- scoped_refptr<base::TestSimpleTaskRunner> task_runner =
- new base::TestSimpleTaskRunner;
- FakeDelayBasedTimeSourceClient client;
- scoped_ptr<FakeDelayBasedTimeSource> timer =
- FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
- timer->SetClient(&client);
-
- timer->SetActive(true);
- task_runner->RunPendingTasks();
-
- // SetActive should return empty TimeTicks when the timer is deactivated.
- base::TimeTicks missed_tick_time = timer->SetActive(false);
- EXPECT_TRUE(missed_tick_time.is_null());
-}
-
} // namespace
} // namespace cc
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index f6dfccb..39dcc08 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -63,6 +63,7 @@ Scheduler::Scheduler(
synthetic_frame_source_(std::move(synthetic_frame_source)),
unthrottled_frame_source_(std::move(unthrottled_frame_source)),
frame_source_(BeginFrameSourceMultiplexer::Create()),
+ observing_frame_source_(false),
throttle_frame_production_(false),
compositor_timing_history_(std::move(compositor_timing_history)),
begin_impl_frame_deadline_mode_(
@@ -84,7 +85,6 @@ Scheduler::Scheduler(
begin_impl_frame_deadline_closure_ = base::Bind(
&Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
- frame_source_->AddObserver(this);
frame_source_->AddSource(primary_frame_source());
primary_frame_source()->SetClientReady();
@@ -95,8 +95,8 @@ Scheduler::Scheduler(
}
Scheduler::~Scheduler() {
- if (frame_source_->NeedsBeginFrames())
- frame_source_->SetNeedsBeginFrames(false);
+ if (observing_frame_source_)
+ frame_source_->RemoveObserver(this);
frame_source_->SetActiveSource(nullptr);
}
@@ -247,7 +247,7 @@ void Scheduler::DidLoseOutputSurface() {
void Scheduler::DidCreateAndInitializeOutputSurface() {
TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
- DCHECK(!frame_source_->NeedsBeginFrames());
+ DCHECK(!observing_frame_source_);
DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
compositor_timing_history_->DidSwapBuffersReset();
state_machine_.DidCreateAndInitializeOutputSurface();
@@ -278,16 +278,18 @@ void Scheduler::BeginImplFrameNotExpectedSoon() {
void Scheduler::SetupNextBeginFrameIfNeeded() {
// Never call SetNeedsBeginFrames if the frame source already has the right
// value.
- if (frame_source_->NeedsBeginFrames() != state_machine_.BeginFrameNeeded()) {
+ if (observing_frame_source_ != state_machine_.BeginFrameNeeded()) {
if (state_machine_.BeginFrameNeeded()) {
- // Call SetNeedsBeginFrames(true) as soon as possible.
- frame_source_->SetNeedsBeginFrames(true);
+ // Call AddObserver as soon as possible.
+ observing_frame_source_ = true;
+ frame_source_->AddObserver(this);
devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
true);
} else if (state_machine_.begin_impl_frame_state() ==
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
- // Call SetNeedsBeginFrames(false) in between frames only.
- frame_source_->SetNeedsBeginFrames(false);
+ // Call RemoveObserver in between frames only.
+ observing_frame_source_ = false;
+ frame_source_->RemoveObserver(this);
BeginImplFrameNotExpectedSoon();
devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
false);
@@ -344,8 +346,7 @@ bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
bool should_defer_begin_frame =
!begin_retro_frame_args_.empty() ||
- !begin_retro_frame_task_.IsCancelled() ||
- !frame_source_->NeedsBeginFrames() ||
+ !begin_retro_frame_task_.IsCancelled() || !observing_frame_source_ ||
(state_machine_.begin_impl_frame_state() !=
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
@@ -447,7 +448,7 @@ void Scheduler::PostBeginRetroFrameIfNeeded() {
"Scheduler::PostBeginRetroFrameIfNeeded",
"state",
AsValue());
- if (!frame_source_->NeedsBeginFrames())
+ if (!observing_frame_source_)
return;
if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
@@ -807,8 +808,7 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
(last_vsync_timebase_ - base::TimeTicks()).InMillisecondsF());
state->SetDouble("estimated_parent_draw_time_ms",
estimated_parent_draw_time_.InMillisecondsF());
- state->SetBoolean("last_set_needs_begin_frame_",
- frame_source_->NeedsBeginFrames());
+ state->SetBoolean("observing_frame_source", observing_frame_source_);
state->SetInteger("begin_retro_frame_args",
static_cast<int>(begin_retro_frame_args_.size()));
state->SetBoolean("begin_retro_frame_task",
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index 61a0ea8..61575ec 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -167,6 +167,7 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase {
scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source_;
scoped_ptr<BeginFrameSourceMultiplexer> frame_source_;
+ bool observing_frame_source_;
bool throttle_frame_production_;
base::TimeDelta authoritative_vsync_interval_;
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index 9a30c34..4da406f 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -72,9 +72,7 @@ class FakeSchedulerClient : public SchedulerClient {
void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; }
- bool needs_begin_frames() {
- return scheduler_->frame_source().NeedsBeginFrames();
- }
+ bool needs_begin_frames() { return scheduler_->begin_frames_expected(); }
int num_draws() const { return num_draws_; }
int num_actions_() const { return static_cast<int>(actions_.size()); }
const char* Action(int i) const { return actions_[i]; }
@@ -220,22 +218,22 @@ class FakeExternalBeginFrameSource : public BeginFrameSourceBase {
: client_(client) {}
~FakeExternalBeginFrameSource() override {}
- void OnNeedsBeginFramesChange(bool needs_begin_frames) override {
- if (needs_begin_frames) {
- client_->PushAction("SetNeedsBeginFrames(true)");
- } else {
- client_->PushAction("SetNeedsBeginFrames(false)");
- }
+ void AddObserver(BeginFrameObserver* obs) override {
+ client_->PushAction("AddObserver(this)");
+ BeginFrameSourceBase::AddObserver(obs);
+ }
+
+ void RemoveObserver(BeginFrameObserver* obs) override {
+ client_->PushAction("RemoveObserver(this)");
+ BeginFrameSourceBase::RemoveObserver(obs);
}
+ // TODO(sunnyps): Use using CallOnBeginFrame, SetBeginFrameSourcePaused.
void TestOnBeginFrame(const BeginFrameArgs& args) {
return CallOnBeginFrame(args);
}
- void SetPaused(bool paused) {
- DCHECK(observer_);
- observer_->OnBeginFrameSourcePausedChanged(paused);
- }
+ void SetPaused(bool paused) { SetBeginFrameSourcePaused(paused); }
private:
FakeSchedulerClient* client_;
@@ -313,7 +311,7 @@ class SchedulerTest : public testing::Test {
// Check the client doesn't have any actions queued when calling this
// function.
EXPECT_NO_ACTION(client_);
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
// Start the initial output surface creation.
scheduler_->SetVisible(true);
@@ -325,7 +323,7 @@ class SchedulerTest : public testing::Test {
// We don't see anything happening until the first impl frame.
scheduler_->DidCreateAndInitializeOutputSurface();
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
@@ -369,7 +367,7 @@ class SchedulerTest : public testing::Test {
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
}
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
client_->Reset();
}
@@ -389,7 +387,7 @@ class SchedulerTest : public testing::Test {
// it will be already in the task queue.
if (scheduler_->settings().use_external_begin_frame_source &&
scheduler_->FrameProductionThrottled()) {
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
SendNextBeginFrame();
}
@@ -455,8 +453,8 @@ TEST_F(SchedulerTest, SendBeginFramesToChildren) {
EXPECT_FALSE(client_->begin_frame_is_sent_to_children());
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
scheduler_->SetChildrenNeedBeginFrames(true);
@@ -466,17 +464,17 @@ TEST_F(SchedulerTest, SendBeginFramesToChildren) {
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
}
TEST_F(SchedulerTest, SendBeginFramesToChildrenWithoutCommit) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
scheduler_->SetChildrenNeedBeginFrames(true);
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -496,10 +494,10 @@ TEST_F(SchedulerTest, SendBeginFramesToChildrenDeadlineNotAdjusted) {
fake_compositor_timing_history_->SetDrawDurationEstimate(
base::TimeDelta::FromMilliseconds(1));
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
scheduler_->SetChildrenNeedBeginFrames(true);
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
@@ -517,8 +515,8 @@ TEST_F(SchedulerTest, VideoNeedsBeginFrames) {
SetUpScheduler(true);
scheduler_->SetVideoNeedsBeginFrames(true);
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -538,9 +536,9 @@ TEST_F(SchedulerTest, VideoNeedsBeginFrames) {
client_->Reset();
task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
}
TEST_F(SchedulerTest, RequestCommit) {
@@ -549,48 +547,48 @@ TEST_F(SchedulerTest, RequestCommit) {
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// If we don't swap on the deadline, we wait for the next BeginFrame.
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_NO_ACTION(client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// NotifyReadyToCommit should trigger the commit.
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// NotifyReadyToActivate should trigger the activation.
scheduler_->NotifyReadyToActivate();
EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// BeginImplFrame should prepare the draw.
EXPECT_SCOPED(AdvanceFrame());
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// BeginImplFrame deadline should draw.
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
@@ -601,7 +599,7 @@ TEST_F(SchedulerTest, RequestCommit) {
client_->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
client_->Reset();
}
@@ -619,11 +617,11 @@ TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
task_runner().RunPendingTasks();
// There are no pending tasks or actions.
EXPECT_NO_ACTION(client_);
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
client_->Reset();
scheduler_->SetDeferCommits(false);
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
// Start new BeginMainFrame after defer commit is off.
client_->Reset();
@@ -646,7 +644,7 @@ TEST_F(SchedulerTest, DeferCommitWithRedraw) {
// begin frame to be needed.
client_->Reset();
scheduler_->SetNeedsRedraw();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
AdvanceFrame();
@@ -657,7 +655,7 @@ TEST_F(SchedulerTest, DeferCommitWithRedraw) {
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
AdvanceFrame();
@@ -670,7 +668,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
// SetNeedsBeginMainFrame should begin the frame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -678,7 +676,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// Now SetNeedsBeginMainFrame again. Calling here means we need a second
@@ -706,7 +704,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
// Because we just swapped, the Scheduler should also request the next
// BeginImplFrame from the OutputSurface.
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// Since another commit is needed, the next BeginImplFrame should initiate
// the second commit.
@@ -730,14 +728,14 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// On the next BeginImplFrame, verify we go back to a quiescent state and
// no longer request BeginImplFrames.
EXPECT_SCOPED(AdvanceFrame());
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
client_->Reset();
}
@@ -1077,7 +1075,7 @@ TEST_F(SchedulerTest, PrepareTiles) {
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
client->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
EXPECT_EQ(0, client->num_draws());
@@ -1236,7 +1234,7 @@ TEST_F(SchedulerTest, PrepareTilesFunnelResetOnVisibilityChange) {
client_->Reset();
scheduler_->SetNeedsRedraw();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
AdvanceFrame();
@@ -1273,7 +1271,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) {
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Begin new frame.
@@ -1313,7 +1311,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostOutputSurface) {
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Begin new frame.
@@ -1342,7 +1340,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostOutputSurface) {
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
@@ -1358,7 +1356,7 @@ void SchedulerTest::CheckMainFrameSkippedAfterLateCommit(
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
scheduler_->NotifyReadyToActivate();
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 5);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
@@ -1494,7 +1492,7 @@ void SchedulerTest::ImplFrameSkippedAfterLateSwapAck(
scheduler_->SetNeedsRedraw();
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
SendNextBeginFrame();
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 3);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
@@ -1626,7 +1624,7 @@ TEST_F(SchedulerTest,
scheduler_->SetNeedsRedraw();
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
SendNextBeginFrame();
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 2);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 2);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2);
client_->Reset();
@@ -1679,7 +1677,7 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateSwapAck() {
scheduler_->SetNeedsBeginMainFrame();
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
SendNextBeginFrame();
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 3);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
@@ -1798,7 +1796,7 @@ TEST_F(SchedulerTest,
scheduler_->NotifyReadyToActivate();
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 5);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
@@ -1922,7 +1920,7 @@ TEST_F(
scheduler_->NotifyReadyToCommit();
scheduler_->NotifyReadyToActivate();
EXPECT_FALSE(scheduler_->CommitPending());
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 6);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 6);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 6);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6);
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 6);
@@ -1988,7 +1986,7 @@ TEST_F(SchedulerTest,
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
EXPECT_FALSE(scheduler_->CommitPending());
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 5);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 5);
@@ -2065,7 +2063,7 @@ TEST_F(
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
EXPECT_FALSE(scheduler_->CommitPending());
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 5);
EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 5);
@@ -2106,7 +2104,7 @@ TEST_F(SchedulerTest, BeginRetroFrame) {
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Create a BeginFrame with a long deadline to avoid race conditions.
@@ -2118,7 +2116,7 @@ TEST_F(SchedulerTest, BeginRetroFrame) {
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// Queue BeginFrames while we are still handling the previous BeginFrame.
@@ -2131,34 +2129,34 @@ TEST_F(SchedulerTest, BeginRetroFrame) {
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_NO_ACTION(client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// NotifyReadyToCommit should trigger the commit.
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// NotifyReadyToActivate should trigger the activation.
scheduler_->NotifyReadyToActivate();
EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// BeginImplFrame should prepare the draw.
task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// BeginImplFrame deadline should draw.
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
// The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
@@ -2169,7 +2167,7 @@ TEST_F(SchedulerTest, BeginRetroFrame) {
client_->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
client_->Reset();
}
@@ -2179,8 +2177,8 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
SetUpScheduler(true);
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_TRUE(client_->needs_begin_frames());
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2238,8 +2236,8 @@ TEST_F(SchedulerTest, RetroFrameExpiresOnTime) {
SetUpScheduler(true);
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_TRUE(client_->needs_begin_frames());
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2290,8 +2288,8 @@ TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) {
SetUpScheduler(true);
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_TRUE(client_->needs_begin_frames());
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
BeginFrameArgs missed_frame_args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
@@ -2315,8 +2313,8 @@ TEST_F(SchedulerTest, MissedFrameExpiresOnTime) {
SetUpScheduler(true);
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_TRUE(client_->needs_begin_frames());
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
BeginFrameArgs missed_frame_args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
@@ -2560,7 +2558,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
// SetNeedsBeginMainFrame should begin the frame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2570,7 +2568,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
client_->Reset();
scheduler_->DidLoseOutputSurface();
- // SetNeedsBeginFrames(false) is not called until the end of the frame.
+ // RemoveObserver(this) is not called until the end of the frame.
EXPECT_NO_ACTION(client_);
client_->Reset();
@@ -2582,7 +2580,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
@@ -2593,7 +2591,7 @@ TEST_F(SchedulerTest,
// SetNeedsBeginMainFrame should begin the frame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2612,7 +2610,7 @@ TEST_F(SchedulerTest,
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
// OnBeginImplFrameDeadline didn't schedule output surface creation because
// main frame is not yet completed.
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
@@ -2637,7 +2635,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommit) {
// SetNeedsBeginMainFrame should begin the frame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2655,11 +2653,11 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommit) {
// Sync tree should be forced to activate.
EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
- // SetNeedsBeginFrames(false) is not called until the end of the frame.
+ // RemoveObserver(this) is not called until the end of the frame.
client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
@@ -2669,7 +2667,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles) {
scheduler_->SetNeedsPrepareTiles();
scheduler_->SetNeedsRedraw();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2678,14 +2676,14 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles) {
client_->Reset();
scheduler_->DidLoseOutputSurface();
- // SetNeedsBeginFrames(false) is not called until the end of the frame.
+ // RemoveObserver(this) is not called until the end of the frame.
EXPECT_NO_ACTION(client_);
client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4);
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 4);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 2, 4);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
}
@@ -2695,7 +2693,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) {
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
// Create a BeginFrame with a long deadline to avoid race conditions.
// This is the first BeginFrame, which will be handled immediately.
@@ -2707,7 +2705,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) {
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// Queue BeginFrames while we are still handling the previous BeginFrame.
args.frame_time += base::TimeDelta::FromSeconds(1);
@@ -2720,26 +2718,26 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) {
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_NO_ACTION(client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// NotifyReadyToCommit should trigger the commit.
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// NotifyReadyToActivate should trigger the activation.
client_->Reset();
scheduler_->NotifyReadyToActivate();
EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty());
scheduler_->DidLoseOutputSurface();
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty());
@@ -2755,7 +2753,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
// Create a BeginFrame with a long deadline to avoid race conditions.
// This is the first BeginFrame, which will be handled immediately.
@@ -2767,7 +2765,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// Queue BeginFrames while we are still handling the previous BeginFrame.
args.frame_time += base::TimeDelta::FromSeconds(1);
@@ -2780,27 +2778,27 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_NO_ACTION(client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// NotifyReadyToCommit should trigger the commit.
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// NotifyReadyToActivate should trigger the activation.
client_->Reset();
scheduler_->NotifyReadyToActivate();
EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// BeginImplFrame should prepare the draw.
client_->Reset();
task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty());
@@ -2812,10 +2810,10 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
// No more BeginRetroFrame because BeginRetroFrame queue is cleared.
client_->Reset();
@@ -2827,41 +2825,41 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceWithSyntheticBeginFrameSource) {
SetUpScheduler(true);
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
- EXPECT_FALSE(scheduler_->frame_source().NeedsBeginFrames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
AdvanceFrame();
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// NotifyReadyToCommit should trigger the commit.
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
scheduler_->NotifyReadyToCommit();
EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
- EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
// NotifyReadyToActivate should trigger the activation.
client_->Reset();
scheduler_->NotifyReadyToActivate();
EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
- EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
scheduler_->DidLoseOutputSurface();
- // SetNeedsBeginFrames(false) is not called until the end of the frame.
+ // RemoveObserver(this) is not called until the end of the frame.
EXPECT_NO_ACTION(client_);
- EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
- EXPECT_FALSE(scheduler_->frame_source().NeedsBeginFrames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
}
TEST_F(SchedulerTest, DidLoseOutputSurfaceWhenIdle) {
@@ -2870,7 +2868,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceWhenIdle) {
// SetNeedsBeginMainFrame should begin the frame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2895,7 +2893,7 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceWhenIdle) {
client_->Reset();
scheduler_->DidLoseOutputSurface();
EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
@@ -2905,7 +2903,7 @@ TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
// SetNeedsBeginMainFrame should begin the frame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2925,7 +2923,7 @@ TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
// Sync tree should be forced to activate.
EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
}
@@ -2935,7 +2933,7 @@ TEST_F(SchedulerTest, ScheduledActionActivateAfterBeginFrameSourcePaused) {
// SetNeedsBeginMainFrame should begin the frame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
@@ -2964,13 +2962,13 @@ TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottled) {
// SetNeedsRedraw should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsRedraw();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
@@ -3001,29 +2999,32 @@ TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) {
// SetNeedsRedraw should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsRedraw();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
EXPECT_SCOPED(AdvanceFrame());
- EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
// Switch to an unthrottled frame source before the frame deadline is hit.
scheduler_->SetThrottleFrameProduction(false);
client_->Reset();
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
+ client_->Reset();
+
+ task_runner().RunPendingTasks(); // Run posted deadline.
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
client_->Reset();
- task_runner().RunPendingTasks(); // Run posted deadline and BeginFrame.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2);
// Unthrottled frame source will immediately begin a new frame.
- EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2);
+ task_runner().RunPendingTasks(); // Run BeginFrame.
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
scheduler_->SetNeedsRedraw();
client_->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
}
@@ -3062,7 +3063,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) {
EXPECT_SCOPED(AdvanceFrame());
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
- EXPECT_TRUE(client_->needs_begin_frames());
+ EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
@@ -3075,7 +3076,7 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) {
// SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Trigger a frame draw.
@@ -3099,7 +3100,7 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) {
client_->Reset();
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
client_->Reset();
}
@@ -3110,7 +3111,7 @@ TEST_F(SchedulerTest, SynchronousCompositorAnimation) {
SetUpScheduler(true);
scheduler_->SetNeedsOneBeginImplFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Testing the case where animation ticks a fling scroll.
@@ -3154,7 +3155,7 @@ TEST_F(SchedulerTest, SynchronousCompositorAnimation) {
// Idle on next vsync, as the animation has completed.
AdvanceFrame();
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
@@ -3168,7 +3169,7 @@ TEST_F(SchedulerTest, SynchronousCompositorOnDrawDuringIdle) {
scheduler_->SetNeedsRedraw();
bool resourceless_software_draw = false;
scheduler_->OnDrawForOutputSurface(resourceless_software_draw);
- EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 2);
+ EXPECT_ACTION("AddObserver(this)", client_, 0, 2);
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
@@ -3176,7 +3177,7 @@ TEST_F(SchedulerTest, SynchronousCompositorOnDrawDuringIdle) {
// Idle on next vsync.
AdvanceFrame();
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
@@ -3186,11 +3187,11 @@ TEST_F(SchedulerTest, SetNeedsOneBeginImplFrame) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
// Request a frame, should kick the source.
scheduler_->SetNeedsOneBeginImplFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// The incoming WillBeginImplFrame will request another one.
@@ -3216,7 +3217,7 @@ TEST_F(SchedulerTest, SetNeedsOneBeginImplFrame) {
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
// Scheduler shuts down the source now that no begin frame is requested.
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
}
@@ -3226,7 +3227,7 @@ TEST_F(SchedulerTest, SynchronousCompositorCommit) {
SetUpScheduler(true);
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Next vsync.
@@ -3271,7 +3272,7 @@ TEST_F(SchedulerTest, SynchronousCompositorCommit) {
// Idle on next vsync.
AdvanceFrame();
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
client_->Reset();
@@ -3283,7 +3284,7 @@ TEST_F(SchedulerTest, SynchronousCompositorDoubleCommitWithoutDraw) {
SetUpScheduler(true);
scheduler_->SetNeedsBeginMainFrame();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Next vsync.
@@ -3343,7 +3344,7 @@ TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) {
SetUpScheduler(std::move(client), true);
scheduler_->SetNeedsRedraw();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Next vsync.
@@ -3375,9 +3376,9 @@ TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) {
EXPECT_SCOPED(AdvanceFrame());
EXPECT_FALSE(scheduler_->PrepareTilesPending());
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
- EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
+ EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
- EXPECT_FALSE(client_->needs_begin_frames());
+ EXPECT_FALSE(scheduler_->begin_frames_expected());
client_->Reset();
}
@@ -3388,7 +3389,7 @@ TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) {
SetUpScheduler(true);
scheduler_->SetNeedsRedraw();
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
+ EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
client_->Reset();
// Next vsync.