// Copyright 2013 The Flutter 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 "vulkan_surface_producer.h"

#include <lib/async/cpp/task.h>
#include <lib/async/default.h>

#include <memory>
#include <string>
#include <vector>

#include "flutter/fml/trace_event.h"
#include "flutter/vulkan/vulkan_skia_proc_table.h"
#include "flutter_vma/flutter_skia_vma.h"

#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSemaphore.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/vk/GrVkDirectContext.h"
#include "third_party/skia/include/gpu/vk/GrVkBackendContext.h"
#include "third_party/skia/include/gpu/vk/GrVkExtensions.h"
#include "third_party/skia/include/gpu/vk/GrVkTypes.h"

namespace flutter_runner {

namespace {

// Tuning advice:
// If you see the following 3 things happening simultaneously in a trace:
//   * Over budget ("flutter", "GPURasterizer::Draw") durations
//   * Many ("skia", "GrGpu::createTexture") events within the
//     "GPURasterizer::Draw"s
//   * The Skia GPU resource cache is full, as indicated by the
//     "SkiaCacheBytes" field in the ("flutter", "SurfacePool") trace counter
//     (compare it to the bytes value here)
// then you should consider increasing the size of the GPU resource cache.
constexpr size_t kGrCacheMaxByteSize = 1024 * 600 * 12 * 4;

}  // namespace

VulkanSurfaceProducer::VulkanSurfaceProducer() {
  valid_ = Initialize();

  if (!valid_) {
    FML_LOG(FATAL) << "VulkanSurfaceProducer: Initialization failed";
  }
}

VulkanSurfaceProducer::~VulkanSurfaceProducer() {
  // Make sure queue is idle before we start destroying surfaces
  if (valid_) {
    VkResult wait_result = VK_CALL_LOG_ERROR(
        vk_->QueueWaitIdle(logical_device_->GetQueueHandle()));
    FML_DCHECK(wait_result == VK_SUCCESS);
  }
};

bool VulkanSurfaceProducer::Initialize() {
  vk_ = fml::MakeRefCounted<vulkan::VulkanProcTable>();

  std::vector<std::string> extensions = {
      VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
  };

  // On Fuchsia, the validation layers need to be packaged as part of the
  // flutter_runner in order to work. As a result, we can use the presence
  // of the layers to mean that we want the layers enabled.
  application_ = std::make_unique<vulkan::VulkanApplication>(
      *vk_, "FlutterRunner", std::move(extensions), VK_MAKE_VERSION(1, 0, 0),
      VK_MAKE_VERSION(1, 1, 0), true /* enable_validation_layers */);

  if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) {
    // Make certain the application instance was created and it set up the
    // instance proc table entries.
    FML_LOG(ERROR) << "VulkanSurfaceProducer: Instance proc addresses have not "
                      "been set up.";
    return false;
  }

  // Create the device.

  logical_device_ = application_->AcquireFirstCompatibleLogicalDevice();

  if (logical_device_ == nullptr || !logical_device_->IsValid() ||
      !vk_->AreDeviceProcsSetup()) {
    // Make certain the device was created and it set up the device proc table
    // entries.
    FML_LOG(ERROR)
        << "VulkanSurfaceProducer: Device proc addresses have not been set up.";
    return false;
  }

  if (!vk_->HasAcquiredMandatoryProcAddresses()) {
    FML_LOG(ERROR)
        << "VulkanSurfaceProducer: Failed to acquire mandatory proc addresses.";
    return false;
  }

  if (!vk_->IsValid()) {
    FML_LOG(ERROR) << "VulkanSurfaceProducer: VulkanProcTable invalid";
    return false;
  }

  auto getProc = CreateSkiaGetProc(vk_);

  if (getProc == nullptr) {
    FML_LOG(ERROR) << "VulkanSurfaceProducer: Failed to create skia getProc.";
    return false;
  }

  uint32_t skia_features = 0;
  if (!logical_device_->GetPhysicalDeviceFeaturesSkia(&skia_features)) {
    FML_LOG(ERROR)
        << "VulkanSurfaceProducer: Failed to get physical device features.";

    return false;
  }

  memory_allocator_ = flutter::FlutterSkiaVulkanMemoryAllocator::Make(
      application_->GetAPIVersion(), application_->GetInstance(),
      logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(),
      vk_, true);

  GrVkBackendContext backend_context;
  backend_context.fInstance = application_->GetInstance();
  backend_context.fPhysicalDevice = logical_device_->GetPhysicalDeviceHandle();
  backend_context.fDevice = logical_device_->GetHandle();
  backend_context.fQueue = logical_device_->GetQueueHandle();
  backend_context.fGraphicsQueueIndex =
      logical_device_->GetGraphicsQueueIndex();
  backend_context.fMinAPIVersion = application_->GetAPIVersion();
  backend_context.fMaxAPIVersion = application_->GetAPIVersion();
  backend_context.fFeatures = skia_features;
  backend_context.fGetProc = std::move(getProc);
  backend_context.fOwnsInstanceAndDevice = false;
  backend_context.fMemoryAllocator = memory_allocator_;

