// Copyright 2014 The Cobalt Authors. 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 "starboard/configuration.h"
#if SB_API_VERSION >= 12 || SB_HAS(GLES2)

#include "cobalt/renderer/rasterizer/skia/hardware_resource_provider.h"

#include <memory>

#include "base/synchronization/waitable_event.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/renderer/backend/egl/graphics_system.h"
#include "cobalt/renderer/backend/egl/utils.h"
#include "cobalt/renderer/egl_and_gles.h"
#include "cobalt/renderer/rasterizer/skia/cobalt_skia_type_conversions.h"
#include "cobalt/renderer/rasterizer/skia/font.h"
#include "cobalt/renderer/rasterizer/skia/gl_format_conversions.h"
#include "cobalt/renderer/rasterizer/skia/glyph_buffer.h"
#include "cobalt/renderer/rasterizer/skia/hardware_image.h"
#include "cobalt/renderer/rasterizer/skia/hardware_mesh.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontMgr_cobalt.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.h"
#include "cobalt/renderer/rasterizer/skia/skottie_animation.h"
#include "cobalt/renderer/rasterizer/skia/typeface.h"
#include "third_party/ots/include/opentype-sanitiser.h"
#include "third_party/ots/include/ots-memory-stream.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"

using cobalt::render_tree::Image;
using cobalt::render_tree::ImageData;
using cobalt::render_tree::RawImageMemory;

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace skia {

HardwareResourceProvider::HardwareResourceProvider(
    backend::GraphicsContextEGL* cobalt_context, GrContext* gr_context,
    const SubmitOffscreenCallback& submit_offscreen_callback,
    bool purge_skia_font_caches_on_destruction)
    : cobalt_context_(cobalt_context),
      gr_context_(gr_context),
      submit_offscreen_callback_(submit_offscreen_callback),
      purge_skia_font_caches_on_destruction_(
          purge_skia_font_caches_on_destruction),
      max_texture_size_(gr_context->maxTextureSize()),
      self_message_loop_(base::MessageLoop::current()) {
  // Initialize the font manager now to ensure that it doesn't get initialized
  // on multiple threads simultaneously later.
  SkFontMgr::RefDefault();
#if SB_HAS(GRAPHICS)
  decode_target_graphics_context_provider_.egl_display =
      cobalt_context_->system_egl()->GetDisplay();
  decode_target_graphics_context_provider_.egl_context =
      cobalt_context_->GetContext();
  decode_target_graphics_context_provider_.gles_context_runner =
      &HardwareResourceProvider::GraphicsContextRunner;
  decode_target_graphics_context_provider_.gles_context_runner_context = this;
#endif  // SB_HAS(GRAPHICS)
}

HardwareResourceProvider::~HardwareResourceProvider() {
  if (purge_skia_font_caches_on_destruction_) {
    text_shaper_.PurgeCaches();

    sk_sp<SkFontMgr> font_manager(SkFontMgr::RefDefault());
    SkFontMgr_Cobalt* cobalt_font_manager =
        base::polymorphic_downcast<SkFontMgr_Cobalt*>(font_manager.get());
    cobalt_font_manager->PurgeCaches();
  }
}

void HardwareResourceProvider::Finish() {
  // Wait for any resource-related to complete (by waiting for all tasks to
  // complete).
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->WaitForFence();
  }
}

bool HardwareResourceProvider::PixelFormatSupported(
    render_tree::PixelFormat pixel_format) {
  return pixel_format == render_tree::kPixelFormatRGBA8 ||
         pixel_format == render_tree::kPixelFormatUYVY;
}

bool HardwareResourceProvider::AlphaFormatSupported(
    render_tree::AlphaFormat alpha_format) {
  return alpha_format == render_tree::kAlphaFormatPremultiplied ||
         alpha_format == render_tree::kAlphaFormatOpaque;
}

