// Copyright 2017 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 >= SB_ALL_RENDERERS_REQUIRED_VERSION || SB_HAS(GLES2)

#include "cobalt/renderer/rasterizer/egl/offscreen_target_manager.h"

#include <algorithm>
#include <memory>
#include <unordered_map>
#include <vector>

#include "cobalt/renderer/rasterizer/egl/rect_allocator.h"
#include "third_party/skia/include/core/SkRefCnt.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace egl {

namespace {

struct AllocationMapValue {
  AllocationMapValue(const OffscreenTargetManager::ErrorData& in_error_data,
                     const math::RectF& in_target_region)
      : error_data(in_error_data), target_region(in_target_region) {}
  OffscreenTargetManager::ErrorData error_data;
  math::RectF target_region;
};

typedef std::unordered_multimap<int64_t, AllocationMapValue> AllocationMap;

int32_t NextPowerOf2(int32_t num) {
  // Return the smallest power of 2 that is greater than or equal to num.
  // This flips on all bits <= num, then num+1 will be the next power of 2.
  --num;
  num |= num >> 1;
  num |= num >> 2;
  num |= num >> 4;
  num |= num >> 8;
  num |= num >> 16;
  return num + 1;
}

bool IsPowerOf2(int32_t num) { return (num & (num - 1)) == 0; }

size_t GetMemorySize(const math::Size& target_size) {
  // RGBA uses 4 bytes per pixel. Assume no rounding to the nearest power of 2.
  return target_size.width() * target_size.height() * 4;
}

}  // namespace

struct OffscreenTargetManager::OffscreenAtlas {
  explicit OffscreenAtlas(const math::Size& size)
      : allocator(size), allocations_used(0), needs_flush(false) {}

  RectAllocator allocator;
  AllocationMap allocation_map;
  size_t allocations_used;
  scoped_refptr<backend::FramebufferRenderTargetEGL> framebuffer;
  sk_sp<SkSurface> skia_surface;
  bool needs_flush;
};

OffscreenTargetManager::OffscreenTargetManager(
    backend::GraphicsContextEGL* graphics_context,
    const CreateFallbackSurfaceFunction& create_fallback_surface,
    size_t memory_limit)
    : graphics_context_(graphics_context),
      create_fallback_surface_(create_fallback_surface),
      offscreen_target_size_mask_(0, 0),
      memory_limit_(memory_limit),
      cache_error_threshold_(1.0f) {}

OffscreenTargetManager::~OffscreenTargetManager() {}

void OffscreenTargetManager::Update(const math::Size& frame_size) {
  if (offscreen_atlases_.empty()) {
    DCHECK(offscreen_atlases_1d_.empty());
    InitializeTargets(frame_size);
  }

  SelectAtlasCache(&offscreen_atlases_, &offscreen_cache_);
  SelectAtlasCache(&offscreen_atlases_1d_, &offscreen_cache_1d_);

  // Delete uncached targets that were not used in the previous render frame.
  for (size_t index = 0; index < uncached_targets_.size();) {
    if (uncached_targets_[index]->allocations_used == 0) {
      uncached_targets_.erase(uncached_targets_.begin() + index);
    } else {
      uncached_targets_[index]->allocations_used = 0;
      ++index;
    }
  }
}

void OffscreenTargetManager::SelectAtlasCache(
    std::vector<std::unique_ptr<OffscreenAtlas>>* atlases_ptr,
    std::unique_ptr<OffscreenAtlas>* cache_ptr) {
  std::vector<std::unique_ptr<OffscreenAtlas>>& atlases = *atlases_ptr;
  std::unique_ptr<OffscreenAtlas>& cache = *cache_ptr;

  // If any of the current atlases have more allocations used than the
  // current cache, then use that as the new cache.
  size_t most_used_atlas_index = 0;
  for (size_t index = 1; index < atlases.size(); ++index) {
    if (atlases[most_used_atlas_index]->allocations_used <
        atlases[index]->allocations_used) {
      most_used_atlas_index = index;
    }
  }

  OffscreenAtlas* most_used_atlas = atlases[most_used_atlas_index].get();
  if (cache->allocations_used < most_used_atlas->allocations_used) {
    OffscreenAtlas* new_atlas = cache.release();
    cache = std::move(atlases[most_used_atlas_index]);
    atlases.erase(atlases.begin() + most_used_atlas_index);
    atlases.emplace_back(new_atlas);
  }
  cache->allocations_used = 0;

  // Reset all current atlases for use this frame.
  for (size_t index = 0; index < atlases.size(); ++index) {
    OffscreenAtlas* atlas = atlases[index].get();
    atlas->allocator.Reset();
    atlas->allocation_map.clear();
    atlas->allocations_used = 0;
  }
}

