blob: 96a061d6ee20fcbabcc40eea7508538b5413784f [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 "garnet/bin/ui/scene_manager/engine/frame_timings.h"
#include "garnet/bin/ui/scene_manager/engine/frame_scheduler.h"
namespace scene_manager {
FrameTimings::FrameTimings() : FrameTimings(nullptr, 0, 0) {}
FrameTimings::FrameTimings(FrameScheduler* frame_scheduler,
uint64_t frame_number,
zx_time_t target_presentation_time)
: frame_scheduler_(frame_scheduler),
frame_number_(frame_number),
target_presentation_time_(target_presentation_time) {}
size_t FrameTimings::AddSwapchain(Swapchain* swapchain) {
// All swapchains that we are timing must be added before any of them finish.
// The purpose of this is to verify that we cannot notify the FrameScheduler
// that the frame has finished before all swapchains have been added.
FXL_DCHECK(frame_finished_rendering_count_ == 0);
FXL_DCHECK(frame_presented_count_ == 0);
swapchain_records_.push_back({});
return swapchain_records_.size() - 1;
}
void FrameTimings::OnFrameFinishedRendering(size_t swapchain_index,
zx_time_t time) {
FXL_DCHECK(swapchain_index < swapchain_records_.size());
FXL_DCHECK(frame_finished_rendering_count_ < swapchain_records_.size());
FXL_DCHECK(swapchain_records_[swapchain_index].frame_finished_time == 0);
FXL_DCHECK(time > 0);
swapchain_records_[swapchain_index].frame_finished_time = time;
++frame_finished_rendering_count_;
if (frame_finished_rendering_count_ == swapchain_records_.size() &&
frame_presented_count_ == swapchain_records_.size()) {
Finalize();
}
}
void FrameTimings::OnFramePresented(size_t swapchain_index, zx_time_t time) {
FXL_DCHECK(swapchain_index < swapchain_records_.size());
FXL_DCHECK(frame_presented_count_ < swapchain_records_.size());
FXL_DCHECK(swapchain_records_[swapchain_index].frame_presented_time == 0);
FXL_DCHECK(time > 0);
swapchain_records_[swapchain_index].frame_presented_time = time;
++frame_presented_count_;
if (frame_finished_rendering_count_ == swapchain_records_.size() &&
frame_presented_count_ == swapchain_records_.size()) {
Finalize();
}
}
void FrameTimings::Finalize() {
// TODO: compute actual presentation time.
FXL_CHECK(false);
frame_scheduler_->ReceiveFrameTimings(this);
}
} // namespace scene_manager