// Copyright 2013 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/renderers/video_resource_updater.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <string>

#include "base/atomic_sequence_num.h"
#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/containers/cxx20_erase.h"
#include "base/logging.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/base/math_util.h"
#include "cc/paint/skia_paint_canvas.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/client/shared_bitmap_reporter.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/quads/compositor_render_pass.h"
#include "components/viz/common/quads/stream_video_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/quads/video_hole_draw_quad.h"
#include "components/viz/common/quads/yuv_video_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "media/base/video_frame.h"
#include "media/renderers/paint_canvas_video_renderer.h"
#include "media/video/half_float_maker.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/khronos/GLES3/gl3.h"
#include "third_party/libyuv/include/libyuv.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gl/gl_enums.h"
#include "ui/gl/trace_util.h"

namespace media {
namespace {

// Generates process-unique IDs to use for tracing video resources.
base::AtomicSequenceNumber g_next_video_resource_updater_id;

VideoFrameResourceType ExternalResourceTypeForHardwarePlanes(
    VideoPixelFormat format,
    GLuint target,
    int num_textures,
    gfx::BufferFormat buffer_formats[VideoFrame::kMaxPlanes],
    bool use_stream_video_draw_quad,
    bool dcomp_surface) {
  switch (format) {
    case PIXEL_FORMAT_ARGB:
    case PIXEL_FORMAT_XRGB:
    case PIXEL_FORMAT_ABGR:
    case PIXEL_FORMAT_XBGR:
    case PIXEL_FORMAT_BGRA:
      DCHECK_EQ(num_textures, 1);
      // This maps VideoPixelFormat back to GMB BufferFormat
      // NOTE: ABGR == RGBA and ARGB == BGRA, they differ only byte order
      // See: VideoFormat function in gpu_memory_buffer_video_frame_pool
      // https://cs.chromium.org/chromium/src/media/video/gpu_memory_buffer_video_frame_pool.cc?type=cs&g=0&l=281
      buffer_formats[0] =
          (format == PIXEL_FORMAT_ABGR || format == PIXEL_FORMAT_XBGR)
              ? gfx::BufferFormat::RGBA_8888
              : gfx::BufferFormat::BGRA_8888;

      switch (target) {
        case GL_TEXTURE_EXTERNAL_OES:
          // `use_stream_video_draw_quad` is set on Android and `dcomp_surface`
          // is used on Windows.
          // TODO(sunnyps): It's odd to reuse the Android path on Windows. There
          // could be other unknown assumptions in other parts of the rendering
          // stack about stream video quads. Investigate alternative solutions.
          if (use_stream_video_draw_quad || dcomp_surface)
            return VideoFrameResourceType::STREAM_TEXTURE;
          FALLTHROUGH;
        case GL_TEXTURE_2D:
        case GL_TEXTURE_RECTANGLE_ARB:
          return (format == PIXEL_FORMAT_XRGB)
                     ? VideoFrameResourceType::RGB
                     : VideoFrameResourceType::RGBA_PREMULTIPLIED;
        default:
          NOTREACHED();
          break;
      }
      break;
    case PIXEL_FORMAT_XR30:
    case PIXEL_FORMAT_XB30:
      buffer_formats[0] = (format == PIXEL_FORMAT_XR30)
                              ? gfx::BufferFormat::BGRA_1010102
                              : gfx::BufferFormat::RGBA_1010102;
      return VideoFrameResourceType::RGB;
    case PIXEL_FORMAT_I420:
      DCHECK_EQ(num_textures, 3);
      buffer_formats[0] = gfx::BufferFormat::R_8;
      buffer_formats[1] = gfx::BufferFormat::R_8;
      buffer_formats[2] = gfx::BufferFormat::R_8;
      return VideoFrameResourceType::YUV;

    case PIXEL_FORMAT_NV12:
      // |target| is set to 0 for Vulkan textures.
      DCHECK(target == 0 || target == GL_TEXTURE_EXTERNAL_OES ||
             target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB)
          << "Unsupported target " << gl::GLEnums::GetStringEnum(target);

      if (num_textures == 1) {
        // Single-texture multi-planar frames can be sampled as RGB.
        buffer_formats[0] = gfx::BufferFormat::YUV_420_BIPLANAR;
        return VideoFrameResourceType::RGB;
      }

      buffer_formats[0] = gfx::BufferFormat::R_8;
      buffer_formats[1] = gfx::BufferFormat::RG_88;
      return VideoFrameResourceType::YUV;

    case PIXEL_FORMAT_P016LE:
      if (num_textures == 1) {
        // Single-texture multi-planar frames can be sampled as RGB.
        buffer_formats[0] = gfx::BufferFormat::P010;
        return VideoFrameResourceType::RGB;
      }
      // TODO(mcasas): Support other formats such as e.g. P012.
      buffer_formats[0] = gfx::BufferFormat::R_16;
      buffer_formats[1] = gfx::BufferFormat::RG_88;
      return VideoFrameResourceType::YUV;

    case PIXEL_FORMAT_RGBAF16:
      DCHECK_EQ(num_textures, 1);
      buffer_formats[0] = gfx::BufferFormat::RGBA_F16;
      return VideoFrameResourceType::RGBA;

    case PIXEL_FORMAT_UYVY:
      NOTREACHED();
      FALLTHROUGH;
    case PIXEL_FORMAT_YV12:
    case PIXEL_FORMAT_I422:
    case PIXEL_FORMAT_I444:
    case PIXEL_FORMAT_I420A:
    case PIXEL_FORMAT_NV21:
    case PIXEL_FORMAT_YUY2:
    case PIXEL_FORMAT_RGB24:
    case PIXEL_FORMAT_MJPEG:
    case PIXEL_FORMAT_YUV420P9:
    case PIXEL_FORMAT_YUV422P9:
    case PIXEL_FORMAT_YUV444P9:
    case PIXEL_FORMAT_YUV420P10:
    case PIXEL_FORMAT_YUV422P10:
    case PIXEL_FORMAT_YUV444P10:
    case PIXEL_FORMAT_YUV420P12:
    case PIXEL_FORMAT_YUV422P12:
    case PIXEL_FORMAT_YUV444P12:
    case PIXEL_FORMAT_Y16:
    case PIXEL_FORMAT_UNKNOWN:
      break;
  }
  return VideoFrameResourceType::NONE;
}

class SyncTokenClientImpl : public VideoFrame::SyncTokenClient {
 public:
  SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl,
                      gpu::SharedImageInterface* sii,
                      gpu::SyncToken sync_token)
      : gl_(gl), sii_(sii), sync_token_(sync_token) {
    // Only one interface should be used.
    DCHECK((gl_ && !sii_) || (!gl_ && sii_));
  }

  SyncTokenClientImpl(const SyncTokenClientImpl&) = delete;
  SyncTokenClientImpl& operator=(const SyncTokenClientImpl&) = delete;

  ~SyncTokenClientImpl() override = default;

  void GenerateSyncToken(gpu::SyncToken* sync_token) override {
    if (sync_token_.HasData()) {
      *sync_token = sync_token_;
    } else {
      if (gl_) {
        gl_->GenSyncTokenCHROMIUM(sync_token->GetData());
      } else {
        *sync_token = sii_->GenVerifiedSyncToken();
      }
    }
  }

