// Copyright 2015 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 <GLES2/gl2extchromium.h>

#include "ash/shell.h"
#include "base/bind.h"
#include "base/run_loop.h"
#include "components/exo/buffer.h"
#include "components/exo/frame_sink_resource_manager.h"
#include "components/exo/surface_tree_host.h"
#include "components/exo/test/exo_test_base.h"
#include "components/exo/test/exo_test_helper.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/resources/single_release_callback.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/aura/env.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/test/in_process_context_factory.h"
#include "ui/gfx/gpu_memory_buffer.h"

namespace exo {
namespace {

using BufferTest = test::ExoTestBase;

aura::Env* GetAuraEnv() {
  return ash::Shell::Get()->aura_env();
}

void Release(int* release_call_count) {
  (*release_call_count)++;
}

void VerifySyncTokensInCompositorFrame(viz::CompositorFrame* frame) {
  std::vector<GLbyte*> sync_tokens;
  for (auto& resource : frame->resource_list)
    sync_tokens.push_back(resource.mailbox_holder.sync_token.GetData());
  gpu::gles2::GLES2Interface* gles2 = GetAuraEnv()
                                          ->context_factory()
                                          ->SharedMainThreadContextProvider()
                                          ->ContextGL();
  gles2->VerifySyncTokensCHROMIUM(sync_tokens.data(), sync_tokens.size());
}

TEST_F(BufferTest, ReleaseCallback) {
  gfx::Size buffer_size(256, 256);
  auto buffer = std::make_unique<Buffer>(
      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
  auto surface_tree_host = std::make_unique<SurfaceTreeHost>("BufferTest");
  LayerTreeFrameSinkHolder* frame_sink_holder =
      surface_tree_host->layer_tree_frame_sink_holder();

  // This is needed to ensure that base::RunLoop().RunUntilIdle() call below
  // is always sufficient for buffer to be released.
  buffer->set_wait_for_release_delay_for_testing(base::TimeDelta());

  // Set the release callback.
  int release_call_count = 0;
  buffer->set_release_callback(
      base::Bind(&Release, base::Unretained(&release_call_count)));

  buffer->OnAttach();
  viz::TransferableResource resource;
  // Produce a transferable resource for the contents of the buffer.
  bool rv = buffer->ProduceTransferableResource(
      frame_sink_holder->resource_manager(), false, &resource);
  ASSERT_TRUE(rv);

  // Release buffer.
  viz::ReturnedResource returned_resource;
  returned_resource.id = resource.id;
  returned_resource.sync_token = resource.mailbox_holder.sync_token;
  returned_resource.lost = false;
  std::vector<viz::ReturnedResource> resources = {returned_resource};
  frame_sink_holder->ReclaimResources(resources);

  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(release_call_count, 0);

  buffer->OnDetach();

  // Release() should have been called exactly once.
  ASSERT_EQ(release_call_count, 1);
}

TEST_F(BufferTest, IsLost) {
  gfx::Size buffer_size(256, 256);
  auto buffer = std::make_unique<Buffer>(
      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
  auto surface_tree_host = std::make_unique<SurfaceTreeHost>("BufferTest");
  LayerTreeFrameSinkHolder* frame_sink_holder =
      surface_tree_host->layer_tree_frame_sink_holder();

  buffer->OnAttach();
  // Acquire a texture transferable resource for the contents of the buffer.
  viz::TransferableResource resource;
  bool rv = buffer->ProduceTransferableResource(
      frame_sink_holder->resource_manager(), false, &resource);
  ASSERT_TRUE(rv);

  scoped_refptr<viz::ContextProvider> context_provider =
      GetAuraEnv()->context_factory()->SharedMainThreadContextProvider();
  if (context_provider) {
    gpu::gles2::GLES2Interface* gles2 = context_provider->ContextGL();
    gles2->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                               GL_INNOCENT_CONTEXT_RESET_ARB);
  }

  // Release buffer.
  bool is_lost = true;
  viz::ReturnedResource returned_resource;
  returned_resource.id = resource.id;
  returned_resource.sync_token = gpu::SyncToken();
  returned_resource.lost = is_lost;
  std::vector<viz::ReturnedResource> resources = {returned_resource};
  frame_sink_holder->ReclaimResources(resources);
  base::RunLoop().RunUntilIdle();

  // Producing a new texture transferable resource for the contents of the
  // buffer.
  viz::TransferableResource new_resource;
  rv = buffer->ProduceTransferableResource(
      frame_sink_holder->resource_manager(), false, &new_resource);
  ASSERT_TRUE(rv);
  buffer->OnDetach();

  viz::ReturnedResource returned_resource2;
  returned_resource2.id = new_resource.id;
  returned_resource2.sync_token = gpu::SyncToken();
  returned_resource2.lost = false;
  std::vector<viz::ReturnedResource> resources2 = {returned_resource2};
  frame_sink_holder->ReclaimResources(resources2);
  base::RunLoop().RunUntilIdle();
}

// Buffer::Texture::OnLostResources is called when the gpu crashes. This test
// verifies that the Texture is collected properly in such event.
TEST_F(BufferTest, OnLostResources) {
  // Create a Buffer and use it to produce a Texture.
  constexpr gfx::Size buffer_size(256, 256);
  auto buffer = std::make_unique<Buffer>(
      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
  auto surface_tree_host = std::make_unique<SurfaceTreeHost>("BufferTest");
  LayerTreeFrameSinkHolder* frame_sink_holder =
      surface_tree_host->layer_tree_frame_sink_holder();

  buffer->OnAttach();
  // Acquire a texture transferable resource for the contents of the buffer.
  viz::TransferableResource resource;
  bool rv = buffer->ProduceTransferableResource(
      frame_sink_holder->resource_manager(), false, &resource);
  ASSERT_TRUE(rv);

  static_cast<ui::InProcessContextFactory*>(GetAuraEnv()->context_factory())
      ->SendOnLostSharedContext();
}

TEST_F(BufferTest, SurfaceTreeHostDestruction) {
  gfx::Size buffer_size(256, 256);
  auto buffer = std::make_unique<Buffer>(
      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
  auto surface_tree_host = std::make_unique<SurfaceTreeHost>("BufferTest");
  LayerTreeFrameSinkHolder* frame_sink_holder =
      surface_tree_host->layer_tree_frame_sink_holder();

  // This is needed to ensure that base::RunLoop().RunUntilIdle() call below
  // is always sufficient for buffer to be released.
  buffer->set_wait_for_release_delay_for_testing(base::TimeDelta());

  // Set the release callback.
  int release_call_count = 0;
  buffer->set_release_callback(
      base::Bind(&Release, base::Unretained(&release_call_count)));

  buffer->OnAttach();
  viz::TransferableResource resource;
  // Produce a transferable resource for the contents of the buffer.
  bool rv = buffer->ProduceTransferableResource(
      frame_sink_holder->resource_manager(), false, &resource);
  ASSERT_TRUE(rv);

  // Submit frame with resource.
  {
    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 = 1;
    frame.metadata.device_scale_factor = 1;
    frame.metadata.local_surface_id_allocation_time = base::TimeTicks::Now();
    std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create();
    pass->SetNew(1, gfx::Rect(buffer_size), gfx::Rect(buffer_size),
                 gfx::Transform());
    frame.render_pass_list.push_back(std::move(pass));
    frame.resource_list.push_back(resource);
    VerifySyncTokensInCompositorFrame(&frame);
    frame_sink_holder->SubmitCompositorFrame(std::move(frame));
  }

  buffer->OnDetach();
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(release_call_count, 0);

  surface_tree_host.reset();
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(release_call_count, 1);
}

TEST_F(BufferTest, SurfaceTreeHostLastFrame) {
  gfx::Size buffer_size(256, 256);
  auto buffer = std::make_unique<Buffer>(
      exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
  auto surface_tree_host = std::make_unique<SurfaceTreeHost>("BufferTest");
  LayerTreeFrameSinkHolder* frame_sink_holder =
      surface_tree_host->layer_tree_frame_sink_holder();

  // This is needed to ensure that base::RunLoop().RunUntilIdle() call below
  // is always sufficient for buffer to be released.
  buffer->set_wait_for_release_delay_for_testing(base::TimeDelta());

  // Set the release callback.
  int release_call_count = 0;
  buffer->set_release_callback(
      base::Bind(&Release, base::Unretained(&release_call_count)));

  buffer->OnAttach();
  viz::TransferableResource resource;
  // Produce a transferable resource for the contents of the buffer.
  bool rv = buffer->ProduceTransferableResource(
      frame_sink_holder->resource_manager(), false, &resource);
  ASSERT_TRUE(rv);

  // Submit frame with resource.
  {
    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 = 1;
    frame.metadata.device_scale_factor = 1;
    frame.metadata.local_surface_id_allocation_time = base::TimeTicks::Now();
    std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create();
    pass->SetNew(1, gfx::Rect(buffer_size), gfx::Rect(buffer_size),
                 gfx::Transform());
    frame.render_pass_list.push_back(std::move(pass));
    frame.resource_list.push_back(resource);
    VerifySyncTokensInCompositorFrame(&frame);
    frame_sink_holder->SubmitCompositorFrame(std::move(frame));

    // Try to release buffer in last frame. This can happen during a resize
    // when frame sink id changes.
    viz::ReturnedResource returned_resource;
    returned_resource.id = resource.id;
    returned_resource.sync_token = resource.mailbox_holder.sync_token;
    returned_resource.lost = false;

    std::vector<viz::ReturnedResource> resources = {returned_resource};
    frame_sink_holder->ReclaimResources(resources);
  }

  base::RunLoop().RunUntilIdle();
  buffer->OnDetach();

  // Release() should not have been called as resource is used by last frame.
  ASSERT_EQ(release_call_count, 0);

  // Submit frame without resource. This should cause buffer to be released.
  {
    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 = 1;
    frame.metadata.device_scale_factor = 1;
    frame.metadata.local_surface_id_allocation_time = base::TimeTicks::Now();
    std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create();
    pass->SetNew(1, gfx::Rect(buffer_size), gfx::Rect(buffer_size),
                 gfx::Transform());
    frame.render_pass_list.push_back(std::move(pass));
    frame_sink_holder->SubmitCompositorFrame(std::move(frame));
  }

  base::RunLoop().RunUntilIdle();
  // Release() should have been called exactly once.
  ASSERT_EQ(release_call_count, 1);
}

}  // namespace
}  // namespace exo
