// Copyright 2014 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 "media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h"

#include "media/gpu/vaapi/va_surface.h"
#include "media/gpu/vaapi/vaapi_wrapper.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_pixmap.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_image_native_pixmap.h"
#include "ui/gl/scoped_binders.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/surface_factory_ozone.h"

namespace media {

VaapiPictureNativePixmapOzone::VaapiPictureNativePixmapOzone(
    scoped_refptr<VaapiWrapper> vaapi_wrapper,
    const MakeGLContextCurrentCallback& make_context_current_cb,
    const BindGLImageCallback& bind_image_cb,
    int32_t picture_buffer_id,
    const gfx::Size& size,
    const gfx::Size& visible_size,
    uint32_t texture_id,
    uint32_t client_texture_id,
    uint32_t texture_target)
    : VaapiPictureNativePixmap(std::move(vaapi_wrapper),
                               make_context_current_cb,
                               bind_image_cb,
                               picture_buffer_id,
                               size,
                               visible_size,
                               texture_id,
                               client_texture_id,
                               texture_target) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // Either |texture_id| and |client_texture_id| are both zero, or not.
  DCHECK((texture_id == 0 && client_texture_id == 0) ||
         (texture_id != 0 && client_texture_id != 0));
}

VaapiPictureNativePixmapOzone::~VaapiPictureNativePixmapOzone() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (gl_image_ && make_context_current_cb_.Run()) {
    gl_image_->ReleaseTexImage(texture_target_);
    DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR));
  }
}

Status VaapiPictureNativePixmapOzone::Initialize(
    scoped_refptr<gfx::NativePixmap> pixmap) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(pixmap);
  DCHECK(pixmap->AreDmaBufFdsValid());
  // Create a |va_surface_| from dmabuf fds (pixmap->GetDmaBufFd)
  va_surface_ = vaapi_wrapper_->CreateVASurfaceForPixmap(pixmap);
  if (!va_surface_) {
    LOG(ERROR) << "Failed creating VASurface for NativePixmap";
    return StatusCode::kVaapiNoSurface;
  }

  // ARC++ has no texture ids.
  if (texture_id_ == 0 && client_texture_id_ == 0)
    return OkStatus();

  // Import dmabuf fds into the output gl texture through EGLImage.
  if (make_context_current_cb_ && !make_context_current_cb_.Run())
    return StatusCode::kVaapiBadContext;

  gl::ScopedTextureBinder texture_binder(texture_target_, texture_id_);

  const gfx::BufferFormat format = pixmap->GetBufferFormat();

  auto image =
      base::MakeRefCounted<gl::GLImageNativePixmap>(visible_size_, format);
  if (!image->Initialize(std::move(pixmap))) {
    LOG(ERROR) << "Failed to create GLImage";
    return StatusCode::kVaapiFailedToInitializeImage;
  }

  gl_image_ = image;
  if (!gl_image_->BindTexImage(texture_target_)) {
    LOG(ERROR) << "Failed to bind texture to GLImage";
    return StatusCode::kVaapiFailedToBindTexture;
  }

  if (bind_image_cb_ &&
      !bind_image_cb_.Run(client_texture_id_, texture_target_, gl_image_,
                          true /* can_bind_to_sampler */)) {
    LOG(ERROR) << "Failed to bind client_texture_id";
    return StatusCode::kVaapiFailedToBindImage;
  }

  return OkStatus();
}

Status VaapiPictureNativePixmapOzone::Allocate(gfx::BufferFormat format) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
  ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
  auto pixmap = factory->CreateNativePixmap(
      gfx::kNullAcceleratedWidget, VK_NULL_HANDLE, size_, format,
      gfx::BufferUsage::SCANOUT_VDA_WRITE, /*framebuffer_size=*/visible_size_);
  if (!pixmap) {
    return StatusCode::kVaapiNoPixmap;
  }

  return Initialize(std::move(pixmap));
}

bool VaapiPictureNativePixmapOzone::ImportGpuMemoryBufferHandle(
    gfx::BufferFormat format,
    gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  const auto& plane = gpu_memory_buffer_handle.native_pixmap_handle.planes[0];
  if (size_.width() > static_cast<int>(plane.stride) ||
      size_.GetArea() > static_cast<int>(plane.size)) {
    DLOG(ERROR) << "GpuMemoryBufferHandle (stride=" << plane.stride
                << ", size=" << plane.size
                << "is smaller than size_=" << size_.ToString();
    return false;
  }

  ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance();
  ui::SurfaceFactoryOzone* factory = platform->GetSurfaceFactoryOzone();
  // CreateNativePixmapFromHandle() will take ownership of the handle.
  auto pixmap = factory->CreateNativePixmapFromHandle(
      gfx::kNullAcceleratedWidget, size_, format,
      std::move(gpu_memory_buffer_handle.native_pixmap_handle));

  if (!pixmap) {
    LOG(ERROR) << "Failed creating a pixmap from a native handle";
    return false;
  }

  return Initialize(std::move(pixmap)).is_ok();
}

}  // namespace media
