// 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 "components/exo/layer_tree_frame_sink_holder.h"

#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "components/exo/surface_tree_host.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/common/resources/returned_resource.h"

namespace exo {

////////////////////////////////////////////////////////////////////////////////
// LayerTreeFrameSinkHolder, public:

LayerTreeFrameSinkHolder::LayerTreeFrameSinkHolder(
    SurfaceTreeHost* surface_tree_host,
    std::unique_ptr<cc::LayerTreeFrameSink> frame_sink)
    : surface_tree_host_(surface_tree_host),
      frame_sink_(std::move(frame_sink)),
      weak_ptr_factory_(this) {
  frame_sink_->BindToClient(this);
}

LayerTreeFrameSinkHolder::~LayerTreeFrameSinkHolder() {
  if (frame_sink_)
    frame_sink_->DetachFromClient();

  if (lifetime_manager_)
    lifetime_manager_->RemoveObserver(this);
}

// static
void LayerTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed(
    std::unique_ptr<LayerTreeFrameSinkHolder> holder) {
  if (holder->last_frame_size_in_pixels_.IsEmpty()) {
    // Delete sink holder immediately if no frame has been submitted.
    DCHECK(holder->last_frame_resources_.empty());
    return;
  }

  // Submit an empty frame to ensure that pending release callbacks will be
  // processed in a finite amount of time.
  viz::CompositorFrame frame;
  frame.metadata.begin_frame_ack.source_id =
      viz::BeginFrameArgs::kManualSourceId;
  frame.metadata.begin_frame_ack.sequence_number =
      viz::BeginFrameArgs::kStartingFrameNumber;
  frame.metadata.begin_frame_ack.has_damage = true;
  frame.metadata.frame_token = ++holder->next_frame_token_;
  frame.metadata.device_scale_factor = holder->last_frame_device_scale_factor_;
  frame.metadata.local_surface_id_allocation_time =
      holder->last_local_surface_id_allocation_time_;
  std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create();
  pass->SetNew(1, gfx::Rect(holder->last_frame_size_in_pixels_),
               gfx::Rect(holder->last_frame_size_in_pixels_), gfx::Transform());
  frame.render_pass_list.push_back(std::move(pass));
  holder->last_frame_resources_.clear();
  holder->frame_sink_->SubmitCompositorFrame(std::move(frame),
                                             /*hit_test_data_changed=*/true,
                                             /*show_hit_test_borders=*/false);

  // Delete sink holder immediately if not waiting for resources to be
  // reclaimed.
  if (holder->resource_manager_.HasNoCallbacks())
    return;

  WMHelper::LifetimeManager* lifetime_manager =
      WMHelper::GetInstance()->GetLifetimeManager();
  holder->lifetime_manager_ = lifetime_manager;
  holder->surface_tree_host_ = nullptr;

  // If we have pending release callbacks then extend the lifetime of holder
  // by adding it as a LifetimeManager observer. The holder will delete itself
  // when LifetimeManager shuts down or when all pending release callbacks have
  // been called.
  lifetime_manager->AddObserver(holder.release());
}

void LayerTreeFrameSinkHolder::SubmitCompositorFrame(
    viz::CompositorFrame frame) {
  last_frame_size_in_pixels_ = frame.size_in_pixels();
  last_frame_device_scale_factor_ = frame.metadata.device_scale_factor;
  last_local_surface_id_allocation_time_ =
      frame.metadata.local_surface_id_allocation_time;
  last_frame_resources_.clear();
  for (auto& resource : frame.resource_list)
    last_frame_resources_.push_back(resource.id);
  frame_sink_->SubmitCompositorFrame(std::move(frame),
                                     /*hit_test_data_changed=*/true,
                                     /*show_hit_test_borders=*/false);
}

void LayerTreeFrameSinkHolder::DidNotProduceFrame(
    const viz::BeginFrameAck& ack) {
  frame_sink_->DidNotProduceFrame(ack);
}

base::WeakPtr<LayerTreeFrameSinkHolder> LayerTreeFrameSinkHolder::GetWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}

////////////////////////////////////////////////////////////////////////////////
// cc::LayerTreeFrameSinkClient overrides:

base::Optional<viz::HitTestRegionList>
LayerTreeFrameSinkHolder::BuildHitTestData() {
  return {};
}

void LayerTreeFrameSinkHolder::ReclaimResources(
    const std::vector<viz::ReturnedResource>& resources) {
  for (auto& resource : resources) {
    // Skip resources that are also in last frame. This can happen if
    // the frame sink id changed.
    if (base::ContainsValue(last_frame_resources_, resource.id)) {
      continue;
    }
    resource_manager_.ReclaimResource(resource);
  }

  if (lifetime_manager_ && resource_manager_.HasNoCallbacks())
    ScheduleDelete();
}

void LayerTreeFrameSinkHolder::DidReceiveCompositorFrameAck() {
  if (surface_tree_host_)
    surface_tree_host_->DidReceiveCompositorFrameAck();
}

void LayerTreeFrameSinkHolder::DidPresentCompositorFrame(
    uint32_t presentation_token,
    const gfx::PresentationFeedback& feedback) {
  if (surface_tree_host_)
    surface_tree_host_->DidPresentCompositorFrame(presentation_token, feedback);
}

void LayerTreeFrameSinkHolder::DidLoseLayerTreeFrameSink() {
  last_frame_resources_.clear();
  resource_manager_.ClearAllCallbacks();

  if (lifetime_manager_)
    ScheduleDelete();
}

////////////////////////////////////////////////////////////////////////////////
// LayerTreeFrameSinkHolder, private:

void LayerTreeFrameSinkHolder::ScheduleDelete() {
  if (delete_pending_)
    return;
  delete_pending_ = true;
  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}

void LayerTreeFrameSinkHolder::OnDestroyed() {
  lifetime_manager_->RemoveObserver(this);
  lifetime_manager_ = nullptr;

  // Make sure frame sink never outlives the shell.
  frame_sink_->DetachFromClient();
  frame_sink_.reset();
  ScheduleDelete();
}

}  // namespace exo
