// Copyright 2017 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 "ui/gl/gl_image_dxgi.h"

#include <d3d11_1.h>

#include "base/debug/alias.h"
#include "third_party/khronos/EGL/egl.h"
#include "third_party/khronos/EGL/eglext.h"
#include "ui/gl/gl_angle_util_win.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_surface_egl.h"

#ifndef EGL_ANGLE_d3d_texture_client_buffer
#define EGL_ANGLE_d3d_texture_client_buffer 1
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
#endif /* EGL_ANGLE_d3d_texture_client_buffer */

namespace gl {

namespace {
// Keys used to acquire and release the keyed mutex.  Will need to be kept in
// sync with any other code that reads from or draws to the same DXGI handle.
const static UINT64 KEY_BIND = 0;
const static UINT64 KEY_RELEASE = 1;

bool SupportedBindFormat(gfx::BufferFormat format) {
  switch (format) {
    case gfx::BufferFormat::RGBA_8888:
    case gfx::BufferFormat::RGBX_8888:
      return true;
    default:
      return false;
  };
}

bool HasAlpha(gfx::BufferFormat format) {
  DCHECK(SupportedBindFormat(format));
  switch (format) {
    case gfx::BufferFormat::RGBA_8888:
      return true;
    case gfx::BufferFormat::RGBX_8888:
      return false;
    default:
      NOTREACHED();
      return false;
  };
}

EGLConfig ChooseCompatibleConfig(gfx::BufferFormat format) {
  DCHECK(SupportedBindFormat(format));

  const EGLint buffer_bind_to_texture =
      HasAlpha(format) ? EGL_BIND_TO_TEXTURE_RGBA : EGL_BIND_TO_TEXTURE_RGB;
  const EGLint buffer_size = HasAlpha(format) ? 32 : 24;
  EGLint const attrib_list[] = {EGL_RED_SIZE,
                                8,
                                EGL_GREEN_SIZE,
                                8,
                                EGL_BLUE_SIZE,
                                8,
                                EGL_SURFACE_TYPE,
                                EGL_PBUFFER_BIT,
                                buffer_bind_to_texture,
                                EGL_TRUE,
                                EGL_BUFFER_SIZE,
                                buffer_size,
                                EGL_NONE};

  EGLint num_config;
  EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay();
  EGLBoolean result =
      eglChooseConfig(display, attrib_list, nullptr, 0, &num_config);
  if (result != EGL_TRUE)
    return nullptr;
  std::vector<EGLConfig> all_configs(num_config);
  result = eglChooseConfig(gl::GLSurfaceEGL::GetHardwareDisplay(), attrib_list,
                           all_configs.data(), num_config, &num_config);
  if (result != EGL_TRUE)
    return nullptr;
  for (EGLConfig config : all_configs) {
    EGLint bits;
    if (!eglGetConfigAttrib(display, config, EGL_RED_SIZE, &bits) ||
        bits != 8) {
      continue;
    }

    if (!eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &bits) ||
        bits != 8) {
      continue;
    }

    if (!eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &bits) ||
        bits != 8) {
      continue;
    }

    if (HasAlpha(format) &&
        (!eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &bits) ||
         bits != 8)) {
      continue;
    }

    return config;
  }
  return nullptr;
}

EGLSurface CreatePbuffer(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture,
                         gfx::BufferFormat format,
                         EGLConfig config,
                         unsigned target) {
  DCHECK(SupportedBindFormat(format));

  D3D11_TEXTURE2D_DESC desc;
  texture->GetDesc(&desc);
  EGLint width = desc.Width;
  EGLint height = desc.Height;

  EGLint pBufferAttributes[] = {
      EGL_WIDTH,
      width,
      EGL_HEIGHT,
      height,
      EGL_TEXTURE_TARGET,
      EGL_TEXTURE_2D,
      EGL_TEXTURE_FORMAT,
      HasAlpha(format) ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
      EGL_NONE};

  return eglCreatePbufferFromClientBuffer(
      gl::GLSurfaceEGL::GetHardwareDisplay(), EGL_D3D_TEXTURE_ANGLE,
      texture.Get(), config, pBufferAttributes);
}

}  // namespace

GLImageDXGI::GLImageDXGI(const gfx::Size& size, EGLStreamKHR stream)
    : size_(size), stream_(stream) {}

// static
GLImageDXGI* GLImageDXGI::FromGLImage(GLImage* image) {
  if (!image || image->GetType() != Type::DXGI_IMAGE)
    return nullptr;
  return static_cast<GLImageDXGI*>(image);
}

