// Copyright 2017 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 "cobalt/renderer/rasterizer/lib/external_rasterizer.h"

#include <algorithm>
#include <cmath>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/threading/thread_checker.h"
#include "cobalt/math/clamp.h"
#include "cobalt/render_tree/image.h"
#include "cobalt/renderer/backend/egl/graphics_context.h"
#include "cobalt/renderer/backend/egl/render_target.h"
#include "cobalt/renderer/rasterizer/common/find_node.h"
#include "cobalt/renderer/rasterizer/egl/hardware_rasterizer.h"
#include "cobalt/renderer/rasterizer/lib/exported/graphics.h"
#include "cobalt/renderer/rasterizer/lib/exported/video.h"
#include "cobalt/renderer/rasterizer/skia/hardware_image.h"
#include "cobalt/renderer/rasterizer/skia/hardware_mesh.h"
#include "cobalt/renderer/rasterizer/skia/hardware_rasterizer.h"
#include "starboard/shared/gles/gl_call.h"
#include "third_party/glm/glm/gtc/matrix_transform.hpp"
#include "third_party/glm/glm/gtc/type_ptr.hpp"

#ifdef ANGLE_ENABLE_D3D11
// Normally, ANGLE defines this symbol internally using its gyp files.
//
// This code is temporary, so for now just enforce that we are truly building
// Windows when this code path is taken.
#if !defined(_WIN32) && !defined(_WIN64)
#error Direct mirroring to the system window is only supported for Windows!
#endif
#define ANGLE_PLATFORM_WINDOWS 1

#include <d3d11.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>

#include "third_party/angle/src/libANGLE/Context.h"
#include "third_party/angle/src/libANGLE/Display.h"
#include "third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h"
#include "third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h"
#include "third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h"
#include "third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.h"
#include "third_party/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h"
#include "third_party/angle/src/libANGLE/Surface.h"
#endif

COMPILE_ASSERT(
    cobalt::render_tree::kMono == kCbLibVideoStereoModeMono &&
        cobalt::render_tree::kLeftRight ==
            kCbLibVideoStereoModeStereoLeftRight &&
        cobalt::render_tree::kTopBottom ==
            kCbLibVideoStereoModeStereoTopBottom &&
        cobalt::render_tree::kLeftRightUnadjustedTextureCoords ==
            kCbLibVideoStereoModeStereoLeftRightUnadjustedCoordinates,
    lib_video_and_map_to_mesh_stereo_mode_constants_mismatch);

using cobalt::renderer::rasterizer::lib::ExternalRasterizer;

namespace {

static const float kMaxRenderTargetSize = 15360.0f;

// The minimum amount of change required in the desired texture size to generate
// a new offscreen render target for the quad texture.
static const float kMinTextureSizeEpsilon = 20.0f;

// Matches the signatures of the callback setter functions in exported/video.h
// and exported/graphics.h.
template <typename Ret, typename... Args>
using CallbackSetter = void(void*, Ret (*)(void*, Args...));

template <typename T, T* t, const char* ErrorMessage>
struct CallbackUpdate;

// Defines useful base:: wrappers for callback setter functions.
template <typename Ret, typename... Args, CallbackSetter<Ret, Args...>* Setter,
          const char* ErrorMessage>
struct CallbackUpdate<CallbackSetter<Ret, Args...>, Setter, ErrorMessage> {
  // Equivalent to the callback types defined in exported/video.h and
  // exported/graphics.h but with the context bound.
  using Callback = base::Callback<Ret(Args...)>;

  static Ret DefaultImplementation(Args...) { LOG(WARNING) << ErrorMessage; }

  struct LazyTraits {
    static const bool kRegisterOnExit = true;
    static const bool kAllowedToAccessOnNonjoinableThread = false;

    static Callback* New(void* instance) {
      return new (instance) Callback(base::Bind(DefaultImplementation));
    }
    static void Delete(Callback* instance) {
      return base::DefaultLazyInstanceTraits<Callback>::Delete(instance);
    }
  };

