// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/renderers/video_frame_yuv_mailboxes_holder.h"

#include <GLES3/gl3.h>

#include "base/logging.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/shared_image_format.h"
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "media/base/media_switches.h"
#include "media/base/video_util.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkYUVAPixmaps.h"

namespace media {

namespace {

viz::SharedImageFormat PlaneSharedImageFormat(int num_channels,
                                              bool supports_red) {
  switch (num_channels) {
    case 1:
      return supports_red ? viz::SinglePlaneFormat::kR_8
                          : viz::SinglePlaneFormat::kLUMINANCE_8;
    case 2:
      return viz::SinglePlaneFormat::kRG_88;
    case 3:
      return viz::SinglePlaneFormat::kRGBX_8888;
    case 4:
      return viz::SinglePlaneFormat::kRGBA_8888;
  }
  NOTREACHED_NORETURN();
}

// Returns multiplanar format equivalent of a VideoPixelFormat.
viz::SharedImageFormat VideoPixelFormatToSharedImageFormat(
    VideoPixelFormat video_format) {
  switch (video_format) {
    case PIXEL_FORMAT_NV12:
      return viz::MultiPlaneFormat::kNV12;
    case PIXEL_FORMAT_NV16:
      return viz::MultiPlaneFormat::kNV16;
    case PIXEL_FORMAT_NV24:
      return viz::MultiPlaneFormat::kNV24;
    case PIXEL_FORMAT_NV12A:
      return viz::MultiPlaneFormat::kNV12A;
    case PIXEL_FORMAT_P016LE:
      return viz::MultiPlaneFormat::kP010;
    case PIXEL_FORMAT_P216LE:
      return viz::MultiPlaneFormat::kP210;
    case PIXEL_FORMAT_P416LE:
      return viz::MultiPlaneFormat::kP410;
    case PIXEL_FORMAT_I420:
      return viz::MultiPlaneFormat::kI420;
    case PIXEL_FORMAT_I420A:
      return viz::MultiPlaneFormat::kI420A;
    default:
      NOTREACHED_NORETURN();
  }
}

}  // namespace

VideoFrameYUVMailboxesHolder::VideoFrameYUVMailboxesHolder() = default;

VideoFrameYUVMailboxesHolder::~VideoFrameYUVMailboxesHolder() {
  ReleaseCachedData();
}

void VideoFrameYUVMailboxesHolder::ReleaseCachedData() {
  if (holders_[0].mailbox.IsZero())
    return;

  // Don't destroy shared images we don't own.
  if (!created_shared_images_)
    return;

  auto* ri = provider_->RasterInterface();
  DCHECK(ri);
  gpu::SyncToken token;
  ri->GenUnverifiedSyncTokenCHROMIUM(token.GetData());

  auto* sii = provider_->SharedImageInterface();
  DCHECK(sii);
  for (unsigned int i = 0; i < kMaxPlanes; ++i) {
    if (shared_images_[i]) {
      sii->DestroySharedImage(token, std::move(shared_images_[i]));
    }
    holders_[i].mailbox.SetZero();
  }

  created_shared_images_ = false;
}

void VideoFrameYUVMailboxesHolder::VideoFrameToMailboxes(
    const VideoFrame* video_frame,
    viz::RasterContextProvider* raster_context_provider,
    gpu::Mailbox mailboxes[SkYUVAInfo::kMaxPlanes],
    bool allow_multiplanar_for_upload) {
  yuva_info_ = VideoFrameGetSkYUVAInfo(video_frame);
  num_planes_ = yuva_info_.planeDimensions(plane_sizes_);

  // If we have cached shared images but the provider or video has changed we
  // need to release shared images created on the old context and recreate them.
  if (created_shared_images_ &&
      (provider_.get() != raster_context_provider ||
       video_frame->coded_size() != cached_video_size_ ||
       video_frame->ColorSpace() != cached_video_color_space_)) {
    ReleaseCachedData();
  }
  provider_ = raster_context_provider;
  DCHECK(provider_);
  auto* ri = provider_->RasterInterface();
  DCHECK(ri);

  if (video_frame->HasTextures()) {
    // Video frames with mailboxes will have shared images per plane as new
    // multiplanar shared image with mailbox path should not go through
    // VideoFrameToMailboxes.
    DCHECK_EQ(num_planes_, video_frame->NumTextures());
    for (size_t plane = 0; plane < video_frame->NumTextures(); ++plane) {
      holders_[plane] = video_frame->mailbox_holder(plane);
      DCHECK(holders_[plane].texture_target == GL_TEXTURE_2D ||
             holders_[plane].texture_target == GL_TEXTURE_EXTERNAL_OES ||
             holders_[plane].texture_target == GL_TEXTURE_RECTANGLE_ARB)
          << "Unsupported texture target " << std::hex << std::showbase
          << holders_[plane].texture_target;
      ri->WaitSyncTokenCHROMIUM(holders_[plane].sync_token.GetConstData());
      mailboxes[plane] = holders_[plane].mailbox;
    }
    return;
  }

  CHECK(!video_frame->HasTextures());
  constexpr SkAlphaType kPlaneAlphaType = kPremul_SkAlphaType;
  auto* sii = provider_->SharedImageInterface();
  DCHECK(sii);

  // These SharedImages will be written to (and later read from) via the raster
  // interface. The full usage depends on whether raster is OOP or is going
  // over the GLES2 interface.
  uint32_t mailbox_usage = gpu::SHARED_IMAGE_USAGE_RASTER_READ |
                           gpu::SHARED_IMAGE_USAGE_RASTER_WRITE;
  auto& caps = provider_->ContextCapabilities();
  if (caps.gpu_rasterization) {
    mailbox_usage |= gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
  } else {
    // NOTE: This GLES2 usage is *only* for raster, as these SharedImages are
    // created to hold YUV data that is then converted to RGBA via the raster
    // interface before being shared with some other use case (e.g., WebGL).
    // There is no flow wherein these SharedImages are directly exposed to
    // WebGL. Moreover, this raster usage is by definition *only* over GLES2
    // (since this is non-OOP-R). It is critical to specify both of these facts
    // to the service side to ensure that the needed SharedImage backing gets
    // created (see crbug.com/328472684).
    mailbox_usage |= gpu::SHARED_IMAGE_USAGE_GLES2_READ |
                     gpu::SHARED_IMAGE_USAGE_GLES2_WRITE |
                     gpu::SHARED_IMAGE_USAGE_GLES2_FOR_RASTER_ONLY |
                     gpu::SHARED_IMAGE_USAGE_RASTER_OVER_GLES2_ONLY;
  }

  // Enabled with flags UseWritePixelsYUV and
  // UseMultiPlaneFormatForHardwareVideo.
  if (allow_multiplanar_for_upload) {
    SkPixmap pixmaps[SkYUVAInfo::kMaxPlanes] = {};
    viz::SharedImageFormat format =
        VideoPixelFormatToSharedImageFormat(video_frame->format());
    CHECK(format.is_multi_plane());

    // Create a multiplanar shared image to upload the data to, if one doesn't
    // exist already.
    if (!created_shared_images_) {
      auto client_shared_image = sii->CreateSharedImage(
          {format, video_frame->coded_size(), video_frame->ColorSpace(),
           kTopLeft_GrSurfaceOrigin, kPlaneAlphaType, mailbox_usage,
           "VideoFrameYUV"},
          gpu::kNullSurfaceHandle);
      CHECK(client_shared_image);
      holders_[0].mailbox = client_shared_image->mailbox();
      holders_[0].texture_target = GL_TEXTURE_2D;
      shared_images_[0] = std::move(client_shared_image);

      // Split up shared image creation from upload so we only have to wait on
      // one sync token.
      ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());

      cached_video_size_ = video_frame->coded_size();
      cached_video_color_space_ = video_frame->ColorSpace();
      created_shared_images_ = true;
    }

    for (size_t plane = 0; plane < num_planes_; ++plane) {
      SkColorType color_type =
          viz::ToClosestSkColorType(/*gpu_compositing=*/true, format, plane);
      SkImageInfo info =
          SkImageInfo::Make(plane_sizes_[plane], color_type, kPlaneAlphaType);
      pixmaps[plane] =
          SkPixmap(info, video_frame->data(plane), video_frame->stride(plane));
    }
    SkYUVAPixmaps yuv_pixmap =
        SkYUVAPixmaps::FromExternalPixmaps(yuva_info_, pixmaps);
    ri->WritePixelsYUV(holders_[0].mailbox, yuv_pixmap);
    mailboxes[0] = holders_[0].mailbox;
    return;
  }

