// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/uwp/decode_target_internal.h"

#include "starboard/configuration.h"
#include "starboard/log.h"
#include "starboard/memory.h"
#include "starboard/shared/win32/error_utils.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
#include "third_party/angle/include/GLES2/gl2.h"
#include "third_party/angle/include/GLES2/gl2ext.h"

namespace {

using Microsoft::WRL::ComPtr;
using starboard::shared::win32::CheckResult;

// {3C3A43AB-C69B-46C9-AA8D-B0CFFCD4596D}
const GUID kCobaltNv12BindChroma = {
    0x3c3a43ab,
    0xc69b,
    0x46c9,
    {0xaa, 0x8d, 0xb0, 0xcf, 0xfc, 0xd4, 0x59, 0x6d}};

// {C62BF18D-B5EE-46B1-9C31-F61BD8AE3B0D}
const GUID kCobaltDxgiBuffer = {
    0Xc62bf18d,
    0Xb5ee,
    0X46b1,
    {0X9c, 0X31, 0Xf6, 0X1b, 0Xd8, 0Xae, 0X3b, 0X0d}};

ComPtr<ID3D11Texture2D> CreateEmptyTexture(
    const ComPtr<ID3D11Device>& d3d_device,
    int width,
    int height) {
  ComPtr<ID3D11Texture2D> texture;
  D3D11_TEXTURE2D_DESC texture_desc = {};
  texture_desc.Width = width;
  texture_desc.Height = height;
  texture_desc.MipLevels = 1;
  texture_desc.ArraySize = 1;
  texture_desc.Format = DXGI_FORMAT_NV12;
  texture_desc.SampleDesc.Count = 1;
  texture_desc.SampleDesc.Quality = 0;
  texture_desc.Usage = D3D11_USAGE_DEFAULT;
  texture_desc.BindFlags =
      D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
  CheckResult(d3d_device->CreateTexture2D(&texture_desc, nullptr,
                                          texture.GetAddressOf()));
  return texture;
}

void UpdateTexture(
    const ComPtr<ID3D11Texture2D>& texture,
    const ComPtr<ID3D11VideoDevice1>& video_device,
    const ComPtr<ID3D11VideoContext>& video_context,
    const ComPtr<ID3D11VideoProcessorEnumerator>& video_enumerator,
    const ComPtr<ID3D11VideoProcessor>& video_processor,
    const ComPtr<IMFSample>& video_sample,
    const RECT& video_area) {
  ComPtr<IMFMediaBuffer> media_buffer;
  CheckResult(video_sample->GetBufferByIndex(0, media_buffer.GetAddressOf()));

  ComPtr<IMFDXGIBuffer> dxgi_buffer;
  CheckResult(media_buffer.As(&dxgi_buffer));

  ComPtr<ID3D11Texture2D> input_texture;
  CheckResult(dxgi_buffer->GetResource(IID_PPV_ARGS(&input_texture)));

  // The VideoProcessor needs to know what subset of the decoded
  // frame contains active pixels that should be displayed to the user.
  video_context->VideoProcessorSetStreamSourceRect(video_processor.Get(), 0,
                                                   TRUE, &video_area);

  D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_desc = {};
  input_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
  input_desc.Texture2D.MipSlice = 0;
  dxgi_buffer->GetSubresourceIndex(&input_desc.Texture2D.ArraySlice);

  ComPtr<ID3D11VideoProcessorInputView> input_view;
  CheckResult(video_device->CreateVideoProcessorInputView(
      input_texture.Get(), video_enumerator.Get(), &input_desc,
      input_view.GetAddressOf()));

  D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_desc = {};
  output_desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D;
  output_desc.Texture2D.MipSlice = 0;

  ComPtr<ID3D11VideoProcessorOutputView> output_view;
  CheckResult(video_device->CreateVideoProcessorOutputView(
      texture.Get(), video_enumerator.Get(), &output_desc,
      output_view.GetAddressOf()));

  // We have a single video stream, which is enabled for display.
  D3D11_VIDEO_PROCESSOR_STREAM stream_info = {};
  stream_info.Enable = TRUE;
  stream_info.pInputSurface = input_view.Get();
  CheckResult(video_context->VideoProcessorBlt(
      video_processor.Get(), output_view.Get(), 0, 1, &stream_info));
}

ComPtr<ID3D11Texture2D> CreateVPXTexture(const ComPtr<ID3D11Device>& d3d_device,
                                         const vpx_image_t* img,
                                         BYTE* frame_buf_nv12) {
  ComPtr<ID3D11Texture2D> texture;
  D3D11_TEXTURE2D_DESC texture_desc = {};
  texture_desc.Width = img->w;
  texture_desc.Height = img->h;
  texture_desc.MipLevels = 1;
  texture_desc.ArraySize = 1;
  texture_desc.Format = DXGI_FORMAT_NV12;
  texture_desc.SampleDesc.Count = 1;
  texture_desc.SampleDesc.Quality = 0;
  texture_desc.Usage = D3D11_USAGE_DEFAULT;
  texture_desc.BindFlags = D3D11_BIND_DECODER | D3D11_BIND_SHADER_RESOURCE;

  BYTE* pData = frame_buf_nv12;
  SbMemoryCopy(pData, img->planes[VPX_PLANE_Y], img->w * img->h);
  pData += texture_desc.Width * texture_desc.Height;

  unsigned int j = 0;
  for (unsigned int i = 0; i < (img->w * img->h / 4); i++) {
    pData[j++] = img->planes[VPX_PLANE_U][i];
    pData[j++] = img->planes[VPX_PLANE_V][i];
  }

  D3D11_SUBRESOURCE_DATA tSData;
  tSData.pSysMem = frame_buf_nv12;
  tSData.SysMemPitch = img->w;
  tSData.SysMemSlicePitch = img->w * img->h + (img->w * img->h / 2);
  CheckResult(d3d_device->CreateTexture2D(&texture_desc, &tSData,
                                          texture.GetAddressOf()));
  return texture;
}

}  // namespace
void SbDecodeTargetPrivate::CreateGLSurfacesNV12(
    const ComPtr<ID3D11Texture2D>& texture,
    int display_width,
    int display_height) {
  SbDecodeTargetInfoPlane* planeY = &(info.planes[kSbDecodeTargetPlaneY]);
  SbDecodeTargetInfoPlane* planeUV = &(info.planes[kSbDecodeTargetPlaneUV]);

  planeY->width = info.width;
  planeY->height = info.height;
  planeY->content_region.left = 0;
  planeY->content_region.top = display_height;
  planeY->content_region.right = display_width;
  planeY->content_region.bottom = 0;

  planeUV->width = info.width / 2;
  planeUV->height = info.height / 2;
  planeUV->content_region.left = planeY->content_region.left / 2;
  planeUV->content_region.top = planeY->content_region.top / 2;
  planeUV->content_region.right = planeY->content_region.right / 2;
  planeUV->content_region.bottom = planeY->content_region.bottom / 2;

  EGLint luma_texture_attributes[] = {EGL_WIDTH,
                                      static_cast<EGLint>(info.width),
                                      EGL_HEIGHT,
                                      static_cast<EGLint>(info.height),
                                      EGL_TEXTURE_TARGET,
                                      EGL_TEXTURE_2D,
                                      EGL_TEXTURE_FORMAT,
                                      EGL_TEXTURE_RGBA,
                                      EGL_NONE};

  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

  EGLConfig config;
  EGLint attribute_list[] = {EGL_SURFACE_TYPE,  // this must be first
                             EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
                             EGL_RED_SIZE,
                             8,
                             EGL_GREEN_SIZE,
                             8,
                             EGL_BLUE_SIZE,
                             8,
                             EGL_ALPHA_SIZE,
                             8,
                             EGL_BIND_TO_TEXTURE_RGBA,
                             EGL_TRUE,
                             EGL_RENDERABLE_TYPE,
                             EGL_OPENGL_ES2_BIT,
                             EGL_NONE};

  EGLint num_configs;
  bool ok = eglChooseConfig(display, attribute_list, &config, 1, &num_configs);
  SB_DCHECK(ok);
  SB_DCHECK(num_configs == 1);

  GLuint gl_textures[2] = {0};
  glGenTextures(2, gl_textures);
  SB_DCHECK(glGetError() == GL_NO_ERROR);

  // This tells ANGLE that the texture it creates should draw
  // the luma channel on R8.
  HRESULT hr = texture->SetPrivateData(kCobaltNv12BindChroma, 0, nullptr);
  SB_DCHECK(SUCCEEDED(hr));

  surface[0] = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
                                                texture.Get(), config,
                                                luma_texture_attributes);

  SB_DCHECK(surface[0] != EGL_NO_SURFACE);

  glBindTexture(GL_TEXTURE_2D, gl_textures[0]);
  SB_DCHECK(glGetError() == GL_NO_ERROR);

  ok = eglBindTexImage(display, surface[0], EGL_BACK_BUFFER);
  SB_DCHECK(ok);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  planeY->texture = gl_textures[0];
  planeY->gl_texture_target = GL_TEXTURE_2D;
  planeY->gl_texture_format = GL_RED_EXT;

  // This tells ANGLE that the texture it creates should draw
  // the chroma channel on R8G8.
  bool bind_chroma = true;
  hr = texture->SetPrivateData(kCobaltNv12BindChroma, 1, &bind_chroma);
  SB_DCHECK(SUCCEEDED(hr));

  EGLint chroma_texture_attributes[] = {EGL_WIDTH,
                                        static_cast<EGLint>(info.width) / 2,
                                        EGL_HEIGHT,
                                        static_cast<EGLint>(info.height) / 2,
                                        EGL_TEXTURE_TARGET,
                                        EGL_TEXTURE_2D,
                                        EGL_TEXTURE_FORMAT,
                                        EGL_TEXTURE_RGBA,
                                        EGL_NONE};
  surface[1] = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE,
                                                texture.Get(), config,
                                                chroma_texture_attributes);

  SB_DCHECK(surface[1] != EGL_NO_SURFACE);

  glBindTexture(GL_TEXTURE_2D, gl_textures[1]);
  SB_DCHECK(glGetError() == GL_NO_ERROR);

  ok = eglBindTexImage(display, surface[1], EGL_BACK_BUFFER);
  SB_DCHECK(ok);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  planeUV->texture = gl_textures[1];
  planeUV->gl_texture_target = GL_TEXTURE_2D;
  planeUV->gl_texture_format = GL_RG_EXT;

  hr = texture->SetPrivateData(kCobaltDxgiBuffer, 0, nullptr);
  SB_DCHECK(SUCCEEDED(hr));
}