std::unique_ptr<ImageData> HardwareResourceProvider::AllocateImageData(
    const math::Size& size, render_tree::PixelFormat pixel_format,
    render_tree::AlphaFormat alpha_format) {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::AllocateImageData()");
  DCHECK(PixelFormatSupported(pixel_format));
  DCHECK(AlphaFormatSupported(alpha_format));

  if (size.width() > max_texture_size_ || size.height() > max_texture_size_) {
    LOG(ERROR) << "Could not allocate image data because one of its dimensions "
               << "(" << size.width() << ", " << size.height() << ") "
               << "exceeds the maximum texture width (" << max_texture_size_
               << ")";
    return std::unique_ptr<ImageData>(nullptr);
  }

  std::unique_ptr<backend::TextureDataEGL> texture_data(
      cobalt_context_->system_egl()->AllocateTextureData(
          size, ConvertRenderTreeFormatToGL(pixel_format)));
  if (texture_data) {
    return std::unique_ptr<ImageData>(new HardwareImageData(
        std::move(texture_data), pixel_format, alpha_format));
  } else {
    return std::unique_ptr<ImageData>();
  }
}

scoped_refptr<render_tree::Image> HardwareResourceProvider::CreateImage(
    std::unique_ptr<ImageData> source_data) {
  TRACE_EVENT0("cobalt::renderer", "HardwareResourceProvider::CreateImage()");
  DCHECK(source_data);
  std::unique_ptr<HardwareImageData> skia_hardware_source_data(
      base::polymorphic_downcast<HardwareImageData*>(source_data.release()));
  const render_tree::ImageDataDescriptor& descriptor =
      skia_hardware_source_data->GetDescriptor();

  DCHECK(descriptor.alpha_format == render_tree::kAlphaFormatPremultiplied ||
         descriptor.alpha_format == render_tree::kAlphaFormatOpaque);
#if defined(COBALT_BUILD_TYPE_DEBUG)
  if (descriptor.alpha_format == render_tree::kAlphaFormatPremultiplied) {
    Image::DCheckForPremultipliedAlpha(
        descriptor.size, descriptor.pitch_in_bytes, descriptor.pixel_format,
        skia_hardware_source_data->GetMemory());
  }
#endif

  // Construct a frontend image from this data, which internally will send
  // a message to the rasterizer thread passing along the image data where the
  // backend texture will be constructed, and associated with this frontend
  // texture through a map that will be accessed when the rasterizer visits
  // any subsequently submitted render trees referencing the frontend image.
  return base::WrapRefCounted(new HardwareFrontendImage(
      std::move(skia_hardware_source_data), cobalt_context_, gr_context_,
      self_message_loop_));
}