void OffscreenTargetManager::Flush() {
  if (offscreen_cache_->needs_flush) {
    offscreen_cache_->needs_flush = false;
    offscreen_cache_->skia_surface->getCanvas()->flush();
  }
  for (size_t index = 0; index < offscreen_atlases_.size(); ++index) {
    if (offscreen_atlases_[index]->needs_flush) {
      offscreen_atlases_[index]->needs_flush = false;
      offscreen_atlases_[index]->skia_surface->getCanvas()->flush();
    }
  }
}

void OffscreenTargetManager::SetCacheErrorThreshold(float threshold) {
  DCHECK_GE(threshold, 0.0f);
  cache_error_threshold_ = threshold;
}

bool OffscreenTargetManager::GetCachedTarget(
    const render_tree::Node* node, const CacheErrorFunction& error_function,
    TargetInfo* out_target_info) {
  // Find the cache of the given node (if any) with the lowest error.
  AllocationMap::iterator best_iter = offscreen_cache_->allocation_map.end();
  float best_error = 2.0f;

  auto range = offscreen_cache_->allocation_map.equal_range(node->GetId());
  for (auto iter = range.first; iter != range.second; ++iter) {
    float error = error_function.Run(iter->second.error_data);
    if (best_error > error) {
      best_error = error;
      best_iter = iter;
    }
  }

  // A cache entry matches the caller's criteria only if error < threshold.
  if (best_error < cache_error_threshold_) {
    offscreen_cache_->allocations_used += 1;
    out_target_info->framebuffer = offscreen_cache_->framebuffer.get();
    out_target_info->skia_canvas = offscreen_cache_->skia_surface->getCanvas();
    out_target_info->region = best_iter->second.target_region;
    return true;
  }

  return false;
}

bool OffscreenTargetManager::GetCachedTarget(
    const render_tree::Node* node, const CacheErrorFunction1D& error_function,
    TargetInfo* out_target_info) {
  // Find the cache of the given node (if any) with the lowest error.
  AllocationMap::iterator best_iter = offscreen_cache_1d_->allocation_map.end();
  float best_error = 2.0f;

  auto range = offscreen_cache_1d_->allocation_map.equal_range(node->GetId());
  for (auto iter = range.first; iter != range.second; ++iter) {
    float error = error_function.Run(iter->second.error_data.width());
    if (best_error > error) {
      best_error = error;
      best_iter = iter;
    }
  }

  // A cache entry matches the caller's criteria only if error < threshold.
  if (best_error < cache_error_threshold_) {
    offscreen_cache_1d_->allocations_used += 1;
    out_target_info->framebuffer = offscreen_cache_1d_->framebuffer.get();
    out_target_info->skia_canvas = nullptr;
    out_target_info->region = best_iter->second.target_region;
    return true;
  }

  return false;
}

void OffscreenTargetManager::AllocateCachedTarget(const render_tree::Node* node,
                                                  const math::SizeF& size,
                                                  const ErrorData& error_data,
                                                  TargetInfo* out_target_info) {
  // Pad the offscreen target size to prevent interpolation with unwanted
  // texels when rendering the results.
  const int kInterpolatePad = 1;

  // Get an offscreen target for rendering. Align up the requested target size
  // to improve usage of the atlas (since more requests will have the same
  // aligned width or height).
  math::Size target_size(
      (static_cast<int>(std::ceil(size.width())) + 2 * kInterpolatePad +
       offscreen_target_size_mask_.width()) &
          ~offscreen_target_size_mask_.width(),
      (static_cast<int>(std::ceil(size.height())) + 2 * kInterpolatePad +
       offscreen_target_size_mask_.height()) &
          ~offscreen_target_size_mask_.height());
  math::RectF target_rect(0.0f, 0.0f, 0.0f, 0.0f);
  OffscreenAtlas* atlas = NULL;

  // See if there's room in the offscreen cache for additional targets.
  atlas = offscreen_cache_.get();
  target_rect = atlas->allocator.Allocate(target_size);

  if (target_rect.IsEmpty()) {
    // See if there's room in the other atlases.
    for (size_t index = offscreen_atlases_.size(); index > 0;) {
      atlas = offscreen_atlases_[--index].get();
      target_rect = atlas->allocator.Allocate(target_size);
      if (!target_rect.IsEmpty()) {
        break;
      }
    }
  }

  if (target_rect.IsEmpty()) {
    // There wasn't enough room for the requested offscreen target.
    out_target_info->framebuffer = nullptr;
    out_target_info->skia_canvas = nullptr;
    out_target_info->region.SetRect(0, 0, 0, 0);
  } else {
    // Inset to prevent interpolation with unwanted pixels at the edge.
    target_rect.Inset(kInterpolatePad, kInterpolatePad);
    DCHECK_LE(size.width(), target_rect.width());
    DCHECK_LE(size.height(), target_rect.height());
    target_rect.set_size(size);

    // Clear the atlas if this will be the first draw into it.
    if (atlas->allocation_map.empty()) {
      atlas->skia_surface->getCanvas()->clear(SK_ColorTRANSPARENT);
    }

    atlas->allocation_map.insert(AllocationMap::value_type(
        node->GetId(), AllocationMapValue(error_data, target_rect)));
    atlas->allocations_used += 1;
    atlas->needs_flush = true;

    out_target_info->framebuffer = atlas->framebuffer.get();
    out_target_info->skia_canvas = atlas->skia_surface->getCanvas();
    out_target_info->region = target_rect;
  }
}