  void WaitSyncToken(const gpu::SyncToken& sync_token) override {
    if (sync_token.HasData()) {
      if (gl_) {
        gl_->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
      } else {
        sii_->WaitSyncToken(sync_token);
      }
      if (sync_token_.HasData() && sync_token_ != sync_token) {
        if (gl_) {
          gl_->WaitSyncTokenCHROMIUM(sync_token_.GetConstData());
        } else {
          sii_->WaitSyncToken(sync_token);
        }
        sync_token_.Clear();
      }
    }
  }

 private:
  gpu::gles2::GLES2Interface* gl_;
  gpu::SharedImageInterface* sii_;
  gpu::SyncToken sync_token_;
};

// Sync tokens passed downstream to the compositor can be unverified.
void GenerateCompositorSyncToken(gpu::gles2::GLES2Interface* gl,
                                 gpu::SyncToken* sync_token) {
  gl->GenUnverifiedSyncTokenCHROMIUM(sync_token->GetData());
}

// For frames that we receive in software format, determine the dimensions of
// each plane in the frame.
gfx::Size SoftwarePlaneDimension(VideoFrame* input_frame,
                                 bool software_compositor,
                                 size_t plane_index) {
  if (software_compositor)
    return input_frame->coded_size();

  int plane_width = input_frame->columns(plane_index);
  int plane_height = input_frame->rows(plane_index);
  return gfx::Size(plane_width, plane_height);
}

}  // namespace

VideoFrameExternalResources::VideoFrameExternalResources() = default;
VideoFrameExternalResources::~VideoFrameExternalResources() = default;

VideoFrameExternalResources::VideoFrameExternalResources(
    VideoFrameExternalResources&& other) = default;
VideoFrameExternalResources& VideoFrameExternalResources::operator=(
    VideoFrameExternalResources&& other) = default;

// Resource for a video plane allocated and owned by VideoResourceUpdater. There
// can be multiple plane resources for each video frame, depending on the
// format. These will be reused when possible.
class VideoResourceUpdater::PlaneResource {
 public:
  PlaneResource(uint32_t plane_resource_id,
                const gfx::Size& resource_size,
                viz::ResourceFormat resource_format,
                bool is_software)
      : plane_resource_id_(plane_resource_id),
        resource_size_(resource_size),
        resource_format_(resource_format),
        is_software_(is_software) {}

  PlaneResource(const PlaneResource&) = delete;
  PlaneResource& operator=(const PlaneResource&) = delete;

  virtual ~PlaneResource() = default;

  // Casts |this| to SoftwarePlaneResource for software compositing.
  SoftwarePlaneResource* AsSoftware();

  // Casts |this| to HardwarePlaneResource for GPU compositing.
  HardwarePlaneResource* AsHardware();

  // Returns true if this resource matches the unique identifiers of another
  // VideoFrame resource.
  bool Matches(int unique_frame_id, size_t plane_index) {
    return has_unique_frame_id_and_plane_index_ &&
           unique_frame_id_ == unique_frame_id && plane_index_ == plane_index;
  }

  // Sets the unique identifiers for this resource, may only be called when
  // there is a single reference to the resource (i.e. |ref_count_| == 1).
  void SetUniqueId(int unique_frame_id, size_t plane_index) {
    DCHECK_EQ(ref_count_, 1);
    plane_index_ = plane_index;
    unique_frame_id_ = unique_frame_id;
    has_unique_frame_id_and_plane_index_ = true;
  }

  // Accessors for resource identifiers provided at construction time.
  uint32_t plane_resource_id() const { return plane_resource_id_; }
  const gfx::Size& resource_size() const { return resource_size_; }
  viz::ResourceFormat resource_format() const { return resource_format_; }

  // Various methods for managing references. See |ref_count_| for details.
  void add_ref() { ++ref_count_; }
  void remove_ref() { --ref_count_; }
  void clear_refs() { ref_count_ = 0; }
  bool has_refs() const { return ref_count_ != 0; }

 private:
  const uint32_t plane_resource_id_;
  const gfx::Size resource_size_;
  const viz::ResourceFormat resource_format_;
  const bool is_software_;

  // The number of times this resource has been imported vs number of times this
  // resource has returned.
  int ref_count_ = 0;

  // These two members are used for identifying the data stored in this
  // resource; they uniquely identify a VideoFrame plane.
  int unique_frame_id_ = 0;
  size_t plane_index_ = 0u;
  // Indicates if the above two members have been set or not.
  bool has_unique_frame_id_and_plane_index_ = false;
};

class VideoResourceUpdater::SoftwarePlaneResource
    : public VideoResourceUpdater::PlaneResource {
 public:
  SoftwarePlaneResource(uint32_t plane_resource_id,
                        const gfx::Size& size,
                        viz::SharedBitmapReporter* shared_bitmap_reporter)
      : PlaneResource(plane_resource_id,
                      size,
                      viz::ResourceFormat::RGBA_8888,
                      /*is_software=*/true),
        shared_bitmap_reporter_(shared_bitmap_reporter),
        shared_bitmap_id_(viz::SharedBitmap::GenerateId()) {
    DCHECK(shared_bitmap_reporter_);

    // Allocate SharedMemory and notify display compositor of the allocation.
    base::MappedReadOnlyRegion shm =
        viz::bitmap_allocation::AllocateSharedBitmap(
            resource_size(), viz::ResourceFormat::RGBA_8888);
    shared_mapping_ = std::move(shm.mapping);
    shared_bitmap_reporter_->DidAllocateSharedBitmap(std::move(shm.region),
                                                     shared_bitmap_id_);
  }

  SoftwarePlaneResource(const SoftwarePlaneResource&) = delete;
  SoftwarePlaneResource& operator=(const SoftwarePlaneResource&) = delete;

  ~SoftwarePlaneResource() override {
    shared_bitmap_reporter_->DidDeleteSharedBitmap(shared_bitmap_id_);
  }

  const viz::SharedBitmapId& shared_bitmap_id() const {
    return shared_bitmap_id_;
  }
  void* pixels() { return shared_mapping_.memory(); }

  // Returns a memory dump GUID consistent across processes.
  base::UnguessableToken GetSharedMemoryGuid() const {
    return shared_mapping_.guid();
  }

 private:
  viz::SharedBitmapReporter* const shared_bitmap_reporter_;
  const viz::SharedBitmapId shared_bitmap_id_;
  base::WritableSharedMemoryMapping shared_mapping_;
};