#if SB_HAS(GRAPHICS)
namespace {

uint32_t DecodeTargetFormatToGLFormat(
    SbDecodeTargetFormat format, int plane,
    const SbDecodeTargetInfoPlane* plane_info) {
  switch (format) {
    case kSbDecodeTargetFormat1PlaneRGBA:
    // For UYVY, we will use a fragment shader where R = the first U, G = Y,
    // B = the second U, and A = V.
    case kSbDecodeTargetFormat1PlaneUYVY:
    {
      DCHECK_EQ(0, plane);
      return GL_RGBA;
    } break;
    case kSbDecodeTargetFormat2PlaneYUVNV12: {
      DCHECK_LT(plane, 2);
#if SB_API_VERSION >= 7
      // If this DCHECK fires, please set gl_texture_format, introduced
      // in Starboard 7.
      //
      // You probably want to set it to GL_ALPHA on plane 0 (luma) and
      // GL_LUMINANCE_ALPHA on plane 1 (chroma), which was the default before.
      DCHECK_NE(plane_info->gl_texture_format, 0);
      switch (plane_info->gl_texture_format) {
        case GL_ALPHA:
        case GL_LUMINANCE_ALPHA:
#if defined(GL_RED_EXT)
        case GL_RED_EXT:
#endif
#if defined(GL_RG_EXT)
        case GL_RG_EXT:
#endif
          return plane_info->gl_texture_format;
        default:
          // gl_texture_format is either unassigned or assigned to
          // an invalud value. Please see comment above for
          // gl_texture_format change, introduced in Starboard 7.
          CHECK(false);
          return 0;
      }
#else   // SB_API_VERSION >= 7
      switch (plane) {
        case 0:
          return GL_ALPHA;
        case 1:
          return GL_LUMINANCE_ALPHA;
        default:
          NOTREACHED();
          return GL_RGBA;
      }
#endif  // SB_API_VERSION >= 7
    } break;
    case kSbDecodeTargetFormat3Plane10BitYUVI420:
    case kSbDecodeTargetFormat3PlaneYUVI420: {
      DCHECK_LT(plane, 3);
#if SB_API_VERSION >= 7 && defined(GL_RED_EXT)
      if (plane_info->gl_texture_format == GL_RED_EXT) {
        return GL_RED_EXT;
      }
#endif  // SB_API_VERSION >= 7 && defined(GL_RED_EXT)
      return GL_ALPHA;
    } break;
    default: {
      NOTREACHED();
      return GL_RGBA;
    }
  }
}

render_tree::MultiPlaneImageFormat
DecodeTargetFormatToRenderTreeMultiPlaneFormat(SbDecodeTargetFormat format) {
  switch (format) {
    case kSbDecodeTargetFormat2PlaneYUVNV12: {
      return render_tree::kMultiPlaneImageFormatYUV2PlaneBT709;
    } break;
    case kSbDecodeTargetFormat3PlaneYUVI420: {
      return render_tree::kMultiPlaneImageFormatYUV3PlaneBT709;
    } break;
    case kSbDecodeTargetFormat3Plane10BitYUVI420: {
      return render_tree::kMultiPlaneImageFormatYUV3Plane10BitBT2020;
    } break;
    default: { NOTREACHED(); }
  }
  return render_tree::kMultiPlaneImageFormatYUV2PlaneBT709;
}

// Helper class that effectively "ref-count-izes" a SbDecodeTarget so that it
// can be shared by multiple consumers and only released when we are done with
// it.
class DecodeTargetReferenceCounted
    : public base::RefCountedThreadSafe<DecodeTargetReferenceCounted> {
 public:
  explicit DecodeTargetReferenceCounted(SbDecodeTarget decode_target)
      : decode_target_(decode_target) {}

 private:
  ~DecodeTargetReferenceCounted() { SbDecodeTargetRelease(decode_target_); }

  SbDecodeTarget decode_target_;

  friend class base::RefCountedThreadSafe<DecodeTargetReferenceCounted>;
};

void DoNothing(scoped_refptr<DecodeTargetReferenceCounted> decode_target_ref) {
  // Dummy function that lets us retain a reference to decode_target_ref within
  // a closure.
}

}  // namespace