  // Create shared images to upload the data to, if they doesn't exist already.
  if (!created_shared_images_) {
    for (size_t plane = 0; plane < num_planes_; ++plane) {
      gfx::Size tex_size = {plane_sizes_[plane].width(),
                            plane_sizes_[plane].height()};
      int num_channels = yuva_info_.numChannelsInPlane(plane);
      viz::SharedImageFormat format =
          PlaneSharedImageFormat(num_channels, caps.texture_rg);
      auto client_shared_image =
          sii->CreateSharedImage({format, tex_size, video_frame->ColorSpace(),
                                  kTopLeft_GrSurfaceOrigin, kPlaneAlphaType,
                                  mailbox_usage, "VideoFrameYUV"},
                                 gpu::kNullSurfaceHandle);
      CHECK(client_shared_image);
      holders_[plane].mailbox = client_shared_image->mailbox();
      holders_[plane].texture_target = GL_TEXTURE_2D;
      shared_images_[plane] = std::move(client_shared_image);
    }

    // Split up shared image creation from upload so we only have to wait on
    // one sync token.
    ri->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData());

    cached_video_size_ = video_frame->coded_size();
    cached_video_color_space_ = video_frame->ColorSpace();
    created_shared_images_ = true;
  }

  for (size_t plane = 0; plane < num_planes_; ++plane) {
    int num_channels = yuva_info_.numChannelsInPlane(plane);
    SkColorType color_type = SkYUVAPixmapInfo::DefaultColorTypeForDataType(
        SkYUVAPixmaps::DataType::kUnorm8, num_channels);
    SkImageInfo info =
        SkImageInfo::Make(plane_sizes_[plane], color_type, kPlaneAlphaType);
    ri->WritePixels(
        holders_[plane].mailbox, /*dst_x_offset=*/0, /*dst_y_offset=*/0,
        GL_TEXTURE_2D,
        SkPixmap(info, video_frame->data(plane), video_frame->stride(plane)));
    mailboxes[plane] = holders_[plane].mailbox;
  }
}

// static
SkYUVAInfo VideoFrameYUVMailboxesHolder::VideoFrameGetSkYUVAInfo(
    const VideoFrame* video_frame) {
  SkISize video_size{video_frame->coded_size().width(),
                     video_frame->coded_size().height()};
  auto plane_config = SkYUVAInfo::PlaneConfig::kUnknown;
  auto subsampling = SkYUVAInfo::Subsampling::kUnknown;
  std::tie(plane_config, subsampling) =
      VideoPixelFormatToSkiaValues(video_frame->format());

  // TODO(crbug.com/41380578): This should really default to rec709.
  SkYUVColorSpace color_space = kRec601_SkYUVColorSpace;
  video_frame->ColorSpace().ToSkYUVColorSpace(video_frame->BitDepth(),
                                              &color_space);
  return SkYUVAInfo(video_size, plane_config, subsampling, color_space);
}

}  // namespace media