  // The memory_requirements_2 extension is required on Fuchsia as the AMD
  // memory allocator used by Skia benefit from it.
  const char* device_extensions[] = {
      VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
  };
  const int device_extensions_count =
      sizeof(device_extensions) / sizeof(device_extensions[0]);
  GrVkExtensions vk_extensions;
  vk_extensions.init(backend_context.fGetProc, backend_context.fInstance,
                     backend_context.fPhysicalDevice, 0, nullptr,
                     device_extensions_count, device_extensions);
  backend_context.fVkExtensions = &vk_extensions;
  GrContextOptions options;
  options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;

  context_ = GrDirectContexts::MakeVulkan(backend_context, options);

  if (context_ == nullptr) {
    FML_LOG(ERROR)
        << "VulkanSurfaceProducer: Failed to create GrDirectContext.";
    return false;
  }

  // Use local limits specified in this file above instead of flutter defaults.
  context_->setResourceCacheLimit(kGrCacheMaxByteSize);

  surface_pool_ = std::make_unique<VulkanSurfacePool>(*this, context_);

  return true;
}

void VulkanSurfaceProducer::SubmitSurfaces(
    std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces) {
  TRACE_EVENT0("flutter", "VulkanSurfaceProducer::SubmitSurfaces");

  // Do a single flush for all canvases derived from the context.
  {
    TRACE_EVENT0("flutter", "GrDirectContext::flushAndSignalSemaphores");
    context_->flushAndSubmit();
  }

  if (!TransitionSurfacesToExternal(surfaces))
    FML_LOG(ERROR) << "TransitionSurfacesToExternal failed";

  // Submit surface
  for (auto& surface : surfaces) {
    SubmitSurface(std::move(surface));
  }

  // Buffer management.
  surface_pool_->AgeAndCollectOldBuffers();

  // If no further surface production has taken place for 10 frames (TODO:
  // Don't hardcode refresh rate here), then shrink our surface pool to fit.
  constexpr auto kShouldShrinkThreshold = zx::msec(10 * 16.67);
  async::PostDelayedTask(
      async_get_default_dispatcher(),
      [self = weak_factory_.GetWeakPtr(), kShouldShrinkThreshold] {
        if (!self) {
          return;
        }
        auto time_since_last_produce =
            async::Now(async_get_default_dispatcher()) -
            self->last_produce_time_;
        if (time_since_last_produce >= kShouldShrinkThreshold) {
          self->surface_pool_->ShrinkToFit();
        }
      },
      kShouldShrinkThreshold);
}

bool VulkanSurfaceProducer::TransitionSurfacesToExternal(
    const std::vector<std::unique_ptr<SurfaceProducerSurface>>& surfaces) {
  for (auto& surface : surfaces) {
    auto vk_surface = static_cast<VulkanSurface*>(surface.get());
    if (!vk_surface) {
      continue;
    }

    vulkan::VulkanCommandBuffer* command_buffer =
        vk_surface->GetCommandBuffer(logical_device_->GetCommandPool());
    if (!command_buffer->Begin())
      return false;

    GrBackendRenderTarget backendRT = SkSurfaces::GetBackendRenderTarget(
        vk_surface->GetSkiaSurface().get(),
        SkSurfaces::BackendHandleAccess::kFlushRead);
    if (!backendRT.isValid()) {
      return false;
    }
    GrVkImageInfo imageInfo;
    if (!GrBackendRenderTargets::GetVkImageInfo(backendRT, &imageInfo)) {
      return false;
    }

    VkImageMemoryBarrier image_barrier = {
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
        .pNext = nullptr,
        .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
        .dstAccessMask = 0,
        .oldLayout = imageInfo.fImageLayout,
    // Understand why this is causing issues on Intel. TODO(fxb/53449)
#if defined(__aarch64__)
        .newLayout = imageInfo.fImageLayout,
#else
        .newLayout = VK_IMAGE_LAYOUT_GENERAL,
#endif
        .srcQueueFamilyIndex = 0,
        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL_KHR,
        .image = vk_surface->GetVkImage(),
        .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};

    if (!command_buffer->InsertPipelineBarrier(
            VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
            VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
            0,           // dependencyFlags
            0, nullptr,  // memory barriers
            0, nullptr,  // buffer barriers
            1, &image_barrier))
      return false;

    GrBackendRenderTargets::SetVkImageLayout(&backendRT,
                                             image_barrier.newLayout);

    if (!command_buffer->End())
      return false;

    if (!logical_device_->QueueSubmit(
            {}, {}, {vk_surface->GetAcquireVkSemaphore()},
            {command_buffer->Handle()}, vk_surface->GetCommandBufferFence()))
      return false;
  }
  return true;
}

std::unique_ptr<SurfaceProducerSurface> VulkanSurfaceProducer::ProduceSurface(
    const SkISize& size) {
  FML_CHECK(valid_);
  last_produce_time_ = async::Now(async_get_default_dispatcher());
  return surface_pool_->AcquireSurface(size);
}

void VulkanSurfaceProducer::SubmitSurface(
    std::unique_ptr<SurfaceProducerSurface> surface) {
  FML_CHECK(valid_);
  surface_pool_->SubmitSurface(std::move(surface));
}

std::unique_ptr<SurfaceProducerSurface>
VulkanSurfaceProducer::ProduceOffscreenSurface(const SkISize& size) {
  return surface_pool_->CreateSurface(size);
}

}  // namespace flutter_runner
