// 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;
    if (!filter->left_eye_mesh()) {
      // Video is rectangular. Mesh is provided externally (by host).
      new_projection_type = kCbLibVideoProjectionTypeRectangular;
    } else {
      new_projection_type = kCbLibVideoProjectionTypeMesh;
    }

    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);
}