scoped_refptr<render_tree::Image>
HardwareResourceProvider::CreateImageFromSbDecodeTarget(
    SbDecodeTarget decode_target) {
  SbDecodeTargetInfo info;
  SbMemorySet(&info, 0, sizeof(info));
  CHECK(SbDecodeTargetGetInfo(decode_target, &info));
  DCHECK_NE(kSbDecodeTargetFormat1PlaneBGRA, info.format);

  std::vector<scoped_refptr<HardwareFrontendImage> > planes;
  scoped_refptr<DecodeTargetReferenceCounted> decode_target_ref(
      new DecodeTargetReferenceCounted(decode_target));

// There is limited format support at this time.
  int planes_per_format = SbDecodeTargetNumberOfPlanesForFormat(info.format);

  for (int i = 0; i < planes_per_format; ++i) {
    const SbDecodeTargetInfoPlane& plane = info.planes[i];

    int gl_handle = plane.texture;
    render_tree::AlphaFormat alpha_format =
        info.is_opaque ? render_tree::kAlphaFormatOpaque
                       : render_tree::kAlphaFormatUnpremultiplied;

    std::unique_ptr<math::RectF> content_region;
    if (plane.content_region.left != 0 || plane.content_region.top != 0 ||
        plane.content_region.right != plane.width ||
        plane.content_region.bottom != plane.height) {
      content_region.reset(new math::RectF(
          plane.content_region.left, plane.content_region.top,
          plane.content_region.right - plane.content_region.left,
          plane.content_region.bottom - plane.content_region.top));
    }

    uint32_t gl_format = DecodeTargetFormatToGLFormat(info.format, i, &plane);

    std::unique_ptr<backend::TextureEGL> texture(new backend::TextureEGL(
        cobalt_context_, gl_handle, math::Size(plane.width, plane.height),
        gl_format, plane.gl_texture_target,
        base::BindOnce(&DoNothing, decode_target_ref)));

    // If the decode target is specified as UYVY format, then we need to pass
    // this in as supplementary data, as the |texture| object only knows that
    // it is RGBA.
    base::Optional<AlternateRgbaFormat> alternate_rgba_format;
    if (info.format == kSbDecodeTargetFormat1PlaneUYVY) {
      alternate_rgba_format = AlternateRgbaFormat_UYVY;
    }

    planes.push_back(base::WrapRefCounted(new HardwareFrontendImage(
        std::move(texture), alpha_format, cobalt_context_, gr_context_,
        std::move(content_region), self_message_loop_, alternate_rgba_format)));
  }

  if (planes_per_format == 1) {
    return planes[0];
  } else {
    return new HardwareMultiPlaneImage(
        DecodeTargetFormatToRenderTreeMultiPlaneFormat(info.format), planes);
  }
}

namespace {
void RunGraphicsContextRunnerOnRasterizerThread(
    SbDecodeTargetGlesContextRunnerTarget target_function,
    void* target_function_context,
    backend::GraphicsContextEGL* graphics_context,
    base::WaitableEvent* done_event) {
  backend::GraphicsContextEGL::ScopedMakeCurrent make_current(graphics_context);
  target_function(target_function_context);
  done_event->Signal();
}
}  // namespace

// static
void HardwareResourceProvider::GraphicsContextRunner(
    SbDecodeTargetGraphicsContextProvider* graphics_context_provider,
    SbDecodeTargetGlesContextRunnerTarget target_function,
    void* target_function_context) {
  SbDecodeTarget decode_target = kSbDecodeTargetInvalid;

  HardwareResourceProvider* provider =
      reinterpret_cast<HardwareResourceProvider*>(
          graphics_context_provider->gles_context_runner_context);

  if (base::MessageLoop::current() != provider->self_message_loop_) {
    // Post a task to the rasterizer thread to have it run the requested
    // function, and wait for it to complete before returning.
    base::WaitableEvent done_event(
        base::WaitableEvent::ResetPolicy::MANUAL,
        base::WaitableEvent::InitialState::NOT_SIGNALED);
    provider->self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&RunGraphicsContextRunnerOnRasterizerThread,
                              target_function, target_function_context,
                              provider->cobalt_context_, &done_event));
    done_event.Wait();
  } else {
    // If we are already on the rasterizer thread, just run the function
    // directly.
    backend::GraphicsContextEGL::ScopedMakeCurrent make_current(
        provider->cobalt_context_);
    target_function(target_function_context);
  }
}

#endif  // SB_HAS(GRAPHICS)

std::unique_ptr<RawImageMemory>
HardwareResourceProvider::AllocateRawImageMemory(size_t size_in_bytes,
                                                 size_t alignment) {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::AllocateRawImageMemory()");
  return std::unique_ptr<RawImageMemory>(new HardwareRawImageMemory(
      cobalt_context_->system_egl()->AllocateRawTextureMemory(size_in_bytes,
                                                              alignment)));
}