void OffscreenTargetManager::AllocateCachedTarget(const render_tree::Node* node,
                                                  float size,
                                                  const ErrorData1D& error_data,
                                                  TargetInfo* out_target_info) {
  // 1D targets do not use any padding to avoid interpolation with neighboring
  // allocations in the atlas.
  math::Size target_size(static_cast<int>(std::ceil(size)), 1);
  math::RectF target_rect(0.0f, 0.0f, 0.0f, 0.0f);
  OffscreenAtlas* atlas = NULL;

  // See if there's room in the offscreen cache for additional targets.
  atlas = offscreen_cache_1d_.get();
  target_rect = atlas->allocator.Allocate(target_size);

  if (target_rect.IsEmpty()) {
    // See if there's room in the other atlases.
    for (size_t index = offscreen_atlases_1d_.size(); index > 0;) {
      atlas = offscreen_atlases_1d_[--index].get();
      target_rect = atlas->allocator.Allocate(target_size);
      if (!target_rect.IsEmpty()) {
        break;
      }
    }
  }

  if (target_rect.IsEmpty()) {
    // There wasn't enough room for the requested offscreen target.
    out_target_info->framebuffer = nullptr;
    out_target_info->skia_canvas = nullptr;
    out_target_info->region.SetRect(0, 0, 0, 0);
  } else {
    DCHECK_LE(size, target_rect.width());
    target_rect.set_width(size);

    atlas->allocation_map.insert(AllocationMap::value_type(
        node->GetId(),
        AllocationMapValue(ErrorData(error_data, 1), target_rect)));
    atlas->allocations_used += 1;
    atlas->needs_flush = false;

    out_target_info->framebuffer = atlas->framebuffer.get();
    out_target_info->skia_canvas = nullptr;
    out_target_info->region = target_rect;
  }
}

void OffscreenTargetManager::AllocateUncachedTarget(
    const math::SizeF& size, TargetInfo* out_target_info) {
  // Align up the requested target size to increase the chances that it can
  // be reused in subsequent frames.
  math::Size target_size((static_cast<int>(std::ceil(size.width())) +
                          offscreen_target_size_mask_.width()) &
                             ~offscreen_target_size_mask_.width(),
                         (static_cast<int>(std::ceil(size.height())) +
                          offscreen_target_size_mask_.height()) &
                             ~offscreen_target_size_mask_.height());

  // Find a render target that meets the size requirement. However, do not
  // select anything that is too big.
  const int kMaxTargetSize = target_size.GetArea() * 2;
  OffscreenAtlas* atlas = nullptr;

  for (size_t index = 0; index < uncached_targets_.size(); ++index) {
    OffscreenAtlas* current = uncached_targets_[index].get();
    if (current->allocations_used == 0) {
      const math::Size& current_size = current->framebuffer->GetSize();
      if (current_size.width() >= target_size.width() &&
          current_size.height() >= target_size.height() &&
          current_size.GetArea() <= kMaxTargetSize) {
        // Pick the smallest render target that meets the requirements.
        if (atlas &&
            atlas->framebuffer->GetSize().GetArea() < current_size.GetArea()) {
          continue;
        }
        atlas = current;
      }
    }
  }

  if (!atlas) {
    atlas = CreateOffscreenAtlas(target_size, true).release();
    if (!atlas) {
      // If there was an error allocating the offscreen atlas, indicate by
      // marking framebuffer and skia canvas as null and returning early.
      out_target_info->framebuffer = nullptr;
      out_target_info->skia_canvas = nullptr;
      return;
    }
    uncached_targets_.emplace_back(atlas);
  }

  atlas->allocations_used = 1;
  out_target_info->framebuffer = atlas->framebuffer.get();
  out_target_info->skia_canvas = atlas->skia_surface->getCanvas();
  out_target_info->region.SetRect(0.0f, 0.0f, size.width(), size.height());
}