class VideoResourceUpdater::HardwarePlaneResource
    : public VideoResourceUpdater::PlaneResource {
 public:
  // Provides a RAII scope to access the HardwarePlaneResource as a texture on a
  // GL context. This will wait on the sync token and provide the shared image
  // access scope.
  class ScopedTexture {
   public:
    ScopedTexture(gpu::gles2::GLES2Interface* gl,
                  HardwarePlaneResource* resource)
        : gl_(gl) {
      texture_id_ = gl_->CreateAndTexStorage2DSharedImageCHROMIUM(
          resource->mailbox().name);
      gl_->BeginSharedImageAccessDirectCHROMIUM(
          texture_id_, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
    }

    ~ScopedTexture() {
      gl_->EndSharedImageAccessDirectCHROMIUM(texture_id_);
      gl_->DeleteTextures(1, &texture_id_);
    }

    GLuint texture_id() const { return texture_id_; }

   private:
    gpu::gles2::GLES2Interface* gl_;
    GLuint texture_id_;
  };

  HardwarePlaneResource(uint32_t plane_resource_id,
                        const gfx::Size& size,
                        viz::ResourceFormat format,
                        const gfx::ColorSpace& color_space,
                        bool use_gpu_memory_buffer_resources,
                        viz::ContextProvider* context_provider,
                        viz::RasterContextProvider* raster_context_provider)
      : PlaneResource(plane_resource_id, size, format, /*is_software=*/false),
        context_provider_(context_provider),
        raster_context_provider_(raster_context_provider) {
    DCHECK(context_provider_ || raster_context_provider_);
    const gpu::Capabilities& caps =
        raster_context_provider_
            ? raster_context_provider_->ContextCapabilities()
            : context_provider_->ContextCapabilities();
    overlay_candidate_ = use_gpu_memory_buffer_resources &&
                         caps.texture_storage_image &&
                         IsGpuMemoryBufferFormatSupported(format);
    uint32_t shared_image_usage =
        gpu::SHARED_IMAGE_USAGE_GLES2 | gpu::SHARED_IMAGE_USAGE_DISPLAY;
    if (overlay_candidate_) {
      shared_image_usage |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
      texture_target_ = gpu::GetBufferTextureTarget(gfx::BufferUsage::SCANOUT,
                                                    BufferFormat(format), caps);
    }
    auto* sii = SharedImageInterface();
    mailbox_ = sii->CreateSharedImage(
        format, size, color_space, kTopLeft_GrSurfaceOrigin,
        kPremul_SkAlphaType, shared_image_usage, gpu::kNullSurfaceHandle);
    ContextGL()->WaitSyncTokenCHROMIUM(
        sii->GenUnverifiedSyncToken().GetConstData());
  }

  ~HardwarePlaneResource() override {
    gpu::SyncToken sync_token;
    ContextGL()->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
    SharedImageInterface()->DestroySharedImage(sync_token, mailbox_);
  }

  const gpu::Mailbox& mailbox() const { return mailbox_; }

  GLenum texture_target() const { return texture_target_; }
  bool overlay_candidate() const { return overlay_candidate_; }

 private:
  gpu::SharedImageInterface* SharedImageInterface() {
    auto* sii = raster_context_provider_
                    ? raster_context_provider_->SharedImageInterface()
                    : context_provider_->SharedImageInterface();
    DCHECK(sii);
    return sii;
  }

  gpu::gles2::GLES2Interface* ContextGL() {
    auto* gl = raster_context_provider_ ? raster_context_provider_->ContextGL()
                                        : context_provider_->ContextGL();
    DCHECK(gl);
    return gl;
  }

  viz::ContextProvider* const context_provider_;
  viz::RasterContextProvider* const raster_context_provider_;
  gpu::Mailbox mailbox_;
  GLenum texture_target_ = GL_TEXTURE_2D;
  bool overlay_candidate_ = false;

  DISALLOW_COPY_AND_ASSIGN(HardwarePlaneResource);
};

VideoResourceUpdater::SoftwarePlaneResource*
VideoResourceUpdater::PlaneResource::AsSoftware() {
  DCHECK(is_software_);
  return static_cast<SoftwarePlaneResource*>(this);
}

VideoResourceUpdater::HardwarePlaneResource*
VideoResourceUpdater::PlaneResource::AsHardware() {
  DCHECK(!is_software_);
  return static_cast<HardwarePlaneResource*>(this);
}

VideoResourceUpdater::VideoResourceUpdater(
    viz::ContextProvider* context_provider,
    viz::RasterContextProvider* raster_context_provider,
    viz::SharedBitmapReporter* shared_bitmap_reporter,
    viz::ClientResourceProvider* resource_provider,
    bool use_stream_video_draw_quad,
    bool use_gpu_memory_buffer_resources,
    bool use_r16_texture,
    int max_resource_size)
    : context_provider_(context_provider),
      raster_context_provider_(raster_context_provider),
      shared_bitmap_reporter_(shared_bitmap_reporter),
      resource_provider_(resource_provider),
      use_stream_video_draw_quad_(use_stream_video_draw_quad),
      use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
      use_r16_texture_(use_r16_texture),
      max_resource_size_(max_resource_size),
      tracing_id_(g_next_video_resource_updater_id.GetNext()) {
  DCHECK(context_provider_ || raster_context_provider_ ||
         shared_bitmap_reporter_);

  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
      this, "media::VideoResourceUpdater", base::ThreadTaskRunnerHandle::Get());
}

VideoResourceUpdater::~VideoResourceUpdater() {
  base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
      this);
}

void VideoResourceUpdater::ObtainFrameResources(
    scoped_refptr<VideoFrame> video_frame) {
  if (video_frame->metadata().overlay_plane_id.has_value()) {
    // This is a hole punching VideoFrame, there is nothing to display.
    overlay_plane_id_ = *video_frame->metadata().overlay_plane_id;
    frame_resource_type_ = VideoFrameResourceType::VIDEO_HOLE;
    return;
  }

  VideoFrameExternalResources external_resources =
      CreateExternalResourcesFromVideoFrame(video_frame);
  frame_resource_type_ = external_resources.type;

  if (external_resources.type == VideoFrameResourceType::YUV) {
    frame_resource_offset_ = external_resources.offset;
    frame_resource_multiplier_ = external_resources.multiplier;
    frame_bits_per_channel_ = external_resources.bits_per_channel;
  }

  DCHECK_EQ(external_resources.resources.size(),
            external_resources.release_callbacks.size());
  for (size_t i = 0; i < external_resources.resources.size(); ++i) {
    viz::ResourceId resource_id = resource_provider_->ImportResource(
        external_resources.resources[i],
        std::move(external_resources.release_callbacks[i]));
    frame_resources_.emplace_back(resource_id,
                                  external_resources.resources[i].size);
  }
  TRACE_EVENT_INSTANT1("media", "VideoResourceUpdater::ObtainFrameResources",
                       TRACE_EVENT_SCOPE_THREAD, "Timestamp",
                       video_frame->timestamp().InMicroseconds());
}

void VideoResourceUpdater::ReleaseFrameResources() {
  for (auto& frame_resource : frame_resources_)
    resource_provider_->RemoveImportedResource(frame_resource.id);
  frame_resources_.clear();
}

