// Copyright 2016 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 "cobalt/renderer/rasterizer/blitter/cached_software_rasterizer.h"

#include <utility>

#include "cobalt/math/vector2d_f.h"
#include "cobalt/render_tree/text_node.h"
#include "cobalt/renderer/rasterizer/blitter/skia_blitter_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImageInfo.h"

#if SB_API_VERSION < 12 && SB_HAS(BLITTER)

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace blitter {

size_t CachedSoftwareRasterizer::Surface::GetEstimatedMemoryUsage() const {
  // We assume 4-bytes-per-pixel.
  return coord_mapping.output_bounds.size().GetArea() * 4;
}

CachedSoftwareRasterizer::CachedSoftwareRasterizer(
    SbBlitterDevice device, SbBlitterContext context, int cache_capacity,
    bool purge_skia_font_caches_on_destruction)
    : cache_capacity_(cache_capacity),
      device_(device),
      context_(context),
      software_rasterizer_(purge_skia_font_caches_on_destruction),
      cache_memory_usage_(
          "Memory.CachedSoftwareRasterizer.CacheUsage", 0,
          "Total memory occupied by cached software-rasterized surfaces."),
      cache_frame_usage_(
          "Memory.CachedSoftwareRasterizer.FrameCacheUsage", 0,
          "Total memory occupied by cache software-rasterizer surfaces that "
          "were referenced this frame.") {}

CachedSoftwareRasterizer::~CachedSoftwareRasterizer() {
  // Clean up any leftover surfaces.
  for (CacheMap::iterator iter = surface_map_.begin();
       iter != surface_map_.end(); ++iter) {
    DCHECK(iter->second.cached);
    SbBlitterDestroySurface(iter->second.surface);
  }
  surface_map_.clear();
}

void CachedSoftwareRasterizer::OnStartNewFrame() {
  for (CacheMap::iterator iter = surface_map_.begin();
       iter != surface_map_.end();) {
    CacheMap::iterator current = iter;
    ++iter;

    // If the surface was referenced mark it as being unreferenced for the next
    // frame.
    if (current->second.referenced) {
#if defined(ENABLE_DEBUGGER)
      current->second.created = false;
#endif  // defined(ENABLE_DEBUGGER)
      current->second.referenced = false;
    }
  }

  // Reset our current frame cache usage to 0 since this is the start of a new
  // frame.
  cache_frame_usage_ = 0;
}

void CachedSoftwareRasterizer::PurgeUntilSpaceAvailable(int space_needed) {
  while (space_needed + cache_memory_usage_.value() > cache_capacity_) {
    CacheMap::iterator next_item = surface_map_.begin();

    // We shouldn't call this function if it means we would have to purge
    // elements that were referenced this frame.  This is to avoid thrashing
    // the cache, we would prefer to cache as much as we can in a frame, and
    // then just not cache whatever we can't without cycling what's in the cache
    // already.
    DCHECK(!next_item->second.referenced);
    cache_memory_usage_ -= next_item->second.GetEstimatedMemoryUsage();
    SbBlitterDestroySurface(next_item->second.surface);
    surface_map_.erase(next_item);
  }
}

CachedSoftwareRasterizer::Surface CachedSoftwareRasterizer::GetSurface(
    render_tree::Node* node, const Transform& transform) {
  CacheMap::iterator found = surface_map_.find(node);
  if (found != surface_map_.end()) {
#if SB_HAS(BILINEAR_FILTERING_SUPPORT)
    if (found->second.scale.x() >= transform.scale().x() &&
        found->second.scale.y() >= transform.scale().y()) {
#else  // SB_HAS(BILINEAR_FILTERING_SUPPORT)
    if (found->second.scale.x() == transform.scale().x() &&
        found->second.scale.y() == transform.scale().y()) {
#endif
      std::pair<render_tree::Node*, Surface> to_insert =
          std::make_pair(node, found->second);

      // Move this surface's position in the queue to the front, since it was
      // referenced.
      to_insert.second.referenced = true;
      surface_map_.erase(found);
      surface_map_.insert(to_insert);

      cache_frame_usage_ += to_insert.second.GetEstimatedMemoryUsage();

      return to_insert.second;
    }
  }

  Surface software_surface;
  software_surface.referenced = true;
#if defined(ENABLE_DEBUGGER)
  software_surface.created = true;
#endif  // defined(ENABLE_DEBUGGER)
  software_surface.node = node;
  software_surface.surface = kSbBlitterInvalidSurface;
  software_surface.cached = false;

  // We ensure that scale is at least 1 except for TextNodes, since the Blitter
  // scaling is not as sophisticated as Skia's. Since it is common to have
  // animating scale between 0 and 1 (e.g. an item animating from 0 to 1 to
  // "grow" into the scene), this ensures that rendered items will not look
  // pixellated as they grow (e.g. if they were cached at scale 0.2, they would
  // be stretched x5 if the scale were to animate to 1.0).
  if (transform.scale().x() == 0.0f || transform.scale().y() == 0.0f) {
    // There won't be anything to render if the transform squishes one dimension
    // to 0.
    return software_surface;
  }
  DCHECK_LT(0, transform.scale().x());
  DCHECK_LT(0, transform.scale().y());
  Transform scaled_transform(transform);
// If bilinear filtering is not supported, do not rely on the rasterizer to
// scale down for us, it results in too many artifacts.
#if SB_HAS(BILINEAR_FILTERING_SUPPORT)
  math::Vector2dF apply_scale(1.0f, 1.0f);
  if (node->GetTypeId() != base::GetTypeId<render_tree::TextNode>()) {
    if (transform.scale().x() < 1.0f) {
      apply_scale.set_x(1.0f / transform.scale().x());
    }
    if (transform.scale().y() < 1.0f) {
      apply_scale.set_y(1.0f / transform.scale().y());
    }
  }
  scaled_transform.ApplyScale(apply_scale);
#endif  // SB_HAS(BILINEAR_FILTERING_SUPPORT)

  software_surface.scale = scaled_transform.scale();

  common::OffscreenRenderCoordinateMapping coord_mapping =
      common::GetOffscreenRenderCoordinateMapping(node->GetBounds(),
                                                  scaled_transform.ToMatrix(),
                                                  base::Optional<math::Rect>());

  software_surface.coord_mapping = coord_mapping;

  if (coord_mapping.output_bounds.IsEmpty()) {
    // There's nothing to render if the bounds are 0.
    return software_surface;
  }

  DCHECK_GE(0.001f, std::abs(1.0f - scaled_transform.scale().x() *
                                        coord_mapping.output_post_scale.x()));
  DCHECK_GE(0.001f, std::abs(1.0f - scaled_transform.scale().y() *
                                        coord_mapping.output_post_scale.y()));

  SkImageInfo output_image_info = SkImageInfo::MakeN32(
      coord_mapping.output_bounds.width(), coord_mapping.output_bounds.height(),
      kPremul_SkAlphaType);

  // Allocate the pixels for the output image.
  SbBlitterPixelDataFormat blitter_pixel_data_format =
      SkiaToBlitterPixelFormat(output_image_info.colorType());
  DCHECK(SbBlitterIsPixelFormatSupportedByPixelData(device_,
                                                    blitter_pixel_data_format));
  SbBlitterPixelData pixel_data = SbBlitterCreatePixelData(
      device_, coord_mapping.output_bounds.width(),
      coord_mapping.output_bounds.height(), blitter_pixel_data_format);
  if (!SbBlitterIsPixelDataValid(pixel_data)) {
    // We failed to allocate the pixel data, just return with a null surface
    // in this case.
    LOG(ERROR) << "Error allocating pixel data for an offscreen software "
                  "rasterization.";
    return software_surface;
  }

  SkBitmap bitmap;
  bitmap.installPixels(output_image_info,
                       SbBlitterGetPixelDataPointer(pixel_data),
                       SbBlitterGetPixelDataPitchInBytes(pixel_data));

  // Setup our Skia canvas that we will be using as the target for all CPU Skia
  // output.
  SkCanvas canvas(bitmap);
  canvas.clear(SkColorSetARGB(0, 0, 0, 0));

  Transform sub_render_transform(coord_mapping.sub_render_transform);

  // Now setup our canvas so that the render tree will be rendered to the top
  // left corner instead of at node->GetBounds().origin().
  canvas.translate(sub_render_transform.translate().x(),
                   sub_render_transform.translate().y());
  // And finally set the scale on our target canvas to match that of the current
  // |transform|.
  canvas.scale(sub_render_transform.scale().x(),
               sub_render_transform.scale().y());

  // Use the Skia software rasterizer to render our subtree.
  software_rasterizer_.Submit(node, &canvas);

  // Create a surface out of the now populated pixel data.
  software_surface.surface =
      SbBlitterCreateSurfaceFromPixelData(device_, pixel_data);

  if (software_surface.GetEstimatedMemoryUsage() + cache_frame_usage_.value() <=
      cache_capacity_) {
    software_surface.cached = true;
    cache_frame_usage_ += software_surface.GetEstimatedMemoryUsage();

    if (found != surface_map_.end()) {
      // This surface may have already been in the cache if it was in there
      // with a different scale.  In that case, replace the old one.
      cache_memory_usage_ -= found->second.GetEstimatedMemoryUsage();
      SbBlitterDestroySurface(found->second.surface);
      surface_map_.erase(found);
    }

    PurgeUntilSpaceAvailable(software_surface.GetEstimatedMemoryUsage());

    std::pair<CacheMap::iterator, bool> inserted =
        surface_map_.insert(std::make_pair(node, software_surface));
    cache_memory_usage_ += software_surface.GetEstimatedMemoryUsage();
  }

  return software_surface;
}

}  // namespace blitter
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

#endif  // SB_API_VERSION < 12 && SB_HAS(BLITTER)