bool GLImageDXGI::BindTexImage(unsigned target) {
  if (!handle_.Get())
    return true;

  DCHECK(texture_);
  DCHECK(keyed_mutex_);
  if (!SupportedBindFormat(buffer_format_))
    return false;

  // Lazy-initialize surface_, as it is only used for binding.
  if (surface_ == EGL_NO_SURFACE) {
    EGLConfig config = ChooseCompatibleConfig(buffer_format_);
    if (!config)
      return false;
    surface_ = CreatePbuffer(texture_, buffer_format_, config, target);
    if (surface_ == EGL_NO_SURFACE)
      return false;
  }

  // We don't wait, just return immediately.
  HRESULT hrWait = keyed_mutex_->AcquireSync(KEY_BIND, 0);

  if (hrWait == WAIT_TIMEOUT || hrWait == WAIT_ABANDONED || FAILED(hrWait)) {
    NOTREACHED();
    return false;
  }

  return eglBindTexImage(gl::GLSurfaceEGL::GetHardwareDisplay(), surface_,
                         EGL_BACK_BUFFER) == EGL_TRUE;
}

bool GLImageDXGI::CopyTexImage(unsigned target) {
  return false;
}

bool GLImageDXGI::CopyTexSubImage(unsigned target,
                                  const gfx::Point& offset,
                                  const gfx::Rect& rect) {
  return false;
}

void GLImageDXGI::Flush() {}

unsigned GLImageDXGI::GetInternalFormat() {
  if (!handle_.Get())
    return GL_BGRA_EXT;
  else
    return HasAlpha(buffer_format_) ? GL_RGBA : GL_RGB;
}

gfx::Size GLImageDXGI::GetSize() {
  return size_;
}

GLImage::Type GLImageDXGI::GetType() const {
  return Type::DXGI_IMAGE;
}

void GLImageDXGI::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
                               uint64_t process_tracing_id,
                               const std::string& dump_name) {}

void GLImageDXGI::ReleaseTexImage(unsigned target) {
  if (!handle_.Get())
    return;

  DCHECK(texture_);
  DCHECK(keyed_mutex_);

  Microsoft::WRL::ComPtr<ID3D11Device> device =
      QueryD3D11DeviceObjectFromANGLE();
  Microsoft::WRL::ComPtr<ID3D11Device1> device1;
  device.CopyTo(device1.GetAddressOf());

  keyed_mutex_->ReleaseSync(KEY_RELEASE);

  eglReleaseTexImage(gl::GLSurfaceEGL::GetHardwareDisplay(), surface_,
                     EGL_BACK_BUFFER);
}

bool GLImageDXGI::ScheduleOverlayPlane(
    gfx::AcceleratedWidget widget,
    int z_order,
    gfx::OverlayTransform transform,
    const gfx::Rect& bounds_rect,
    const gfx::RectF& crop_rect,
    bool enable_blend,
    std::unique_ptr<gfx::GpuFence> gpu_fence) {
  return false;
}

void GLImageDXGI::SetColorSpace(const gfx::ColorSpace& color_space) {
  color_space_ = color_space;
}

bool GLImageDXGI::InitializeHandle(base::win::ScopedHandle handle,
                                   uint32_t level,
                                   gfx::BufferFormat format) {
  level_ = level;
  buffer_format_ = format;
  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      QueryD3D11DeviceObjectFromANGLE();
  if (!d3d11_device)
    return false;

  Microsoft::WRL::ComPtr<ID3D11Device1> d3d11_device1;
  if (FAILED(d3d11_device.CopyTo(d3d11_device1.GetAddressOf())))
    return false;

  if (FAILED(d3d11_device1->OpenSharedResource1(
          handle.Get(), IID_PPV_ARGS(texture_.GetAddressOf())))) {
    return false;
  }
  D3D11_TEXTURE2D_DESC desc;
  texture_->GetDesc(&desc);
  if (desc.ArraySize <= level_)
    return false;
  if (FAILED(texture_.CopyTo(keyed_mutex_.GetAddressOf())))
    return false;

  handle_ = std::move(handle);
  return true;
}

void GLImageDXGI::SetTexture(
    const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture,
    size_t level) {
  texture_ = texture;
  level_ = level;
}

GLImageDXGI::~GLImageDXGI() {
  if (handle_.Get()) {
    if (surface_ != EGL_NO_SURFACE) {
      eglDestroySurface(gl::GLSurfaceEGL::GetHardwareDisplay(), surface_);
    }
  } else if (stream_) {
    EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();
    eglDestroyStreamKHR(egl_display, stream_);
  }
}

CopyingGLImageDXGI::CopyingGLImageDXGI(
    const Microsoft::WRL::ComPtr<ID3D11Device>& d3d11_device,
    const gfx::Size& size,
    EGLStreamKHR stream)
    : GLImageDXGI(size, stream), d3d11_device_(d3d11_device) {}