void VideoResourceUpdater::AppendQuads(
    viz::CompositorRenderPass* render_pass,
    scoped_refptr<VideoFrame> frame,
    gfx::Transform transform,
    gfx::Rect quad_rect,
    gfx::Rect visible_quad_rect,
    const gfx::MaskFilterInfo& mask_filter_info,
    absl::optional<gfx::Rect> clip_rect,
    bool contents_opaque,
    float draw_opacity,
    int sorting_context_id) {
  DCHECK(frame.get());

  viz::SharedQuadState* shared_quad_state =
      render_pass->CreateAndAppendSharedQuadState();
  shared_quad_state->SetAll(
      transform, quad_rect, visible_quad_rect, mask_filter_info, clip_rect,
      contents_opaque, draw_opacity, SkBlendMode::kSrcOver, sorting_context_id);

  bool needs_blending = !contents_opaque;

  gfx::Rect visible_rect = frame->visible_rect();
  gfx::Size coded_size = frame->coded_size();

  const gfx::PointF uv_top_left(
      static_cast<float>(visible_rect.x()) / coded_size.width(),
      static_cast<float>(visible_rect.y()) / coded_size.height());

  const gfx::PointF uv_bottom_right(
      static_cast<float>(visible_rect.right()) / coded_size.width(),
      static_cast<float>(visible_rect.bottom()) / coded_size.height());

  switch (frame_resource_type_) {
    case VideoFrameResourceType::VIDEO_HOLE: {
      auto* video_hole_quad =
          render_pass->CreateAndAppendDrawQuad<viz::VideoHoleDrawQuad>();
      video_hole_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
                              overlay_plane_id_);
      break;
    }
    case VideoFrameResourceType::YUV: {
      const gfx::Size ya_tex_size = coded_size;

      int u_width = frame->columns(VideoFrame::kUPlane);
      int u_height = frame->rows(VideoFrame::kUPlane);
      gfx::Size uv_tex_size(u_width, u_height);

      DCHECK_EQ(frame_resources_.size(),
                VideoFrame::NumPlanes(frame->format()));
      if (frame->HasTextures()) {
        DCHECK(frame->format() == PIXEL_FORMAT_NV12 ||
               frame->format() == PIXEL_FORMAT_P016LE ||
               frame->format() == PIXEL_FORMAT_I420);
      }

      // Compute the UV sub-sampling factor based on the ratio between
      // |ya_tex_size| and |uv_tex_size|.
      float uv_subsampling_factor_x =
          static_cast<float>(ya_tex_size.width()) / uv_tex_size.width();
      float uv_subsampling_factor_y =
          static_cast<float>(ya_tex_size.height()) / uv_tex_size.height();
      gfx::RectF ya_tex_coord_rect(visible_rect);
      gfx::RectF uv_tex_coord_rect(
          visible_rect.x() / uv_subsampling_factor_x,
          visible_rect.y() / uv_subsampling_factor_y,
          visible_rect.width() / uv_subsampling_factor_x,
          visible_rect.height() / uv_subsampling_factor_y);

      auto* yuv_video_quad =
          render_pass->CreateAndAppendDrawQuad<viz::YUVVideoDrawQuad>();
      yuv_video_quad->SetNew(
          shared_quad_state, quad_rect, visible_quad_rect, needs_blending,
          ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size,
          frame_resources_[0].id, frame_resources_[1].id,
          frame_resources_.size() > 2 ? frame_resources_[2].id
                                      : frame_resources_[1].id,
          frame_resources_.size() > 3 ? frame_resources_[3].id
                                      : viz::kInvalidResourceId,
          frame->ColorSpace(), frame_resource_offset_,
          frame_resource_multiplier_, frame_bits_per_channel_);
      if (frame->hdr_metadata().has_value())
        yuv_video_quad->hdr_metadata = frame->hdr_metadata().value();
      if (frame->metadata().protected_video) {
        if (frame->metadata().hw_protected) {
          yuv_video_quad->protected_video_type =
              gfx::ProtectedVideoType::kHardwareProtected;
        } else {
          yuv_video_quad->protected_video_type =
              gfx::ProtectedVideoType::kSoftwareProtected;
        }
      }

      for (viz::ResourceId resource_id : yuv_video_quad->resources) {
        resource_provider_->ValidateResource(resource_id);
      }
      break;
    }
    case VideoFrameResourceType::RGBA:
    case VideoFrameResourceType::RGBA_PREMULTIPLIED:
    case VideoFrameResourceType::RGB: {
      DCHECK_EQ(frame_resources_.size(), 1u);
      if (frame_resources_.size() < 1u)
        break;
      bool premultiplied_alpha =
          frame_resource_type_ == VideoFrameResourceType::RGBA_PREMULTIPLIED;

      float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
      bool flipped = !frame->metadata().texture_origin_is_top_left;
      bool nearest_neighbor = false;
      gfx::ProtectedVideoType protected_video_type =
          gfx::ProtectedVideoType::kClear;
      if (frame->metadata().protected_video) {
        if (frame->metadata().hw_protected)
          protected_video_type = gfx::ProtectedVideoType::kHardwareProtected;
        else
          protected_video_type = gfx::ProtectedVideoType::kSoftwareProtected;
      }

      auto* texture_quad =
          render_pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
      texture_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
                           needs_blending, frame_resources_[0].id,
                           premultiplied_alpha, uv_top_left, uv_bottom_right,
                           SK_ColorTRANSPARENT, opacity, flipped,
                           nearest_neighbor, false, protected_video_type);
      texture_quad->set_resource_size_in_pixels(coded_size);
      texture_quad->is_video_frame = true;
      texture_quad->hw_protected_validation_id =
          frame->metadata().hw_protected_validation_id;
      for (viz::ResourceId resource_id : texture_quad->resources) {
        resource_provider_->ValidateResource(resource_id);
      }

      break;
    }
    case VideoFrameResourceType::STREAM_TEXTURE: {
      DCHECK_EQ(frame_resources_.size(), 1u);
      if (frame_resources_.size() < 1u)
        break;
      auto* stream_video_quad =
          render_pass->CreateAndAppendDrawQuad<viz::StreamVideoDrawQuad>();
      stream_video_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
                                needs_blending, frame_resources_[0].id,
                                frame_resources_[0].size_in_pixels, uv_top_left,
                                uv_bottom_right);
      for (viz::ResourceId resource_id : stream_video_quad->resources) {
        resource_provider_->ValidateResource(resource_id);
      }
      break;
    }
    case VideoFrameResourceType::NONE:
      NOTIMPLEMENTED();
      break;
  }
}

VideoFrameExternalResources
VideoResourceUpdater::CreateExternalResourcesFromVideoFrame(
    scoped_refptr<VideoFrame> video_frame) {
  if (video_frame->format() == PIXEL_FORMAT_UNKNOWN)
    return VideoFrameExternalResources();
  DCHECK(video_frame->HasTextures() || video_frame->IsMappable());
  if (video_frame->HasTextures())
    return CreateForHardwarePlanes(std::move(video_frame));
  else
    return CreateForSoftwarePlanes(std::move(video_frame));
}

viz::ResourceFormat VideoResourceUpdater::YuvResourceFormat(
    int bits_per_channel) {
  DCHECK(raster_context_provider_ || context_provider_);
  const auto& caps = raster_context_provider_
                         ? raster_context_provider_->ContextCapabilities()
                         : context_provider_->ContextCapabilities();
  if (caps.disable_one_component_textures)
    return viz::RGBA_8888;
  if (bits_per_channel <= 8)
    return caps.texture_rg ? viz::RED_8 : viz::LUMINANCE_8;
  if (use_r16_texture_ && caps.texture_norm16)
    return viz::R16_EXT;
  if (caps.texture_half_float_linear)
    return viz::LUMINANCE_F16;
  return viz::LUMINANCE_8;
}

VideoResourceUpdater::PlaneResource*
VideoResourceUpdater::RecycleOrAllocateResource(
    const gfx::Size& resource_size,
    viz::ResourceFormat resource_format,
    const gfx::ColorSpace& color_space,
    int unique_id,
    int plane_index) {
  PlaneResource* recyclable_resource = nullptr;
  for (auto& resource : all_resources_) {
    // If the plane index is valid (positive, or 0, meaning all planes)
    // then we are allowed to return a referenced resource that already
    // contains the right frame data. It's safe to reuse it even if
    // resource_provider_ holds some references to it, because those
    // references are read-only.
    if (plane_index != -1 && resource->Matches(unique_id, plane_index)) {
      DCHECK(resource->resource_size() == resource_size);
      DCHECK(resource->resource_format() == resource_format);
      return resource.get();
    }

    // Otherwise check whether this is an unreferenced resource of the right
    // format that we can recycle. Remember it, but don't return immediately,
    // because we still want to find any reusable resources.
    const bool in_use = resource->has_refs();

    if (!in_use && resource->resource_size() == resource_size &&
        resource->resource_format() == resource_format) {
      recyclable_resource = resource.get();
    }
  }

  if (recyclable_resource)
    return recyclable_resource;

  // There was nothing available to reuse or recycle. Allocate a new resource.
  return AllocateResource(resource_size, resource_format, color_space);
}