  // This provides a default warning function for the callbacks and allows to
  // set them even before the external rasterizer is created.
  using LazyCallback = base::LazyInstance<Callback, LazyTraits>;
};

// Creates an instance for the above template for a given callback setter
// function, with an error message.
// We must use 'extern' in here as otherwise we get compiler error C2970 when
// using MSVC for compilation.
#define INSTANCE_CALLBACK_UPDATE(instance_name, callback_setter)  \
  extern const char kWarningMessageDidNotSet##instance_name[] =   \
      #callback_setter                                            \
      "was never called to set a callback, yet Cobalt is "        \
      "attempting to call it.";                                   \
  using instance_name =                                           \
      CallbackUpdate<decltype(callback_setter), &callback_setter, \
                     kWarningMessageDidNotSet##instance_name>;

INSTANCE_CALLBACK_UPDATE(UpdateMeshes, CbLibVideoSetOnUpdateMeshes);
INSTANCE_CALLBACK_UPDATE(UpdateRgbTextureId, CbLibVideoSetOnUpdateRgbTextureId);
INSTANCE_CALLBACK_UPDATE(UpdateProjectionTypeAndStereoMode,
                         CbLibVideoSetOnUpdateProjectionTypeAndStereoMode);
INSTANCE_CALLBACK_UPDATE(UpdateAspectRatio, CbLibVideoSetOnUpdateAspectRatio);
INSTANCE_CALLBACK_UPDATE(GraphicsContextCreated,
                         CbLibGraphicsSetContextCreatedCallback);
INSTANCE_CALLBACK_UPDATE(BeginRenderFrame,
                         CbLibGraphicsSetBeginRenderFrameCallback);
INSTANCE_CALLBACK_UPDATE(EndRenderFrame,
                         CbLibGraphicsSetEndRenderFrameCallback);
#undef INSTANCE_CALLBACK_UPDATE

UpdateMeshes::LazyCallback g_update_meshes_callback = LAZY_INSTANCE_INITIALIZER;
UpdateRgbTextureId::LazyCallback g_update_rgb_texture_id_callback =
    LAZY_INSTANCE_INITIALIZER;
UpdateProjectionTypeAndStereoMode::LazyCallback
    g_update_projection_type_and_stereo_mode_callback =
        LAZY_INSTANCE_INITIALIZER;
UpdateAspectRatio::LazyCallback g_update_aspect_ratio_callback =
    LAZY_INSTANCE_INITIALIZER;
GraphicsContextCreated::LazyCallback g_graphics_context_created_callback =
    LAZY_INSTANCE_INITIALIZER;
BeginRenderFrame::LazyCallback g_begin_render_frame_callback =
    LAZY_INSTANCE_INITIALIZER;
EndRenderFrame::LazyCallback g_end_render_frame_callback =
    LAZY_INSTANCE_INITIALIZER;

bool ApproxEqual(const cobalt::math::Size& a, const cobalt::math::Size& b,
                 float epsilon) {
  return std::abs(a.width() - b.width()) < epsilon &&
         std::abs(a.height() - b.height()) < epsilon;
}

cobalt::math::Size CobaltSizeFromCbLibSize(CbLibSize size) {
  return cobalt::math::Size(size.width, size.height);
}

ExternalRasterizer::Impl* g_external_rasterizer_impl = nullptr;

}  // namespace

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace lib {

class ExternalRasterizer::Impl {
 public:
  Impl(backend::GraphicsContext* graphics_context, int skia_atlas_width,
       int skia_atlas_height, int skia_cache_size_in_bytes,
       int scratch_surface_cache_size_in_bytes,
#if defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
       int offscreen_target_cache_size_in_bytes,
#endif
       bool purge_skia_font_caches_on_destruction,
       bool disable_rasterizer_caching);
  ~Impl();

  void Submit(const scoped_refptr<render_tree::Node>& render_tree,
              const scoped_refptr<backend::RenderTarget>& render_target);

  render_tree::ResourceProvider* GetResourceProvider();

  void MakeCurrent() { hardware_rasterizer_.MakeCurrent(); }

  intptr_t GetMainTextureHandle();

  // Sets the target size in pixels to use for the main render target buffer.
  void SetTargetMainTextureSize(const cobalt::math::Size& target_render_size) {
    target_main_render_target_size_ = target_render_size;
  }

 private:
  void RenderOffscreenVideo(render_tree::FilterNode* map_to_mesh_filter_node);

  scoped_refptr<render_tree::MatrixTransformNode> UpdateTextureSizeAndWrapNode(
      const cobalt::math::Size& native_render_target_size,
      const scoped_refptr<render_tree::Node>& render_tree);

  base::ThreadChecker thread_checker_;

  backend::GraphicsContextEGL* graphics_context_;

#if defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
  egl::HardwareRasterizer hardware_rasterizer_;
#else
  skia::HardwareRasterizer hardware_rasterizer_;
#endif
  Rasterizer::Options options_;

  // The main offscreen render target to use when rendering UI or rectangular
  // video.
  scoped_refptr<backend::RenderTarget> main_offscreen_render_target_;
  scoped_ptr<backend::TextureEGL> main_texture_;

  // TODO: do not actually rasterize offscreen video, but just submit it to the
  // host directly.
  scoped_refptr<backend::RenderTarget> video_offscreen_render_target_;
  scoped_ptr<backend::TextureEGL> video_texture_;
  CbLibVideoProjectionType video_projection_type_;
  scoped_refptr<skia::HardwareMesh> left_eye_video_mesh_;
  scoped_refptr<skia::HardwareMesh> right_eye_video_mesh_;
  render_tree::StereoMode video_stereo_mode_;
  GLuint video_texture_rgb_;
  // The 'target'/'ideal' size to use for the main RenderTarget. The actual size
  // of the buffer for the main RenderTarget should aim to be within some small
  // delta of this whenever a new RenderTree is rendered.
  cobalt::math::Size target_main_render_target_size_;
  int video_width_;
  int video_height_;
};

ExternalRasterizer::Impl::Impl(backend::GraphicsContext* graphics_context,
                               int skia_atlas_width, int skia_atlas_height,
                               int skia_cache_size_in_bytes,
                               int scratch_surface_cache_size_in_bytes,
#if defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
                               int offscreen_target_cache_size_in_bytes,
#endif
                               bool purge_skia_font_caches_on_destruction,
                               bool disable_rasterizer_caching)
    : graphics_context_(
          base::polymorphic_downcast<backend::GraphicsContextEGL*>(
              graphics_context)),
      hardware_rasterizer_(graphics_context, skia_atlas_width,
                           skia_atlas_height, skia_cache_size_in_bytes,
                           scratch_surface_cache_size_in_bytes,
#if defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
                           offscreen_target_cache_size_in_bytes,
#endif
                           purge_skia_font_caches_on_destruction
#if defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
                           , disable_rasterizer_caching
#endif
                           ),
      video_projection_type_(kCbLibVideoProjectionTypeNone),
      video_stereo_mode_(render_tree::StereoMode::kMono),
      video_texture_rgb_(0),
      video_width_(-1),
      video_height_(-1),
      target_main_render_target_size_(1, 1) {
  CHECK(!g_external_rasterizer_impl);
  g_external_rasterizer_impl = this;
  options_.flags = Rasterizer::kSubmitFlags_Clear;
  graphics_context_->MakeCurrent();

  main_offscreen_render_target_ =
      graphics_context_->CreateOffscreenRenderTarget(
          target_main_render_target_size_);
  main_texture_.reset(new backend::TextureEGL(
      graphics_context_,
      make_scoped_refptr(base::polymorphic_downcast<backend::RenderTargetEGL*>(
          main_offscreen_render_target_.get()))));

  g_graphics_context_created_callback.Get().Run();
}

ExternalRasterizer::Impl::~Impl() {
  graphics_context_->MakeCurrent();
  g_external_rasterizer_impl = nullptr;
}

void ExternalRasterizer::Impl::Submit(
    const scoped_refptr<render_tree::Node>& render_tree,
    const scoped_refptr<backend::RenderTarget>& render_target) {
  backend::RenderTargetEGL* render_target_egl =
      base::polymorphic_downcast<backend::RenderTargetEGL*>(
          render_target.get());

  // When the provided RenderTarget is not a window RenderTarget, then this
  // implies the rasterized RenderTree should not be shown directly to the user
  // and thus should not be rasterized into a texture and sent through to the
  // client implementing CbLibRenderFrame.
  if (!render_target_egl->IsWindowRenderTarget()) {
    hardware_rasterizer_.Submit(render_tree, render_target, options_);
    return;
  }

  graphics_context_->MakeCurrentWithSurface(render_target_egl);

  // Attempt to find map to mesh filter node, then render video subtree
  // offscreen.
  auto map_to_mesh_search = common::FindNode<render_tree::FilterNode>(
      render_tree, base::Bind(common::HasMapToMesh),
      base::Bind(common::ReplaceWithEmptyCompositionNode));
  if (map_to_mesh_search.found_node != NULL) {
    base::optional<render_tree::MapToMeshFilter> filter =
        map_to_mesh_search.found_node->data().map_to_mesh_filter;

    CbLibVideoProjectionType new_projection_type;
    switch (filter->mesh_type()) {
      case render_tree::kRectangular:
        // Video is rectangular. Mesh is provided externally (by host).
        new_projection_type = kCbLibVideoProjectionTypeRectangular;
        break;
      case render_tree::kCustomMesh:
        new_projection_type = kCbLibVideoProjectionTypeMesh;
        break;
    }

    if (video_projection_type_ != new_projection_type ||
        filter->stereo_mode() != video_stereo_mode_) {
      // Note the above condition will always be true when playback has not
      // started.
      video_projection_type_ = new_projection_type;
      video_stereo_mode_ = filter->stereo_mode();
      g_update_projection_type_and_stereo_mode_callback.Get().Run(
          video_projection_type_,
          static_cast<CbLibVideoStereoMode>(video_stereo_mode_));
    }

    const scoped_refptr<render_tree::Node>& video_render_tree =
        map_to_mesh_search.found_node->data().source;
    math::SizeF resolutionf = video_render_tree->GetBounds().size();
    int width = static_cast<int>(resolutionf.width());
    int height = static_cast<int>(resolutionf.height());

    if (video_width_ != width || video_height_ != height) {
      g_update_aspect_ratio_callback.Get().Run(
          width > 0 && height > 0 ?  // Avoid division by zero.
              resolutionf.width() / resolutionf.height()
                                  : 0.0f);
      video_width_ = width;
      video_height_ = height;
    }

    if (video_projection_type_ == kCbLibVideoProjectionTypeMesh) {
      // Use resolution to lookup custom mesh map.
      math::Size resolution(width, height);
      scoped_refptr<skia::HardwareMesh> left_eye_video_mesh(
          base::polymorphic_downcast<skia::HardwareMesh*>(
              filter->left_eye_mesh(resolution).get()));
      scoped_refptr<skia::HardwareMesh> right_eye_video_mesh(
          base::polymorphic_downcast<skia::HardwareMesh*>(
              filter->right_eye_mesh(resolution).get()));

      DCHECK(left_eye_video_mesh);

      if (left_eye_video_mesh_.get() != left_eye_video_mesh.get() ||
          right_eye_video_mesh_.get() != right_eye_video_mesh.get()) {
        left_eye_video_mesh_ = left_eye_video_mesh;
        right_eye_video_mesh_ = right_eye_video_mesh;

        CbLibVideoMesh left_mesh;
        left_mesh.vertex_count =
            static_cast<int>(left_eye_video_mesh_->GetVertexCount());
        left_mesh.draw_mode = static_cast<CbLibVideoMeshDrawMode>(
            left_eye_video_mesh_->GetDrawMode());
        left_mesh.vertices = left_eye_video_mesh_->GetVertices();

        if (right_eye_video_mesh_) {
          CbLibVideoMesh right_mesh;
          right_mesh.vertex_count =
              static_cast<int>(right_eye_video_mesh_->GetVertexCount());
          right_mesh.draw_mode = static_cast<CbLibVideoMeshDrawMode>(
              right_eye_video_mesh_->GetDrawMode());
          right_mesh.vertices = right_eye_video_mesh_->GetVertices();
          g_update_meshes_callback.Get().Run(left_mesh, right_mesh);
        } else {
          g_update_meshes_callback.Get().Run(left_mesh, left_mesh);
        }
      }
    }

    // Render video to external texture(s) and pass those to the host.
    RenderOffscreenVideo(map_to_mesh_search.found_node);
  } else {
    if (video_projection_type_ != kCbLibVideoProjectionTypeNone) {
      video_projection_type_ = kCbLibVideoProjectionTypeNone;
      g_update_projection_type_and_stereo_mode_callback.Get().Run(
          video_projection_type_, kCbLibVideoStereoModeMono);
      video_width_ = video_height_ = -1;
    }
  }

  const scoped_refptr<render_tree::MatrixTransformNode> scaled_main_node =
      UpdateTextureSizeAndWrapNode(render_target->GetSize(),
                                   map_to_mesh_search.replaced_tree);
  hardware_rasterizer_.Submit(scaled_main_node, main_offscreen_render_target_,
                              options_);

  CbLibRenderContext host_render_context;
  // TODO: Allow clients to specify arbitrary subtrees to render into
  // different textures?
  g_begin_render_frame_callback.Get().Run(&host_render_context);

  // If there is any host-provided surface, mirror it directly into the
  // system window with a blit.  The surface will be streched or shrunk as
  // appropriate so that it fits the system window's backbuffer.
  if (host_render_context.surface_to_mirror != 0) {
#ifdef ANGLE_ENABLE_D3D11
    EGLContext egl_context = eglGetCurrentContext();
    EGLSurface egl_mirror_surface = reinterpret_cast<EGLSurface>(
        host_render_context.surface_to_mirror);
    EGLSurface egl_window_surface = render_target_egl->GetSurface();
    ::gl::Context* angle_context =
        reinterpret_cast<::gl::Context*>(egl_context);
    ::egl::Surface* angle_mirror_surface = reinterpret_cast<::egl::Surface*>(
        egl_mirror_surface);
    ::egl::Surface* angle_window_surface =
        reinterpret_cast<::egl::Surface*>(egl_window_surface);
    ::rx::SurfaceD3D* d3d_mirror_surface =
        ::rx::GetImplAs<rx::SurfaceD3D>(angle_mirror_surface);
    ::rx::SurfaceD3D* d3d_window_surface =
        ::rx::GetImplAs<rx::SurfaceD3D>(angle_window_surface);
    ::rx::Context11* d3d11_context =
        ::rx::GetImplAs<::rx::Context11>(angle_context);
    ::rx::Renderer11* d3d11_renderer = d3d11_context->getRenderer();
    ::rx::SwapChain11* d3d11_mirror_swapchain =
        static_cast<::rx::SwapChain11*>(d3d_mirror_surface->getSwapChain());
    ::rx::SwapChain11* d3d11_window_swapchain =
        static_cast<::rx::SwapChain11*>(d3d_window_surface->getSwapChain());
    float src_width_scale =
        std::min(1.0f, std::max(host_render_context.width_to_mirror, 0.0f));

    d3d11_renderer->getBlitter()->copyTexture(
        d3d11_mirror_swapchain->getRenderTargetShaderResource(),
        gl::Box(0, 0, 0, d3d11_mirror_swapchain->getWidth() * src_width_scale,
                d3d11_mirror_swapchain->getHeight(), 1),
        gl::Extents(d3d11_mirror_swapchain->getWidth(),
                    d3d11_mirror_swapchain->getHeight(), 1),
        d3d11_window_swapchain->getRenderTarget(),
        gl::Box(0, 0, 0, d3d11_window_swapchain->getWidth(),
                d3d11_window_swapchain->getHeight(), 1),
        gl::Extents(d3d11_window_swapchain->getWidth(),
                    d3d11_window_swapchain->getHeight(), 1),
        nullptr, GL_RGBA_INTEGER, GL_LINEAR, false, false, false);
#else
    LOG(FATAL) << "Direct mirroring to the system window is only supported "
               << "under DirectX.";
#endif
  }
  graphics_context_->SwapBuffers(render_target_egl);
  g_end_render_frame_callback.Get().Run();
}

// TODO: Share this logic with the ComponentRenderer.
scoped_refptr<render_tree::MatrixTransformNode>
ExternalRasterizer::Impl::UpdateTextureSizeAndWrapNode(
    const cobalt::math::Size& native_render_target_size,
    const scoped_refptr<render_tree::Node>& render_tree) {
  // Create a new offscreen render target if the exist one's size is far enough
  // off from the target/ideal size.
  if (!main_offscreen_render_target_ ||
      !ApproxEqual(main_offscreen_render_target_->GetSize(),
                   target_main_render_target_size_, kMinTextureSizeEpsilon)) {
    LOG(INFO) << "Creating a new offscreen render target of size "
              << target_main_render_target_size_;
    main_offscreen_render_target_ =
        graphics_context_->CreateOffscreenRenderTarget(
            target_main_render_target_size_);
    // Note: The TextureEGL this pointer references must first be destroyed by
    // calling reset() before a new TextureEGL can be constructed.
    main_texture_.reset();
    main_texture_.reset(new backend::TextureEGL(
        graphics_context_,
        make_scoped_refptr(
            base::polymorphic_downcast<backend::RenderTargetEGL*>(
                main_offscreen_render_target_.get()))));
  }

  DCHECK(native_render_target_size.width());
  DCHECK(native_render_target_size.height());
  // We wrap the RenderTree in a MatrixTransformNode to scale the RenderTree so
  // that its scale relative to our RenderTarget matches its original scale
  // relative to native_render_target_size. This makes the texture cropped to
  // fit our RenderTarget the same amount it would be for the original
  // RenderTarget.
  const float texture_x_scale =
      static_cast<float>(main_offscreen_render_target_->GetSize().width()) /
      native_render_target_size.width();
  const float texture_y_scale =
      static_cast<float>(main_offscreen_render_target_->GetSize().height()) /
      native_render_target_size.height();
  const glm::mat3 scale_mat(glm::scale(
      glm::mat4(1.0f), glm::vec3(texture_x_scale, texture_y_scale, 1)));
  const cobalt::math::Matrix3F root_transform_matrix =
      cobalt::math::Matrix3F::FromArray(glm::value_ptr(scale_mat));
  return scoped_refptr<render_tree::MatrixTransformNode>(
      new render_tree::MatrixTransformNode(render_tree, root_transform_matrix));
}

render_tree::ResourceProvider* ExternalRasterizer::Impl::GetResourceProvider() {
  return hardware_rasterizer_.GetResourceProvider();
}

intptr_t ExternalRasterizer::Impl::GetMainTextureHandle() {
  return main_texture_->GetPlatformHandle();
}

void ExternalRasterizer::Impl::RenderOffscreenVideo(
    render_tree::FilterNode* map_to_mesh_filter_node) {
  DCHECK(map_to_mesh_filter_node);
  if (!map_to_mesh_filter_node) {
    return;
  }

  // Render the mesh-video into a texture to render into 3D space.
  const scoped_refptr<render_tree::Node>& video_render_tree =
      map_to_mesh_filter_node->data().source;
  // Search the video_render_tree for the video frame ImageNode.
  auto image_node =
      common::FindNode<render_tree::ImageNode>(video_render_tree).found_node;

  math::SizeF video_size_float = video_render_tree->GetBounds().size();
  if (image_node.get() && image_node->data().source) {
    video_size_float = image_node->data().source.get()->GetSize();
  }

  // Width and height of the video render target are based on the size of the
  // video clamped to the valid range for creating an offscreen render target.
  const float target_width = math::Clamp(std::floor(video_size_float.width()),
                                         1.0f, kMaxRenderTargetSize);
  const float target_height = math::Clamp(std::floor(video_size_float.height()),
                                          1.0f, kMaxRenderTargetSize);
  const math::Size video_size(target_width, target_height);

  if (!video_offscreen_render_target_ ||
      video_offscreen_render_target_->GetSize() != video_size) {
    video_offscreen_render_target_ =
        graphics_context_->CreateOffscreenRenderTarget(video_size);
    DLOG(INFO) << "Created new video_offscreen_render_target_: "
               << video_offscreen_render_target_->GetSize();

    // Note: The TextureEGL this pointer references must first be destroyed by
    // calling reset() before a new TextureEGL can be constructed.
    video_texture_.reset();
    video_texture_.reset(new backend::TextureEGL(
        graphics_context_,
        make_scoped_refptr(
            base::polymorphic_downcast<backend::RenderTargetEGL*>(
                video_offscreen_render_target_.get()))));
  }

  if (image_node.get()) {
    // Create a new ImageNode around the raw image data which will
    // automatically scale it to the right size.
    backend::RenderTargetEGL* video_offscreen_render_target_egl =
        base::polymorphic_downcast<backend::RenderTargetEGL*>(
            video_offscreen_render_target_.get());

    const scoped_refptr<render_tree::ImageNode> correctly_scaled_image_node(
        new render_tree::ImageNode(image_node->data().source));

    // TODO: Instead of submitting the image for rendering and producing an
    // RGB texture, try to cast to HardwareMultiPlaneImage to use the YUV
    // textures already produced by decode-to-texture.
    hardware_rasterizer_.Submit(correctly_scaled_image_node,
                                video_offscreen_render_target_, options_);

    const intptr_t video_texture_handle = video_texture_->GetPlatformHandle();
    if (video_texture_rgb_ != video_texture_handle) {
      video_texture_rgb_ = video_texture_handle;
      g_update_rgb_texture_id_callback.Get().Run(video_texture_handle);
    }
  }
}

ExternalRasterizer::ExternalRasterizer(
    backend::GraphicsContext* graphics_context, int skia_atlas_width,
    int skia_atlas_height, int skia_cache_size_in_bytes,
    int scratch_surface_cache_size_in_bytes,
#if defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
    int offscreen_target_cache_size_in_bytes,
#endif
    bool purge_skia_font_caches_on_destruction,
    bool disable_rasterizer_caching)
    : impl_(new Impl(graphics_context, skia_atlas_width, skia_atlas_height,
                     skia_cache_size_in_bytes,
                     scratch_surface_cache_size_in_bytes,
#if defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
                     offscreen_target_cache_size_in_bytes,
#endif
                     purge_skia_font_caches_on_destruction,
                     disable_rasterizer_caching)) {}

ExternalRasterizer::~ExternalRasterizer() {}

void ExternalRasterizer::Submit(
    const scoped_refptr<render_tree::Node>& render_tree,
    const scoped_refptr<backend::RenderTarget>& render_target,
    const Options& options) {
  impl_->Submit(render_tree, render_target);
}

render_tree::ResourceProvider* ExternalRasterizer::GetResourceProvider() {
  return impl_->GetResourceProvider();
}

void ExternalRasterizer::MakeCurrent() { return impl_->MakeCurrent(); }

}  // namespace lib
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