bool CopyingGLImageDXGI::Initialize() {
  D3D11_TEXTURE2D_DESC desc;
  desc.Width = size_.width();
  desc.Height = size_.height();
  desc.MipLevels = 1;
  desc.ArraySize = 1;
  desc.Format = DXGI_FORMAT_NV12;
  desc.SampleDesc.Count = 1;
  desc.SampleDesc.Quality = 0;
  desc.Usage = D3D11_USAGE_DEFAULT;
  desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
  desc.CPUAccessFlags = 0;
  desc.MiscFlags = 0;

  HRESULT hr = d3d11_device_->CreateTexture2D(
      &desc, nullptr, decoder_copy_texture_.GetAddressOf());
  if (FAILED(hr)) {
    DLOG(ERROR) << "CreateTexture2D failed: " << std::hex << hr;
    return false;
  }
  EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay();

  EGLAttrib frame_attributes[] = {
      EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0, EGL_NONE,
  };

  EGLBoolean result = eglStreamPostD3DTextureANGLE(
      egl_display, stream_, static_cast<void*>(decoder_copy_texture_.Get()),
      frame_attributes);
  if (!result) {
    DLOG(ERROR) << "eglStreamPostD3DTextureANGLE failed";
    return false;
  }
  result = eglStreamConsumerAcquireKHR(egl_display, stream_);
  if (!result) {
    DLOG(ERROR) << "eglStreamConsumerAcquireKHR failed";
    return false;
  }

  d3d11_device_.CopyTo(video_device_.GetAddressOf());
  Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
  d3d11_device_->GetImmediateContext(context.GetAddressOf());
  context.CopyTo(video_context_.GetAddressOf());

#if DCHECK_IS_ON()
  Microsoft::WRL::ComPtr<ID3D10Multithread> multithread;
  d3d11_device_.CopyTo(multithread.GetAddressOf());
  DCHECK(multithread->GetMultithreadProtected());
#endif  // DCHECK_IS_ON()

  return true;
}

bool CopyingGLImageDXGI::InitializeVideoProcessor(
    const Microsoft::WRL::ComPtr<ID3D11VideoProcessor>& video_processor,
    const Microsoft::WRL::ComPtr<ID3D11VideoProcessorEnumerator>& enumerator) {
  output_view_.Reset();

  Microsoft::WRL::ComPtr<ID3D11Device> processor_device;
  video_processor->GetDevice(processor_device.GetAddressOf());
  DCHECK_EQ(d3d11_device_.Get(), processor_device.Get());

  d3d11_processor_ = video_processor;
  enumerator_ = enumerator;
  D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_view_desc = {
      D3D11_VPOV_DIMENSION_TEXTURE2D};
  output_view_desc.Texture2D.MipSlice = 0;
  Microsoft::WRL::ComPtr<ID3D11VideoProcessorOutputView> output_view;
  HRESULT hr = video_device_->CreateVideoProcessorOutputView(
      decoder_copy_texture_.Get(), enumerator_.Get(), &output_view_desc,
      output_view_.GetAddressOf());
  if (FAILED(hr)) {
    DLOG(ERROR) << "Failed to get output view";
    return false;
  }
  return true;
}

void CopyingGLImageDXGI::UnbindFromTexture() {
  copied_ = false;
}

bool CopyingGLImageDXGI::BindTexImage(unsigned target) {
  if (copied_)
    return true;

  DCHECK(video_device_);
  Microsoft::WRL::ComPtr<ID3D11Device> texture_device;
  texture_->GetDevice(texture_device.GetAddressOf());
  DCHECK_EQ(d3d11_device_.Get(), texture_device.Get());

  D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_view_desc = {0};
  input_view_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
  input_view_desc.Texture2D.ArraySlice = (UINT)level_;
  input_view_desc.Texture2D.MipSlice = 0;
  Microsoft::WRL::ComPtr<ID3D11VideoProcessorInputView> input_view;
  HRESULT hr = video_device_->CreateVideoProcessorInputView(
      texture_.Get(), enumerator_.Get(), &input_view_desc,
      input_view.GetAddressOf());
  if (FAILED(hr)) {
    DLOG(ERROR) << "Failed to create video processor input view.";
    return false;
  }

  D3D11_VIDEO_PROCESSOR_STREAM streams = {0};
  streams.Enable = TRUE;
  streams.pInputSurface = input_view.Get();

  hr = video_context_->VideoProcessorBlt(d3d11_processor_.Get(),
                                         output_view_.Get(), 0, 1, &streams);
  if (FAILED(hr)) {
    DLOG(ERROR) << "Failed to process video";
    return false;
  }
  copied_ = true;
  return true;
}

CopyingGLImageDXGI::~CopyingGLImageDXGI() {}

}  // namespace gl