VideoResourceUpdater::PlaneResource* VideoResourceUpdater::AllocateResource(
    const gfx::Size& plane_size,
    viz::ResourceFormat format,
    const gfx::ColorSpace& color_space) {
  const uint32_t plane_resource_id = next_plane_resource_id_++;

  if (software_compositor()) {
    DCHECK_EQ(format, viz::ResourceFormat::RGBA_8888);

    all_resources_.push_back(std::make_unique<SoftwarePlaneResource>(
        plane_resource_id, plane_size, shared_bitmap_reporter_));
  } else {
    all_resources_.push_back(std::make_unique<HardwarePlaneResource>(
        plane_resource_id, plane_size, format, color_space,
        use_gpu_memory_buffer_resources_, context_provider_,
        raster_context_provider_));
  }
  return all_resources_.back().get();
}

void VideoResourceUpdater::CopyHardwarePlane(
    VideoFrame* video_frame,
    const gfx::ColorSpace& resource_color_space,
    const gpu::MailboxHolder& mailbox_holder,
    VideoFrameExternalResources* external_resources) {
  const gfx::Size output_plane_resource_size = video_frame->coded_size();
  // The copy needs to be a direct transfer of pixel data, so we use an RGBA8
  // target to avoid loss of precision or dropping any alpha component.
  constexpr viz::ResourceFormat copy_resource_format =
      viz::ResourceFormat::RGBA_8888;

  const int no_unique_id = 0;
  const int no_plane_index = -1;  // Do not recycle referenced textures.
  PlaneResource* plane_resource = RecycleOrAllocateResource(
      output_plane_resource_size, copy_resource_format, resource_color_space,
      no_unique_id, no_plane_index);
  HardwarePlaneResource* hardware_resource = plane_resource->AsHardware();
  hardware_resource->add_ref();

  DCHECK_EQ(hardware_resource->texture_target(),
            static_cast<GLenum>(GL_TEXTURE_2D));

  auto* gl = ContextGL();
  gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());

  // This is only used on Android where all video mailboxes already use shared
  // images.
  DCHECK(mailbox_holder.mailbox.IsSharedImage());

  // TODO(vikassoni): Use raster interface instead of gl interface eventually.
  GLuint src_texture_id =
      gl->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox_holder.mailbox.name);
  gl->BeginSharedImageAccessDirectCHROMIUM(
      src_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM);
  {
    HardwarePlaneResource::ScopedTexture scope(gl, hardware_resource);
    gl->CopySubTextureCHROMIUM(
        src_texture_id, 0, GL_TEXTURE_2D, scope.texture_id(), 0, 0, 0, 0, 0,
        output_plane_resource_size.width(), output_plane_resource_size.height(),
        false, false, false);
  }
  gl->EndSharedImageAccessDirectCHROMIUM(src_texture_id);
  gl->DeleteTextures(1, &src_texture_id);

  // Pass an empty sync token to force generation of a new sync token.
  SyncTokenClientImpl client(gl, nullptr /* gpu::SharedImageInterface* */,
                             gpu::SyncToken());
  gpu::SyncToken sync_token = video_frame->UpdateReleaseSyncToken(&client);

  auto transferable_resource = viz::TransferableResource::MakeGL(
      hardware_resource->mailbox(), GL_LINEAR, GL_TEXTURE_2D, sync_token,
      output_plane_resource_size, false /* is_overlay_candidate */);
  transferable_resource.color_space = resource_color_space;
  transferable_resource.format = copy_resource_format;
  external_resources->resources.push_back(std::move(transferable_resource));

  external_resources->release_callbacks.push_back(base::BindOnce(
      &VideoResourceUpdater::RecycleResource, weak_ptr_factory_.GetWeakPtr(),
      hardware_resource->plane_resource_id()));
}

VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
    scoped_refptr<VideoFrame> video_frame) {
  TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForHardwarePlanes");
  DCHECK(video_frame->HasTextures());
  if (!context_provider_ && !raster_context_provider_)
    return VideoFrameExternalResources();

  VideoFrameExternalResources external_resources;
  gfx::ColorSpace resource_color_space = video_frame->ColorSpace();

  const auto& copy_mode = video_frame->metadata().copy_mode;
  GLuint target = video_frame->mailbox_holder(0).texture_target;
  // If texture copy is required, then we will copy into a GL_TEXTURE_2D target.
  if (copy_mode == VideoFrameMetadata::CopyMode::kCopyToNewTexture)
    target = GL_TEXTURE_2D;

  gfx::BufferFormat buffer_formats[VideoFrame::kMaxPlanes];
  external_resources.type = ExternalResourceTypeForHardwarePlanes(
      video_frame->format(), target, video_frame->NumTextures(), buffer_formats,
      use_stream_video_draw_quad_, video_frame->metadata().dcomp_surface);

  if (external_resources.type == VideoFrameResourceType::NONE) {
    DLOG(ERROR) << "Unsupported Texture format"
                << VideoPixelFormatToString(video_frame->format());
    return external_resources;
  }
  if (external_resources.type == VideoFrameResourceType::RGB ||
      external_resources.type == VideoFrameResourceType::RGBA ||
      external_resources.type == VideoFrameResourceType::RGBA_PREMULTIPLIED) {
    resource_color_space = resource_color_space.GetAsFullRangeRGB();
  }

  const size_t num_textures = video_frame->NumTextures();
  for (size_t i = 0; i < num_textures; ++i) {
    const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i);
    if (mailbox_holder.mailbox.IsZero())
      break;
    if (copy_mode == VideoFrameMetadata::CopyMode::kCopyToNewTexture) {
      CopyHardwarePlane(video_frame.get(), resource_color_space, mailbox_holder,
                        &external_resources);
    } else {
      gpu::SyncToken sync_token = mailbox_holder.sync_token;
      gpu::Mailbox mailbox = mailbox_holder.mailbox;
      if (copy_mode == VideoFrameMetadata::CopyMode::kCopyMailboxesOnly) {
        auto* sii = SharedImageInterface();
        uint32_t usage =
            gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_GLES2;
        mailbox = sii->CreateSharedImageWithAHB(mailbox_holder.mailbox, usage,
                                                mailbox_holder.sync_token);
        // Insert a sync token at this point and update video frame release sync
        // token with it.
        SyncTokenClientImpl client(nullptr /* GLES2Interface */, sii,
                                   gpu::SyncToken());
        sync_token = video_frame->UpdateReleaseSyncToken(&client);
      }

      const size_t width = video_frame->columns(i);
      const size_t height = video_frame->rows(i);
      const gfx::Size plane_size(width, height);
      auto transfer_resource = viz::TransferableResource::MakeGL(
          mailbox, GL_LINEAR, mailbox_holder.texture_target, sync_token,
          plane_size, video_frame->metadata().allow_overlay);
      transfer_resource.color_space = resource_color_space;
      transfer_resource.hdr_metadata = video_frame->hdr_metadata();
      transfer_resource.read_lock_fences_enabled =
          video_frame->metadata().read_lock_fences_enabled;
      transfer_resource.format = viz::GetResourceFormat(buffer_formats[i]);
      transfer_resource.ycbcr_info = video_frame->ycbcr_info();

#if defined(OS_ANDROID)
      transfer_resource.is_backed_by_surface_texture =
          video_frame->metadata().texture_owner;
      transfer_resource.wants_promotion_hint =
          video_frame->metadata().wants_promotion_hint;
#endif
      external_resources.resources.push_back(std::move(transfer_resource));
      if (copy_mode == VideoFrameMetadata::CopyMode::kCopyMailboxesOnly) {
        // Adding a ref on |video_frame| to make sure lifetime of |video frame|
        // is same as lifetime of this |mailbox|. Releasing |video_frame| before
        // |mailbox| causes renderer to prepare more video frame which in turn
        // causes holding onto multiple AHardwareBuffers by both |mailbox| and
        // |video_frame| which in turn causes higher gpu memory usage and
        // potential memory crashes.
        external_resources.release_callbacks.push_back(base::BindOnce(
            &VideoResourceUpdater::DestroyMailbox,
            weak_ptr_factory_.GetWeakPtr(), mailbox, video_frame));
      } else {
        external_resources.release_callbacks.push_back(
            base::BindOnce(&VideoResourceUpdater::ReturnTexture,
                           weak_ptr_factory_.GetWeakPtr(), video_frame));
      }
    }
  }
  return external_resources;
}

VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
    scoped_refptr<VideoFrame> video_frame) {
  TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
  const VideoPixelFormat input_frame_format = video_frame->format();

  size_t bits_per_channel = video_frame->BitDepth();

  const bool is_rgb = input_frame_format == PIXEL_FORMAT_XBGR ||
                      input_frame_format == PIXEL_FORMAT_XRGB ||
                      input_frame_format == PIXEL_FORMAT_ABGR ||
                      input_frame_format == PIXEL_FORMAT_ARGB;

  DCHECK(IsYuvPlanar(input_frame_format) ||
         input_frame_format == PIXEL_FORMAT_Y16 || is_rgb);

  viz::ResourceFormat output_resource_format;
  gfx::ColorSpace output_color_space = video_frame->ColorSpace();
  if (input_frame_format == PIXEL_FORMAT_XBGR) {
    output_resource_format = viz::RGBX_8888;
  } else if (input_frame_format == PIXEL_FORMAT_XRGB) {
    output_resource_format = viz::BGRX_8888;
  } else if (input_frame_format == PIXEL_FORMAT_ABGR) {
    output_resource_format = viz::RGBA_8888;
  } else if (input_frame_format == PIXEL_FORMAT_XBGR) {
    output_resource_format = viz::RGBX_8888;
  } else if (input_frame_format == PIXEL_FORMAT_ARGB) {
    output_resource_format = viz::BGRA_8888;
  } else if (input_frame_format == PIXEL_FORMAT_Y16) {
    // Unable to display directly as yuv planes so convert it to RGBA for
    // compositing.
    output_resource_format = viz::RGBA_8888;
    output_color_space = output_color_space.GetAsFullRangeRGB();
  } else if (!software_compositor()) {
    // Can be composited directly from yuv planes.
    output_resource_format = YuvResourceFormat(bits_per_channel);
  }

  // If GPU compositing is enabled, but the output resource format
  // returned by the resource provider is viz::RGBA_8888, then a GPU driver
  // bug workaround requires that YUV frames must be converted to RGB
  // before texture upload.
  const bool texture_needs_rgb_conversion =
      input_frame_format == PIXEL_FORMAT_Y16 ||
      (!software_compositor() && IsYuvPlanar(input_frame_format) &&
       output_resource_format == viz::ResourceFormat::RGBA_8888);

  size_t output_plane_count = VideoFrame::NumPlanes(input_frame_format);

  // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
  // conversion here. That involves an extra copy of each frame to a bitmap.
  // Obviously, this is suboptimal and should be addressed once ubercompositor
  // starts shaping up.
  if (software_compositor() || texture_needs_rgb_conversion) {
    output_resource_format = viz::RGBA_8888;
    output_plane_count = 1;
    bits_per_channel = 8;

    // The YUV to RGB conversion will be performed when we convert
    // from single-channel textures to an RGBA texture via
    // ConvertVideoFrameToRGBPixels below.
    output_color_space = output_color_space.GetAsFullRangeRGB();
  }

  std::vector<gfx::Size> outplane_plane_sizes;
  outplane_plane_sizes.reserve(output_plane_count);
  for (size_t i = 0; i < output_plane_count; ++i) {
    outplane_plane_sizes.push_back(
        SoftwarePlaneDimension(video_frame.get(), software_compositor(), i));
    const gfx::Size& output_plane_resource_size = outplane_plane_sizes.back();
    if (output_plane_resource_size.IsEmpty() ||
        output_plane_resource_size.width() > max_resource_size_ ||
        output_plane_resource_size.height() > max_resource_size_) {
      // This output plane has invalid geometry so return an empty external
      // resources.
      return VideoFrameExternalResources();
    }
  }

  // Delete recycled resources that are the wrong format or wrong size.
  auto can_delete_resource_fn =
      [output_resource_format,
       &outplane_plane_sizes](const std::unique_ptr<PlaneResource>& resource) {
        // Resources that are still being used can't be deleted.
        if (resource->has_refs())
          return false;

        return resource->resource_format() != output_resource_format ||
               !base::Contains(outplane_plane_sizes, resource->resource_size());
      };
  base::EraseIf(all_resources_, can_delete_resource_fn);

  // Recycle or allocate resources for each video plane.
  std::vector<PlaneResource*> plane_resources;
  plane_resources.reserve(output_plane_count);
  for (size_t i = 0; i < output_plane_count; ++i) {
    plane_resources.push_back(RecycleOrAllocateResource(
        outplane_plane_sizes[i], output_resource_format, output_color_space,
        video_frame->unique_id(), i));
    plane_resources.back()->add_ref();
  }

  VideoFrameExternalResources external_resources;

  external_resources.bits_per_channel = bits_per_channel;

  if (software_compositor() || texture_needs_rgb_conversion || is_rgb) {
    DCHECK_EQ(plane_resources.size(), 1u);
    PlaneResource* plane_resource = plane_resources[0];

    if (!plane_resource->Matches(video_frame->unique_id(), 0)) {
      // We need to transfer data from |video_frame| to the plane resource.
      if (software_compositor()) {
        DCHECK_EQ(plane_resource->resource_format(), viz::RGBA_8888);

        if (!video_renderer_)
          video_renderer_ = std::make_unique<PaintCanvasVideoRenderer>();

        SoftwarePlaneResource* software_resource = plane_resource->AsSoftware();

        // We know the format is RGBA_8888 from check above.
        SkImageInfo info = SkImageInfo::MakeN32Premul(
            gfx::SizeToSkISize(software_resource->resource_size()));

        SkBitmap sk_bitmap;
        sk_bitmap.installPixels(info, software_resource->pixels(),
                                info.minRowBytes());
        // This is software path, so |canvas| and |video_frame| are always
        // backed by software.
        cc::SkiaPaintCanvas canvas(sk_bitmap);
        cc::PaintFlags flags;
        flags.setBlendMode(SkBlendMode::kSrc);
        flags.setFilterQuality(cc::PaintFlags::FilterQuality::kLow);

        // Note that PaintCanvasVideoRenderer::Copy would copy to the origin,
        // not |video_frame->visible_rect|, so call Paint instead.
        // https://crbug.com/1090435
        video_renderer_->Paint(video_frame, &canvas,
                               gfx::RectF(video_frame->visible_rect()), flags,
                               media::kNoTransformation, nullptr);
      } else {
        HardwarePlaneResource* hardware_resource = plane_resource->AsHardware();
        size_t bytes_per_row = viz::ResourceSizes::CheckedWidthInBytes<size_t>(
            video_frame->coded_size().width(), output_resource_format);
        size_t needed_size = bytes_per_row * video_frame->coded_size().height();
        if (upload_pixels_size_ < needed_size) {
          // Free the existing data first so that the memory can be reused,
          // if possible. Note that the new array is purposely not initialized.
          upload_pixels_.reset();
          upload_pixels_.reset(new uint8_t[needed_size]);
          upload_pixels_size_ = needed_size;
        }

        PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
            video_frame.get(), upload_pixels_.get(), bytes_per_row);

        // Copy pixels into texture.
        auto* gl = ContextGL();
        const gfx::Size& plane_size = hardware_resource->resource_size();
        {
          HardwarePlaneResource::ScopedTexture scope(gl, hardware_resource);
          gl->BindTexture(hardware_resource->texture_target(),
                          scope.texture_id());
          gl->TexSubImage2D(
              hardware_resource->texture_target(), 0, 0, 0, plane_size.width(),
              plane_size.height(), GLDataFormat(output_resource_format),
              GLDataType(output_resource_format), upload_pixels_.get());
        }
      }
      plane_resource->SetUniqueId(video_frame->unique_id(), 0);
    }

    viz::TransferableResource transferable_resource;
    if (software_compositor()) {
      SoftwarePlaneResource* software_resource = plane_resource->AsSoftware();
      external_resources.type = VideoFrameResourceType::RGBA_PREMULTIPLIED;
      transferable_resource = viz::TransferableResource::MakeSoftware(
          software_resource->shared_bitmap_id(),
          software_resource->resource_size(),
          plane_resource->resource_format());
    } else {
      HardwarePlaneResource* hardware_resource = plane_resource->AsHardware();
      external_resources.type = VideoFrameResourceType::RGBA;
      gpu::SyncToken sync_token;
      auto* gl = ContextGL();
      GenerateCompositorSyncToken(gl, &sync_token);
      transferable_resource = viz::TransferableResource::MakeGL(
          hardware_resource->mailbox(), GL_LINEAR,
          hardware_resource->texture_target(), sync_token,
          hardware_resource->resource_size(),
          hardware_resource->overlay_candidate());
    }

    transferable_resource.color_space = output_color_space;
    transferable_resource.format = output_resource_format;
    external_resources.resources.push_back(std::move(transferable_resource));
    external_resources.release_callbacks.push_back(base::BindOnce(
        &VideoResourceUpdater::RecycleResource, weak_ptr_factory_.GetWeakPtr(),
        plane_resource->plane_resource_id()));

    return external_resources;
  }

  const viz::ResourceFormat yuv_resource_format =
      YuvResourceFormat(bits_per_channel);
  DCHECK(yuv_resource_format == viz::LUMINANCE_F16 ||
         yuv_resource_format == viz::R16_EXT ||
         yuv_resource_format == viz::LUMINANCE_8 ||
         yuv_resource_format == viz::RED_8)
      << yuv_resource_format;

  std::unique_ptr<HalfFloatMaker> half_float_maker;
  if (yuv_resource_format == viz::LUMINANCE_F16) {
    half_float_maker = HalfFloatMaker::NewHalfFloatMaker(bits_per_channel);
    external_resources.offset = half_float_maker->Offset();
    external_resources.multiplier = half_float_maker->Multiplier();
  } else if (yuv_resource_format == viz::R16_EXT) {
    external_resources.multiplier = 65535.0f / ((1 << bits_per_channel) - 1);
    external_resources.offset = 0;
  }

  auto* gl = ContextGL();
  // We need to transfer data from |video_frame| to the plane resources.
  for (size_t i = 0; i < plane_resources.size(); ++i) {
    HardwarePlaneResource* plane_resource = plane_resources[i]->AsHardware();

    // Skip the transfer if this |video_frame|'s plane has been processed.
    if (plane_resource->Matches(video_frame->unique_id(), i))
      continue;

    const viz::ResourceFormat plane_resource_format =
        plane_resource->resource_format();
    DCHECK_EQ(plane_resource_format, yuv_resource_format);

    // TODO(hubbe): Move upload code to media/.
    // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.

    // |video_stride_bytes| is the width of the |video_frame| we are uploading
    // (including non-frame data to fill in the stride).
    const int video_stride_bytes = video_frame->stride(i);

    // |resource_size_pixels| is the size of the destination resource.
    const gfx::Size resource_size_pixels = plane_resource->resource_size();

    const size_t bytes_per_row =
        viz::ResourceSizes::CheckedWidthInBytes<size_t>(
            resource_size_pixels.width(), plane_resource_format);

    // Use 4-byte row alignment (OpenGL default) for upload performance.
    // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
    constexpr size_t kDefaultUnpackAlignment = 4;
    const size_t upload_image_stride = cc::MathUtil::CheckedRoundUp<size_t>(
        bytes_per_row, kDefaultUnpackAlignment);

    const size_t resource_bit_depth =
        static_cast<size_t>(viz::BitsPerPixel(plane_resource_format));

    // Data downshifting is needed if the resource bit depth is not enough.
    const bool needs_bit_downshifting = bits_per_channel > resource_bit_depth;

    // We need to convert the incoming data if we're transferring to half float,
    // if the need a bit downshift or if the strides need to be reconciled.
    const bool needs_conversion =
        plane_resource_format == viz::LUMINANCE_F16 || needs_bit_downshifting;

    constexpr size_t kDefaultUnpackRowLength = 0;
    GLuint unpack_row_length = kDefaultUnpackRowLength;
    GLuint unpack_alignment = kDefaultUnpackAlignment;

    const uint8_t* pixels;

    if (!needs_conversion) {
      // Stride adaptation is needed if source and destination strides are
      // different but they have the same bit depth.
      const bool needs_stride_adaptation =
          (bits_per_channel == resource_bit_depth) &&
          (upload_image_stride != static_cast<size_t>(video_stride_bytes));
      if (needs_stride_adaptation) {
        const int bytes_per_element =
            VideoFrame::BytesPerElement(video_frame->format(), i);
        // Stride is aligned to VideoFrameLayout::kFrameAddressAlignment (32)
        // which should be divisible by pixel size for YUV formats (1, 2 or 4).
        DCHECK_EQ(video_stride_bytes % bytes_per_element, 0);
        // Unpack row length is in pixels not bytes.
        unpack_row_length = video_stride_bytes / bytes_per_element;
        // Use a non-standard alignment only if necessary.
        if (video_stride_bytes % kDefaultUnpackAlignment != 0)
          unpack_alignment = bytes_per_element;
      }
      pixels = video_frame->data(i);
    } else {
      // Avoid malloc for each frame/plane if possible.
      const size_t needed_size =
          upload_image_stride * resource_size_pixels.height();
      if (upload_pixels_size_ < needed_size) {
        // Free the existing data first so that the memory can be reused,
        // if possible. Note that the new array is purposely not initialized.
        upload_pixels_.reset();
        upload_pixels_.reset(new uint8_t[needed_size]);
        upload_pixels_size_ = needed_size;
      }

      if (plane_resource_format == viz::LUMINANCE_F16) {
        for (int row = 0; row < resource_size_pixels.height(); ++row) {
          uint16_t* dst = reinterpret_cast<uint16_t*>(
              &upload_pixels_[upload_image_stride * row]);
          const uint16_t* src = reinterpret_cast<uint16_t*>(
              video_frame->data(i) + (video_stride_bytes * row));
          half_float_maker->MakeHalfFloats(src, bytes_per_row / 2, dst);
        }
      } else if (needs_bit_downshifting) {
        DCHECK(plane_resource_format == viz::LUMINANCE_8 ||
               plane_resource_format == viz::RED_8);
        const int scale = 0x10000 >> (bits_per_channel - 8);
        libyuv::Convert16To8Plane(
            reinterpret_cast<uint16_t*>(video_frame->data(i)),
            video_stride_bytes / 2, upload_pixels_.get(), upload_image_stride,
            scale, bytes_per_row, resource_size_pixels.height());
      } else {
        NOTREACHED();
      }

      pixels = upload_pixels_.get();
    }

    // Copy pixels into texture. TexSubImage2D() is applicable because
    // |yuv_resource_format| is LUMINANCE_F16, R16_EXT, LUMINANCE_8 or RED_8.
    DCHECK(GLSupportsFormat(plane_resource_format));
    {
      HardwarePlaneResource::ScopedTexture scope(gl, plane_resource);

      gl->BindTexture(plane_resource->texture_target(), scope.texture_id());

      gl->PixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length);
      gl->PixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment);
      gl->TexSubImage2D(plane_resource->texture_target(), 0, 0, 0,
                        resource_size_pixels.width(),
                        resource_size_pixels.height(),
                        GLDataFormat(plane_resource_format),
                        GLDataType(plane_resource_format), pixels);
      gl->PixelStorei(GL_UNPACK_ROW_LENGTH, kDefaultUnpackRowLength);
      gl->PixelStorei(GL_UNPACK_ALIGNMENT, kDefaultUnpackAlignment);
    }

    plane_resource->SetUniqueId(video_frame->unique_id(), i);
  }

  // Set the sync token otherwise resource is assumed to be synchronized.
  gpu::SyncToken sync_token;
  GenerateCompositorSyncToken(gl, &sync_token);

  for (size_t i = 0; i < plane_resources.size(); ++i) {
    HardwarePlaneResource* plane_resource = plane_resources[i]->AsHardware();
    auto transferable_resource = viz::TransferableResource::MakeGL(
        plane_resource->mailbox(), GL_LINEAR, plane_resource->texture_target(),
        sync_token, plane_resource->resource_size(),
        plane_resource->overlay_candidate());
    transferable_resource.color_space = output_color_space;
    transferable_resource.format = output_resource_format;
    external_resources.resources.push_back(std::move(transferable_resource));
    external_resources.release_callbacks.push_back(base::BindOnce(
        &VideoResourceUpdater::RecycleResource, weak_ptr_factory_.GetWeakPtr(),
        plane_resource->plane_resource_id()));
  }

  external_resources.type = VideoFrameResourceType::YUV;
  return external_resources;
}

