// Copyright 2019 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/viz/service/display_embedder/skia_output_surface_dependency_impl.h"

#include <memory>
#include <utility>

#include "base/callback_helpers.h"
#include "base/task/bind_post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/viz/service/gl/gpu_service_impl.h"
#include "gpu/command_buffer/service/command_buffer_task_executor.h"
#include "gpu/command_buffer/service/gpu_task_scheduler_helper.h"
#include "gpu/command_buffer/service/scheduler.h"
#include "gpu/command_buffer/service/scheduler_sequence.h"
#include "gpu/ipc/service/image_transport_surface.h"
#include "ui/gl/gl_utils.h"
#include "ui/gl/init/gl_factory.h"

namespace viz {

SkiaOutputSurfaceDependencyImpl::SkiaOutputSurfaceDependencyImpl(
    GpuServiceImpl* gpu_service_impl,
    gpu::SurfaceHandle surface_handle)
    : gpu_service_impl_(gpu_service_impl),
      surface_handle_(surface_handle),
      client_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}

SkiaOutputSurfaceDependencyImpl::~SkiaOutputSurfaceDependencyImpl() = default;

std::unique_ptr<gpu::SingleTaskSequence>
SkiaOutputSurfaceDependencyImpl::CreateSequence() {
  return std::make_unique<gpu::SchedulerSequence>(
      gpu_service_impl_->GetGpuScheduler(),
      gpu_service_impl_->gpu_task_runner());
}

gpu::SharedImageManager*
SkiaOutputSurfaceDependencyImpl::GetSharedImageManager() {
  return gpu_service_impl_->shared_image_manager();
}

gpu::SyncPointManager* SkiaOutputSurfaceDependencyImpl::GetSyncPointManager() {
  return gpu_service_impl_->sync_point_manager();
}

const gpu::GpuDriverBugWorkarounds&
SkiaOutputSurfaceDependencyImpl::GetGpuDriverBugWorkarounds() {
  return gpu_service_impl_->gpu_driver_bug_workarounds();
}

scoped_refptr<gpu::SharedContextState>
SkiaOutputSurfaceDependencyImpl::GetSharedContextState() {
  if (gpu_service_impl_->compositor_gpu_thread()) {
    return gpu_service_impl_->compositor_gpu_thread()->GetSharedContextState();
  }
  return gpu_service_impl_->GetContextState();
}

gpu::raster::GrShaderCache*
SkiaOutputSurfaceDependencyImpl::GetGrShaderCache() {
  return gpu_service_impl_->gr_shader_cache();
}

VulkanContextProvider*
SkiaOutputSurfaceDependencyImpl::GetVulkanContextProvider() {
  if (gpu_service_impl_->compositor_gpu_thread()) {
    return gpu_service_impl_->compositor_gpu_thread()
        ->vulkan_context_provider();
  }
  return gpu_service_impl_->vulkan_context_provider();
}

DawnContextProvider* SkiaOutputSurfaceDependencyImpl::GetDawnContextProvider() {
  return gpu_service_impl_->dawn_context_provider();
}

const gpu::GpuPreferences& SkiaOutputSurfaceDependencyImpl::GetGpuPreferences()
    const {
  return gpu_service_impl_->gpu_preferences();
}

const gpu::GpuFeatureInfo&
SkiaOutputSurfaceDependencyImpl::GetGpuFeatureInfo() {
  return gpu_service_impl_->gpu_feature_info();
}

gpu::MailboxManager* SkiaOutputSurfaceDependencyImpl::GetMailboxManager() {
  return gpu_service_impl_->mailbox_manager();
}

gpu::ImageFactory* SkiaOutputSurfaceDependencyImpl::GetGpuImageFactory() {
  return gpu_service_impl_->gpu_image_factory();
}

bool SkiaOutputSurfaceDependencyImpl::IsOffscreen() {
  return surface_handle_ == gpu::kNullSurfaceHandle;
}

gpu::SurfaceHandle SkiaOutputSurfaceDependencyImpl::GetSurfaceHandle() {
  return surface_handle_;
}

scoped_refptr<gl::GLSurface> SkiaOutputSurfaceDependencyImpl::CreateGLSurface(
    base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub,
    gl::GLSurfaceFormat format) {
  if (IsOffscreen()) {
    return gl::init::CreateOffscreenGLSurfaceWithFormat(gl::GetDefaultDisplay(),
                                                        gfx::Size(), format);
  } else {
    return gpu::ImageTransportSurface::CreateNativeSurface(
        gl::GetDefaultDisplay(), stub, surface_handle_, format);
  }
}

base::ScopedClosureRunner SkiaOutputSurfaceDependencyImpl::CacheGLSurface(
    gl::GLSurface* surface) {
  gpu_service_impl_->gpu_task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(&gl::GLSurface::AddRef, base::Unretained(surface)));

  auto release_callback = base::BindPostTask(
      gpu_service_impl_->gpu_task_runner(),
      base::BindOnce(&gl::GLSurface::Release, base::Unretained(surface)));

  return base::ScopedClosureRunner(std::move(release_callback));
}

scoped_refptr<base::TaskRunner>
SkiaOutputSurfaceDependencyImpl::GetClientTaskRunner() {
  return client_thread_task_runner_;
}

void SkiaOutputSurfaceDependencyImpl::ScheduleGrContextCleanup() {
  GetSharedContextState()->ScheduleGrContextCleanup();
}

void SkiaOutputSurfaceDependencyImpl::ScheduleDelayedGPUTaskFromGPUThread(
    base::OnceClosure task) {
  constexpr base::TimeDelta kDelayForDelayedWork = base::Milliseconds(2);
  gpu_service_impl_->gpu_task_runner()->PostDelayedTask(
      FROM_HERE, std::move(task), kDelayForDelayedWork);
}

#if BUILDFLAG(IS_WIN)
void SkiaOutputSurfaceDependencyImpl::DidCreateAcceleratedSurfaceChildWindow(
    gpu::SurfaceHandle parent_window,
    gpu::SurfaceHandle child_window) {
  gpu_service_impl_->SendCreatedChildWindow(parent_window, child_window);
}
#endif

void SkiaOutputSurfaceDependencyImpl::RegisterDisplayContext(
    gpu::DisplayContext* display_context) {
  gpu_service_impl_->RegisterDisplayContext(display_context);
}

void SkiaOutputSurfaceDependencyImpl::UnregisterDisplayContext(
    gpu::DisplayContext* display_context) {
  gpu_service_impl_->UnregisterDisplayContext(display_context);
}

void SkiaOutputSurfaceDependencyImpl::DidLoseContext(
    gpu::error::ContextLostReason reason,
    const GURL& active_url) {
  // |offscreen| is used to determine if it's compositing context or not to
  // decide if we need to disable webgl and canvas.
  gpu_service_impl_->DidLoseContext(/*offscreen=*/false, reason, active_url);
}

base::TimeDelta
SkiaOutputSurfaceDependencyImpl::GetGpuBlockedTimeSinceLastSwap() {
  return gpu_service_impl_->GetGpuScheduler()->TakeTotalBlockingTime();
}

bool SkiaOutputSurfaceDependencyImpl::NeedsSupportForExternalStencil() {
  return false;
}

}  // namespace viz
