// 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/lib/ui/gfx/engine/frame_timings.h"

#include "garnet/lib/ui/gfx/engine/frame_scheduler.h"

namespace scenic_impl {
namespace gfx {

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_rendered_count_ == 0);
  FXL_DCHECK(frame_presented_count_ == 0);
  swapchain_records_.push_back({});
  return swapchain_records_.size() - 1;
}

void FrameTimings::OnFrameRendered(size_t swapchain_index, zx_time_t time) {
  FXL_DCHECK(swapchain_index < swapchain_records_.size());
  FXL_DCHECK(frame_rendered_count_ < swapchain_records_.size());
  FXL_DCHECK(time > 0);

  auto& record = swapchain_records_[swapchain_index];
  FXL_DCHECK(swapchain_records_[swapchain_index].frame_rendered_time == 0);

  if (record.frame_presented_time > 0 && record.frame_presented_time < time) {
    // NOTE: Because there is a delay between when rendering is actually
    // completed and when EventTimestamper generates the timestamp, it's
    // possible that this timestamp is later than the present timestamp. Since
    // we know that's actually impossible, adjust the render timestamp to
    // make it a bit more accurate.
    time = record.frame_presented_time;
  }

  swapchain_records_[swapchain_index].frame_rendered_time = time;

  ++frame_rendered_count_;
  if (received_all_callbacks()) {
    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;

  if (time > actual_presentation_time_) {
    actual_presentation_time_ = time;
  }

  ++frame_presented_count_;
  if (received_all_callbacks()) {
    Finalize();
  }
}

void FrameTimings::OnFrameDropped(size_t swapchain_index) {
  // Indicates that "frame was dropped".
  actual_presentation_time_ = ZX_TIME_INFINITE;

  // The record should also reflect that "frame was dropped". Additionally,
  // update counts to simulate calls to OnFrameRendered/OnFramePresented; this
  // maintains count-related invariants.
  Record& record = swapchain_records_[swapchain_index];
  if (record.frame_presented_time == 0) {
    record.frame_presented_time = ZX_TIME_INFINITE;
    ++frame_presented_count_;
  }
  if (record.frame_rendered_time == 0) {
    record.frame_rendered_time = ZX_TIME_INFINITE;
    ++frame_rendered_count_;
  }

  FXL_DCHECK(received_all_callbacks())
      << "Callback counts for render/present are incorrect.";
  // Do scheduler-related cleanup.
  Finalize();
}

void FrameTimings::Finalize() {
  FXL_DCHECK(!finalized());
  finalized_ = true;

  if (frame_scheduler_) {
    frame_scheduler_->OnFramePresented(this);
  }
}

}  // namespace gfx
}  // namespace scenic_impl