gpu::gles2::GLES2Interface* VideoResourceUpdater::ContextGL() {
  auto* gl = raster_context_provider_ ? raster_context_provider_->ContextGL()
                                      : context_provider_->ContextGL();
  DCHECK(gl);
  return gl;
}

void VideoResourceUpdater::ReturnTexture(scoped_refptr<VideoFrame> video_frame,
                                         const gpu::SyncToken& sync_token,
                                         bool lost_resource) {
  // TODO(dshwang): Forward to the decoder as a lost resource.
  if (lost_resource)
    return;

  // The video frame will insert a wait on the previous release sync token.
  SyncTokenClientImpl client(
      ContextGL(), nullptr /* gpu::SharedImageInterface* */, sync_token);
  video_frame->UpdateReleaseSyncToken(&client);
}

void VideoResourceUpdater::DestroyMailbox(gpu::Mailbox mailbox,
                                          scoped_refptr<VideoFrame> video_frame,
                                          const gpu::SyncToken& sync_token,
                                          bool lost_resource) {
  if (lost_resource)
    return;

  auto* sii = SharedImageInterface();
  sii->DestroySharedImage(sync_token, mailbox);
  SyncTokenClientImpl client(nullptr, sii, sync_token);
  video_frame->UpdateReleaseSyncToken(&client);
}