void CbLibVideoSetOnUpdateMeshes(void* context,
                                 CbLibVideoUpdateMeshesCallback callback) {
  g_update_meshes_callback.Get() =
      callback ? base::Bind(callback, context)
               : base::Bind(&UpdateMeshes::DefaultImplementation);
}

void CbLibVideoSetOnUpdateRgbTextureId(
    void* context, CbLibVideoUpdateRgbTextureIdCallback callback) {
  g_update_rgb_texture_id_callback.Get() =
      callback ? base::Bind(callback, context)
               : base::Bind(&UpdateRgbTextureId::DefaultImplementation);
}

void CbLibVideoSetOnUpdateProjectionTypeAndStereoMode(
    void* context,
    CbLibVideoUpdateProjectionTypeAndStereoModeCallback callback) {
  g_update_projection_type_and_stereo_mode_callback.Get() =
      callback ? base::Bind(callback, context)
               : base::Bind(
                     &UpdateProjectionTypeAndStereoMode::DefaultImplementation);
}

void CbLibVideoSetOnUpdateAspectRatio(
    void* context, CbLibVideoUpdateAspectRatioCallback callback) {
  g_update_aspect_ratio_callback.Get() =
      callback ? base::Bind(callback, context)
               : base::Bind(&UpdateAspectRatio::DefaultImplementation);
}