void OffscreenTargetManager::InitializeTargets(const math::Size& frame_size) {
  if (frame_size.width() >= 64 && frame_size.height() >= 64) {
    offscreen_target_size_mask_.SetSize(
        NextPowerOf2(frame_size.width() / 64) - 1,
        NextPowerOf2(frame_size.height() / 64) - 1);
  } else {
    offscreen_target_size_mask_.SetSize(0, 0);
  }
  DCHECK(IsPowerOf2(offscreen_target_size_mask_.width() + 1));
  DCHECK(IsPowerOf2(offscreen_target_size_mask_.height() + 1));

  // Allow offscreen targets to be as large as the frame.
  math::Size max_size(std::max(frame_size.width(), 1),
                      std::max(frame_size.height(), 1));

  // Offscreen render targets are optional but highly recommended. These
  // allow caching of render results for improved performance. At least two
  // must exist -- one for the cache and the other a working scratch.
  size_t half_memory_limit = memory_limit_ / 2;
  math::Size atlas_size(1, 1);
  for (;;) {
    // See if the next atlas size will fit in the memory budget.
    // Try to keep the atlas square-ish.
    math::Size next_size(atlas_size);
    if (atlas_size.width() < max_size.width() &&
        (atlas_size.width() <= atlas_size.height() ||
         atlas_size.height() >= max_size.height())) {
      next_size.set_width(std::min(atlas_size.width() * 2, max_size.width()));
    } else if (atlas_size.height() < max_size.height()) {
      next_size.set_height(
          std::min(atlas_size.height() * 2, max_size.height()));
    } else {
      break;
    }
    if (GetMemorySize(next_size) > half_memory_limit) {
      break;
    }
    atlas_size = next_size;
  }

  // It is better to have fewer, large atlases than many small atlases to
  // minimize the cost of switching render targets. Consider changing the
  // max_size logic if there's plenty of memory to spare.
  const int kMaxAtlases = 4;
  int num_atlases = memory_limit_ / GetMemorySize(atlas_size);
  if (num_atlases < 2) {
    // Must have at least two atlases -- even if they are of a token size.
    // This simplifies code elsewhere.
    DCHECK(atlas_size.width() == 1 && atlas_size.height() == 1);
    num_atlases = 2;
  } else if (num_atlases > kMaxAtlases) {
    DCHECK(atlas_size == max_size);
    num_atlases = kMaxAtlases;
    DLOG_ONCE(WARNING) << "More memory was allotted for offscreen render"
                       << " targets than will be used.";
  }
  offscreen_cache_ = CreateOffscreenAtlas(atlas_size, true);
  CHECK(offscreen_cache_);
  for (int i = 1; i < num_atlases; ++i) {
    offscreen_atlases_.emplace_back(
        CreateOffscreenAtlas(atlas_size, true).release());
    CHECK(offscreen_atlases_.back());
  }

  // Create 1D texture atlases. These are just regular 2D textures that will
  // be used as 1D row textures. These atlases are not intended to be used by
  // skia.
  const int kAtlasHeight1D =
      std::min(std::min(16, frame_size.width()), frame_size.height());
  math::Size atlas_size_1d(std::max(frame_size.width(), frame_size.height()),
                           kAtlasHeight1D);
  offscreen_atlases_1d_.emplace_back(
      CreateOffscreenAtlas(atlas_size_1d, false).release());
  CHECK(offscreen_atlases_1d_.back());
  offscreen_cache_1d_ = CreateOffscreenAtlas(atlas_size_1d, false);
  CHECK(offscreen_cache_1d_);
}

std::unique_ptr<OffscreenTargetManager::OffscreenAtlas>
OffscreenTargetManager::CreateOffscreenAtlas(const math::Size& size,
                                             bool create_canvas) {
  std::unique_ptr<OffscreenAtlas> atlas(new OffscreenAtlas(size));

  // Create a new framebuffer.
  atlas->framebuffer =
      new backend::FramebufferRenderTargetEGL(graphics_context_, size);
  if (atlas->framebuffer->CreationError()) {
    return std::unique_ptr<OffscreenAtlas>();
  }

  if (create_canvas) {
    // Wrap the framebuffer as a skia surface.
    atlas->skia_surface =
        create_fallback_surface_.Run(atlas->framebuffer.get());
  }

  return std::move(atlas);
}

}  // namespace egl
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt

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