void VideoResourceUpdater::RecycleResource(uint32_t plane_resource_id,
                                           const gpu::SyncToken& sync_token,
                                           bool lost_resource) {
  auto matches_id_fn =
      [plane_resource_id](const std::unique_ptr<PlaneResource>& resource) {
        return resource->plane_resource_id() == plane_resource_id;
      };
  auto resource_it =
      std::find_if(all_resources_.begin(), all_resources_.end(), matches_id_fn);
  if (resource_it == all_resources_.end())
    return;

  if ((raster_context_provider_ || context_provider_) && sync_token.HasData()) {
    ContextGL()->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
  }

  if (lost_resource) {
    all_resources_.erase(resource_it);
  } else {
    (*resource_it)->remove_ref();
  }
}

bool VideoResourceUpdater::OnMemoryDump(
    const base::trace_event::MemoryDumpArgs& args,
    base::trace_event::ProcessMemoryDump* pmd) {
  for (auto& resource : all_resources_) {
    std::string dump_name =
        base::StringPrintf("cc/video_memory/updater_%d/resource_%d",
                           tracing_id_, resource->plane_resource_id());
    base::trace_event::MemoryAllocatorDump* dump =
        pmd->CreateAllocatorDump(dump_name);

    const uint64_t total_bytes =
        viz::ResourceSizes::UncheckedSizeInBytesAligned<uint64_t>(
            resource->resource_size(), resource->resource_format());
    dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
                    base::trace_event::MemoryAllocatorDump::kUnitsBytes,
                    total_bytes);

    // The importance value assigned to the GUID here must be greater than the
    // importance value assigned elsewhere so that resource ownership is
    // attributed to VideoResourceUpdater.
    constexpr int kImportance = 2;

    // Resources are shared across processes and require a shared GUID to
    // prevent double counting the memory.
    if (software_compositor()) {
      base::UnguessableToken shm_guid =
          resource->AsSoftware()->GetSharedMemoryGuid();
      pmd->CreateSharedMemoryOwnershipEdge(dump->guid(), shm_guid, kImportance);
    } else {
      base::trace_event::MemoryAllocatorDumpGuid guid =
          gpu::GetSharedImageGUIDForTracing(resource->AsHardware()->mailbox());
      pmd->CreateSharedGlobalAllocatorDump(guid);
      pmd->AddOwnershipEdge(dump->guid(), guid, kImportance);
    }
  }

  return true;
}

gpu::SharedImageInterface* VideoResourceUpdater::SharedImageInterface() const {
  auto* sii = raster_context_provider_
                  ? raster_context_provider_->SharedImageInterface()
                  : context_provider_->SharedImageInterface();
  DCHECK(sii);
  return sii;
}

VideoResourceUpdater::FrameResource::FrameResource() = default;

VideoResourceUpdater::FrameResource::FrameResource(viz::ResourceId id,
                                                   const gfx::Size& size)
    : id(id), size_in_pixels(size) {}

}  // namespace media