void CbLibGraphicsSetContextCreatedCallback(
    void* context, CbLibGraphicsContextCreatedCallback callback) {
  g_graphics_context_created_callback.Get() =
      callback ? base::Bind(callback, context)
               : base::Bind(&GraphicsContextCreated::DefaultImplementation);
}

void CbLibGraphicsSetBeginRenderFrameCallback(
    void* context, CbLibGraphicsBeginRenderFrameCallback callback) {
  g_begin_render_frame_callback.Get() =
      callback ? base::Bind(callback, context)
               : base::Bind(&BeginRenderFrame::DefaultImplementation);
}

void CbLibGraphicsSetEndRenderFrameCallback(
    void* context, CbLibGraphicsEndRenderFrameCallback callback) {
  g_end_render_frame_callback.Get() =
      callback ? base::Bind(callback, context)
               : base::Bind(&EndRenderFrame::DefaultImplementation);
}

intptr_t CbLibGrapicsGetMainTextureHandle() {
  DCHECK(g_external_rasterizer_impl);
  if (!g_external_rasterizer_impl) {
    LOG(WARNING) << __FUNCTION__
                 << "ExternalRasterizer not yet created; unable to progress.";
    return 0;
  }

  return g_external_rasterizer_impl->GetMainTextureHandle();
}

void CbLibGraphicsSetTargetMainTextureSize(
    const CbLibSize& target_render_size) {
  DCHECK(g_external_rasterizer_impl);
  if (!g_external_rasterizer_impl) {
    LOG(WARNING) << __FUNCTION__
                 << "ExternalRasterizer not yet created; unable to progress.";
    return;
  }
  const cobalt::math::Size size = CobaltSizeFromCbLibSize(target_render_size);
  g_external_rasterizer_impl->SetTargetMainTextureSize(size);
}
