blob: 171cffcb8129f6791b43a5ec8096911e22b0f890 [file] [log] [blame]
// Copyright 2019 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 "cc/trees/presentation_time_callback_buffer.h"
#include <utility>
#include <vector>
#include "components/viz/common/quads/compositor_frame_metadata.h"
namespace cc {
PresentationTimeCallbackBuffer::PresentationTimeCallbackBuffer() = default;
PresentationTimeCallbackBuffer::PresentationTimeCallbackBuffer(
PresentationTimeCallbackBuffer&& other)
: frame_token_infos_(std::move(other.frame_token_infos_)) {}
PresentationTimeCallbackBuffer& PresentationTimeCallbackBuffer::operator=(
PresentationTimeCallbackBuffer&& other) {
if (this != &other) {
frame_token_infos_ = std::move(other.frame_token_infos_);
}
return *this;
}
PresentationTimeCallbackBuffer::~PresentationTimeCallbackBuffer() = default;
PresentationTimeCallbackBuffer::FrameTokenInfo::FrameTokenInfo(uint32_t token)
: token(token) {}
PresentationTimeCallbackBuffer::FrameTokenInfo::FrameTokenInfo(
FrameTokenInfo&&) = default;
PresentationTimeCallbackBuffer::FrameTokenInfo&
PresentationTimeCallbackBuffer::FrameTokenInfo::operator=(FrameTokenInfo&&) =
default;
PresentationTimeCallbackBuffer::FrameTokenInfo::~FrameTokenInfo() = default;
void PresentationTimeCallbackBuffer::RegisterMainThreadPresentationCallbacks(
uint32_t frame_token,
std::vector<MainCallback> callbacks) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
FrameTokenInfo& frame_info = GetOrMakeRegistration(frame_token);
// Splice the given |callbacks| onto the vector of existing callbacks.
auto& sink = frame_info.main_thread_callbacks;
sink.reserve(sink.size() + callbacks.size());
std::move(callbacks.begin(), callbacks.end(), std::back_inserter(sink));
}
void PresentationTimeCallbackBuffer::RegisterCompositorPresentationCallbacks(
uint32_t frame_token,
std::vector<CompositorCallback> callbacks) {
// Splice the given |callbacks| onto the vector of existing callbacks.
std::vector<CompositorCallback>& sink =
GetOrMakeRegistration(frame_token).compositor_thread_callbacks;
sink.reserve(sink.size() + callbacks.size());
std::move(callbacks.begin(), callbacks.end(), std::back_inserter(sink));
}
PresentationTimeCallbackBuffer::PendingCallbacks::PendingCallbacks() = default;
PresentationTimeCallbackBuffer::PendingCallbacks::PendingCallbacks(
PendingCallbacks&&) = default;
PresentationTimeCallbackBuffer::PendingCallbacks&
PresentationTimeCallbackBuffer::PendingCallbacks::operator=(
PendingCallbacks&&) = default;
PresentationTimeCallbackBuffer::PendingCallbacks::~PendingCallbacks() = default;
PresentationTimeCallbackBuffer::PendingCallbacks
PresentationTimeCallbackBuffer::PopPendingCallbacks(uint32_t frame_token,
bool main_only) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
PendingCallbacks result;
for (auto info = frame_token_infos_.begin();
info != frame_token_infos_.end();) {
if (viz::FrameTokenGT(info->token, frame_token))
break;
std::move(info->main_thread_callbacks.begin(),
info->main_thread_callbacks.end(),
std::back_inserter(result.main_thread_callbacks));
info->main_thread_callbacks.clear();
const bool should_keep_callbacks =
main_only && !info->compositor_thread_callbacks.empty();
if (should_keep_callbacks) {
++info;
} else {
std::move(info->compositor_thread_callbacks.begin(),
info->compositor_thread_callbacks.end(),
std::back_inserter(result.compositor_thread_callbacks));
info = frame_token_infos_.erase(info);
}
}
return result;
}
PresentationTimeCallbackBuffer::FrameTokenInfo&
PresentationTimeCallbackBuffer::GetOrMakeRegistration(uint32_t frame_token) {
// If the freshest registration is for an earlier frame token, add a new
// entry to the queue.
if (frame_token_infos_.empty() ||
viz::FrameTokenGT(frame_token, frame_token_infos_.back().token)) {
frame_token_infos_.emplace_back(frame_token);
DCHECK_LE(frame_token_infos_.size(), kMaxBufferSize);
}
// Registrations should use monotonically increasing frame tokens.
DCHECK_EQ(frame_token_infos_.back().token, frame_token);
return frame_token_infos_.back();
}
} // namespace cc