SbDecodeTargetPrivate::SbDecodeTargetPrivate(
    const ComPtr<ID3D11Device>& d3d_device,
    const vpx_image_t* img,
    BYTE* frame_buf_nv12)
    : refcount(1), d3d_device_(d3d_device) {
  SbMemorySet(&info, 0, sizeof(info));
  info.format = kSbDecodeTargetFormat2PlaneYUVNV12;
  info.is_opaque = true;
  info.width = img->w;
  info.height = img->h;

  d3d_texture = CreateVPXTexture(d3d_device, img, frame_buf_nv12);
  CreateGLSurfacesNV12(d3d_texture, img->d_w, img->d_h);
}

SbDecodeTargetPrivate::SbDecodeTargetPrivate(
    const ComPtr<ID3D11Device>& d3d_device,
    const ComPtr<ID3D11VideoDevice1>& video_device,
    const ComPtr<ID3D11VideoContext>& video_context,
    const ComPtr<ID3D11VideoProcessorEnumerator>& video_enumerator,
    const ComPtr<ID3D11VideoProcessor>& video_processor,
    const ComPtr<IMFSample>& video_sample,
    const RECT& video_area)
    : refcount(1) {
  SbMemorySet(&info, 0, sizeof(info));
  info.format = kSbDecodeTargetFormat2PlaneYUVNV12;
  info.is_opaque = true;
  info.width = video_area.right;
  info.height = video_area.bottom;

  d3d_texture = CreateEmptyTexture(d3d_device, info.width, info.height);
  if (video_sample) {
    UpdateTexture(d3d_texture, video_device, video_context, video_enumerator,
                  video_processor, video_sample, video_area);
  }
  CreateGLSurfacesNV12(d3d_texture, info.width, info.height);
}

