| Index: content/browser/compositor/gpu_vsync_begin_frame_source.cc
|
| diff --git a/content/browser/compositor/gpu_vsync_begin_frame_source.cc b/content/browser/compositor/gpu_vsync_begin_frame_source.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8fc7e9a39967c9e4ebd34ba55ab1d53bdd911e19
|
| --- /dev/null
|
| +++ b/content/browser/compositor/gpu_vsync_begin_frame_source.cc
|
| @@ -0,0 +1,98 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/browser/compositor/gpu_vsync_begin_frame_source.h"
|
| +
|
| +namespace content {
|
| +
|
| +GpuVSyncBeginFrameSource::GpuVSyncBeginFrameSource(
|
| + GpuVSyncControl* vsync_control)
|
| + : vsync_control_(vsync_control),
|
| + enabled_(false),
|
| + next_sequence_number_(cc::BeginFrameArgs::kStartingFrameNumber) {
|
| + DCHECK(vsync_control);
|
| +}
|
| +
|
| +GpuVSyncBeginFrameSource::~GpuVSyncBeginFrameSource() = default;
|
| +
|
| +void GpuVSyncBeginFrameSource::AddObserver(cc::BeginFrameObserver* obs) {
|
| + DCHECK(obs);
|
| + DCHECK(observers_.find(obs) == observers_.end());
|
| +
|
| + obs->OnBeginFrameSourcePausedChanged(false);
|
| +
|
| + bool observers_was_empty = observers_.empty();
|
| + observers_.insert(obs);
|
| + if (observers_was_empty)
|
| + EnableVSync(true);
|
| +
|
| + // Send a MISSED begin frame if necessary.
|
| + if (previous_begin_frame_args_.IsValid()) {
|
| + cc::BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
|
| + if (!last_args.IsValid() ||
|
| + (previous_begin_frame_args_.frame_time > last_args.frame_time)) {
|
| + DCHECK((previous_begin_frame_args_.source_id != last_args.source_id) ||
|
| + (previous_begin_frame_args_.sequence_number >
|
| + last_args.sequence_number));
|
| +
|
| + previous_begin_frame_args_.type = cc::BeginFrameArgs::MISSED;
|
| + obs->OnBeginFrame(previous_begin_frame_args_);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void GpuVSyncBeginFrameSource::RemoveObserver(cc::BeginFrameObserver* obs) {
|
| + DCHECK(obs);
|
| + DCHECK(observers_.find(obs) != observers_.end());
|
| +
|
| + observers_.erase(obs);
|
| + if (observers_.empty()) {
|
| + previous_begin_frame_args_ = cc::BeginFrameArgs();
|
| + EnableVSync(false);
|
| + }
|
| +}
|
| +
|
| +void GpuVSyncBeginFrameSource::DidFinishFrame(cc::BeginFrameObserver* obs,
|
| + const cc::BeginFrameAck& ack) {}
|
| +
|
| +bool GpuVSyncBeginFrameSource::IsThrottled() const {
|
| + return true;
|
| +}
|
| +
|
| +void GpuVSyncBeginFrameSource::OnUpdateVSyncParameters(
|
| + base::TimeTicks timebase,
|
| + base::TimeDelta interval) {
|
| + if (!enabled_)
|
| + return;
|
| +
|
| + base::TimeTicks now = base::TimeTicks::Now();
|
| + base::TimeTicks deadline = now.SnappedToNextTick(timebase, interval);
|
| +
|
| + TRACE_EVENT1("cc", "GpuVSyncBeginFrameSource::OnUpdateVSyncParameters",
|
| + "vsync_delay", (now - timebase).ToInternalValue());
|
| +
|
| + next_sequence_number_++;
|
| + OnBeginFrame(cc::BeginFrameArgs::Create(
|
| + BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, timebase,
|
| + deadline, interval, cc::BeginFrameArgs::NORMAL));
|
| +}
|
| +
|
| +void GpuVSyncBeginFrameSource::SetAuthoritativeVSyncInterval(
|
| + base::TimeDelta interval) {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void GpuVSyncBeginFrameSource::OnBeginFrame(const cc::BeginFrameArgs& args) {
|
| + previous_begin_frame_args_ = args;
|
| + std::unordered_set<cc::BeginFrameObserver*> observers(observers_);
|
| + for (auto* obs : observers)
|
| + obs->OnBeginFrame(args);
|
| +}
|
| +
|
| +void GpuVSyncBeginFrameSource::EnableVSync(bool enabled) {
|
| + enabled_ = enabled;
|
| + vsync_control_->EnableVSync(enabled);
|
| +}
|
| +
|
| +} // namespace content
|
|
|