blob: e4cf54bc2f0300f2fe737cdbb0c8971d0ef60976 [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 "src/ui/lib/escher/impl/command_buffer_sequencer.h"
#include <lib/syslog/cpp/macros.h>
namespace escher {
namespace impl {
CommandBufferSequencer::~CommandBufferSequencer() {
// Ensure clean shutdown.
FX_DCHECK(latest_sequence_number_ == last_finished_sequence_number_);
FX_DCHECK(listeners_.size() == 0);
}
uint64_t CommandBufferSequencer::GenerateNextCommandBufferSequenceNumber() {
return ++latest_sequence_number_;
}
void CommandBufferSequencer::CommandBufferFinished(uint64_t sequence_number) {
if (sequence_number != last_finished_sequence_number_ + 1) {
// There is a gap. Remember the just-finished sequence number so that we
// can notify listeners once the gap is filled.
out_of_sequence_numbers_.push_back(sequence_number);
std::sort(out_of_sequence_numbers_.begin(), out_of_sequence_numbers_.end());
} else {
++last_finished_sequence_number_;
// If there were any buffers that were finished "out of sequence", the gap
// between them and last_finished_sequence_number_ may now be filled.
size_t removed = 0;
for (size_t i = 0; i < out_of_sequence_numbers_.size(); ++i) {
if (out_of_sequence_numbers_[i] == last_finished_sequence_number_ + 1) {
++last_finished_sequence_number_;
++removed;
} else {
// This works because we sort the list every time we add to
// out_of_sequence_numbers_
out_of_sequence_numbers_[i - removed] = out_of_sequence_numbers_[i];
}
}
out_of_sequence_numbers_.resize(out_of_sequence_numbers_.size() - removed);
// Notify listeners.
for (auto& listener : listeners_) {
listener->OnCommandBufferFinished(last_finished_sequence_number_);
}
}
}
void CommandBufferSequencer::AddListener(CommandBufferSequencerListener* listener) {
FX_DCHECK(listener);
FX_DCHECK(std::find(listeners_.begin(), listeners_.end(), listener) == listeners_.end());
listeners_.push_back(listener);
}
void CommandBufferSequencer::RemoveListener(CommandBufferSequencerListener* listener) {
FX_DCHECK(listener);
listeners_.erase(std::remove(listeners_.begin(), listeners_.end(), listener), listeners_.end());
}
} // namespace impl
} // namespace escher