scoped_refptr<render_tree::Image>
HardwareResourceProvider::CreateMultiPlaneImageFromRawMemory(
    std::unique_ptr<RawImageMemory> raw_image_memory,
    const render_tree::MultiPlaneImageDataDescriptor& descriptor) {
  TRACE_EVENT0(
      "cobalt::renderer",
      "HardwareResourceProvider::CreateMultiPlaneImageFromRawMemory()");
  DCHECK((render_tree::kMultiPlaneImageFormatYUV2PlaneBT709 ==
              descriptor.image_format() &&
          2 == descriptor.num_planes()) ||
         (render_tree::kMultiPlaneImageFormatYUV3PlaneBT709 ==
              descriptor.image_format() &&
          3 == descriptor.num_planes()) ||
         (render_tree::kMultiPlaneImageFormatYUV3PlaneBT601FullRange ==
              descriptor.image_format() &&
          3 == descriptor.num_planes()))
      << "Currently we only support 2-plane or 3-plane YUV multi plane images.";

  std::unique_ptr<HardwareRawImageMemory> skia_hardware_raw_image_memory(
      base::polymorphic_downcast<HardwareRawImageMemory*>(
          raw_image_memory.release()));

  return base::WrapRefCounted(new HardwareMultiPlaneImage(
      std::move(skia_hardware_raw_image_memory), descriptor, cobalt_context_,
      gr_context_, self_message_loop_));
}

bool HardwareResourceProvider::HasLocalFontFamily(
    const char* font_family_name) const {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::HasLocalFontFamily()");

  sk_sp<SkFontMgr> font_manager(SkFontMgr::RefDefault());
  sk_sp<SkFontStyleSet> style_set(font_manager->matchFamily(font_family_name));
  return style_set->count() > 0;
}

scoped_refptr<render_tree::Typeface> HardwareResourceProvider::GetLocalTypeface(
    const char* font_family_name, render_tree::FontStyle font_style) {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::GetLocalTypeface()");

  sk_sp<SkFontMgr> font_manager(SkFontMgr::RefDefault());
  sk_sp<SkTypeface_Cobalt> typeface(
      base::polymorphic_downcast<SkTypeface_Cobalt*>(
          font_manager->matchFamilyStyle(
              font_family_name, CobaltFontStyleToSkFontStyle(font_style))));
  return scoped_refptr<render_tree::Typeface>(new SkiaTypeface(typeface));
}

scoped_refptr<render_tree::Typeface>
HardwareResourceProvider::GetLocalTypefaceByFaceNameIfAvailable(
    const char* font_face_name) {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::GetLocalTypefaceIfAvailable()");

  sk_sp<SkFontMgr> font_manager(SkFontMgr::RefDefault());
  SkFontMgr_Cobalt* cobalt_font_manager =
      base::polymorphic_downcast<SkFontMgr_Cobalt*>(font_manager.get());

  sk_sp<SkTypeface_Cobalt> typeface(
      base::polymorphic_downcast<SkTypeface_Cobalt*>(
          cobalt_font_manager->MatchFaceName(font_face_name)));
  if (!typeface) {
    return nullptr;
  }

  return scoped_refptr<render_tree::Typeface>(new SkiaTypeface(typeface));
}

scoped_refptr<render_tree::Typeface>
HardwareResourceProvider::GetCharacterFallbackTypeface(
    int32 character, render_tree::FontStyle font_style,
    const std::string& language) {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::GetCharacterFallbackTypeface()");

  sk_sp<SkFontMgr> font_manager(SkFontMgr::RefDefault());
  const char* language_cstr = language.c_str();
  sk_sp<SkTypeface_Cobalt> typeface(
      base::polymorphic_downcast<SkTypeface_Cobalt*>(
          font_manager->matchFamilyStyleCharacter(
              NULL, CobaltFontStyleToSkFontStyle(font_style), &language_cstr, 1,
              character)));
  return scoped_refptr<render_tree::Typeface>(new SkiaTypeface(typeface));
}