SbDecodeTargetPrivate::~SbDecodeTargetPrivate() {
  glDeleteTextures(1, &(info.planes[kSbDecodeTargetPlaneY].texture));
  glDeleteTextures(1, &(info.planes[kSbDecodeTargetPlaneUV].texture));

  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

  eglReleaseTexImage(display, surface[0], EGL_BACK_BUFFER);
  eglDestroySurface(display, surface[0]);

  eglReleaseTexImage(display, surface[1], EGL_BACK_BUFFER);
  eglDestroySurface(display, surface[1]);
}

bool SbDecodeTargetPrivate::Update(
    const ComPtr<ID3D11Device>& d3d_device,
    const ComPtr<ID3D11VideoDevice1>& video_device,
    const ComPtr<ID3D11VideoContext>& video_context,
    const ComPtr<ID3D11VideoProcessorEnumerator>& video_enumerator,
    const ComPtr<ID3D11VideoProcessor>& video_processor,
    const ComPtr<IMFSample>& video_sample,
    const RECT& video_area) {
  // Only allow updating if this is the only reference. Otherwise the update
  // may change something that's currently being used.
  if (SbAtomicNoBarrier_Load(&refcount) > 1) {
    return false;
  }

  // The decode target info must be compatible. The resolution should match
  // exactly, otherwise the shader may sample invalid texels along the
  // texture border.
  if (info.format != kSbDecodeTargetFormat2PlaneYUVNV12 ||
      info.is_opaque != true || info.width != video_area.right ||
      info.height != video_area.bottom) {
    return false;
  }

  SB_UNREFERENCED_PARAMETER(d3d_device);
  UpdateTexture(d3d_texture, video_device, video_context, video_enumerator,
                video_processor, video_sample, video_area);
  return true;
}