scoped_refptr<render_tree::Typeface>
HardwareResourceProvider::CreateTypefaceFromRawData(
    std::unique_ptr<render_tree::ResourceProvider::RawTypefaceDataVector>
        raw_data,
    std::string* error_string) {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::CreateFontFromData()");

  if (raw_data == NULL) {
    *error_string = "No data to process";
    return NULL;
  }

  ots::ExpandingMemoryStream sanitized_data(
      raw_data->size(), render_tree::ResourceProvider::kMaxTypefaceDataSize);
  ots::OTSContext context;
  if (!context.Process(&sanitized_data, &((*raw_data)[0]), raw_data->size())) {
    *error_string = "OpenType sanitizer unable to process data";
    return NULL;
  }

  // Free the raw data now that we're done with it.
  raw_data.reset();

  std::unique_ptr<SkStreamAsset> stream;
  {
    sk_sp<SkData> skia_data(SkData::MakeWithCopy(
        sanitized_data.get(), static_cast<size_t>(sanitized_data.Tell())));
    stream.reset(new SkMemoryStream(skia_data));
  }

  sk_sp<SkTypeface_Cobalt> typeface(
      base::polymorphic_downcast<SkTypeface_Cobalt*>(
          SkTypeface::MakeFromStream(std::move(stream)).release()));
  if (typeface) {
    return scoped_refptr<render_tree::Typeface>(new SkiaTypeface(typeface));
  } else {
    *error_string = "Skia unable to create typeface";
    return NULL;
  }
}

scoped_refptr<render_tree::GlyphBuffer>
HardwareResourceProvider::CreateGlyphBuffer(
    const base::char16* text_buffer, size_t text_length,
    const std::string& language, bool is_rtl,
    render_tree::FontProvider* font_provider) {
  return text_shaper_.CreateGlyphBuffer(text_buffer, text_length, language,
                                        is_rtl, font_provider);
}

scoped_refptr<render_tree::GlyphBuffer>
HardwareResourceProvider::CreateGlyphBuffer(
    const std::string& utf8_string,
    const scoped_refptr<render_tree::Font>& font) {
  return text_shaper_.CreateGlyphBuffer(utf8_string, font);
}

float HardwareResourceProvider::GetTextWidth(
    const base::char16* text_buffer, size_t text_length,
    const std::string& language, bool is_rtl,
    render_tree::FontProvider* font_provider,
    render_tree::FontVector* maybe_used_fonts) {
  return text_shaper_.GetTextWidth(text_buffer, text_length, language, is_rtl,
                                   font_provider, maybe_used_fonts);
}

scoped_refptr<render_tree::LottieAnimation>
HardwareResourceProvider::CreateLottieAnimation(const char* data,
                                                size_t length) {
  TRACE_EVENT0("cobalt::renderer",
               "HardwareResourceProvider::CreateLottieAnimation()");
  return base::WrapRefCounted(new SkottieAnimation(data, length));
}

scoped_refptr<render_tree::Mesh> HardwareResourceProvider::CreateMesh(
    std::unique_ptr<std::vector<render_tree::Mesh::Vertex> > vertices,
    render_tree::Mesh::DrawMode draw_mode) {
  return new HardwareMesh(std::move(vertices), draw_mode, cobalt_context_);
}

scoped_refptr<render_tree::Image> HardwareResourceProvider::DrawOffscreenImage(
    const scoped_refptr<render_tree::Node>& root) {
  return base::WrapRefCounted(new HardwareFrontendImage(
      root, submit_offscreen_callback_, cobalt_context_, gr_context_,
      self_message_loop_));
}

}  // namespace skia
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // SB_API_VERSION >= 12 || SB_HAS(GLES2)