void SbDecodeTargetPrivate::AddRef() {
  SbAtomicBarrier_Increment(&refcount, 1);
}

void SbDecodeTargetPrivate::Release() {
  int new_count = SbAtomicBarrier_Increment(&refcount, -1);
  SB_DCHECK(new_count >= 0);
  if (new_count == 0) {
    delete this;
  }
}

void SbDecodeTargetRelease(SbDecodeTarget decode_target) {
  if (SbDecodeTargetIsValid(decode_target)) {
    decode_target->Release();
  }
}

SbDecodeTargetFormat SbDecodeTargetGetFormat(SbDecodeTarget decode_target) {
  // Note that kSbDecodeTargetFormat2PlaneYUVNV12 represents DXGI_FORMAT_NV12.
  SB_DCHECK(kSbDecodeTargetFormat2PlaneYUVNV12 == decode_target->info.format);
  return decode_target->info.format;
}

bool SbDecodeTargetGetInfo(SbDecodeTarget decode_target,
                           SbDecodeTargetInfo* out_info) {
  if (!out_info || !SbMemoryIsZero(out_info, sizeof(*out_info))) {
    SB_DCHECK(false) << "out_info must be zeroed out.";
    return false;
  }
  SbMemoryCopy(out_info, &decode_target->info, sizeof(*out_info));
  return true;
}