/*
 * 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/browser/memory_settings/calculations.h"

#include <algorithm>

#include "cobalt/browser/memory_settings/constants.h"
#include "cobalt/math/clamp.h"
#include "cobalt/math/size.h"

namespace cobalt {
namespace browser {
namespace memory_settings {
namespace {

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

int32_t NearestPowerOf2(int32_t num) {
  int32_t nearest = NextPowerOf2(num);
  if (static_cast<float>(nearest) / num > 1.5f) {
    nearest /= 2;
  }
  return nearest;
}

double DisplayScaleTo1080p(const math::Size& dimensions) {
  static const double kNumReferencePixels = 1920. * 1080.;
  const double num_pixels = static_cast<double>(dimensions.width()) *
                            static_cast<double>(dimensions.height());
  return num_pixels / kNumReferencePixels;
}

// LinearRemap maps a value from one number line to a corresponding value on
// another number line.
// Example:
//  LinearRemap linear_remap(0, 1, 5, 10);
//  EXPECT_EQ(5.0f, linear_remap.Map(0));
//  EXPECT_EQ(7.5f, linear_remap.Map(.5));
//  EXPECT_EQ(10.f, linear_remap.Map(1));
class LinearRemap {
 public:
  LinearRemap(double amin, double amax, double bmin, double bmax)
      : amin_(amin), amax_(amax), bmin_(bmin), bmax_(bmax) {
    DCHECK_NE(amax_, amin_);
  }

  // Maps the value from the number line [amin,amax] to [bmin,bmax]. For
  // example:
  //   Map(amin) -> bmin.
  //   Map(amax) -> bmax.
  //   Map((amax+amin)/2) -> (bmax+bmin)/2.
  double Map(double value) const {
    value -= amin_;
    value *= (bmax_ - bmin_);
    value /= (amax_ - amin_);
    value += bmin_;
    return value;
  }

 private:
  const double amin_, amax_, bmin_, bmax_;
};

math::Size ExpandTextureSizeToContain(const int64_t num_pixels) {
  // Iterate through to find size to contain number of pixels.
  math::Size texture_size(1, 1);
  bool toggle = false;

  // Expand the texture by powers of two until the specific number of pixels
  // is contained.
  while (texture_size.GetArea() < num_pixels) {
    if (!toggle) {
      texture_size.set_width(texture_size.width() * 2);
    } else {
      texture_size.set_height(texture_size.height() * 2);
    }
    toggle = !toggle;
  }
  return texture_size;
}

}  // namespace

int64_t CalculateImageCacheSize(const math::Size& dimensions) {
  const double display_scale = DisplayScaleTo1080p(dimensions);
  static const int64_t kReferenceSize1080p = 32 * 1024 * 1024;
  double output_bytes = kReferenceSize1080p * display_scale;

  return math::Clamp<int64_t>(static_cast<int64_t>(output_bytes),
                              kMinImageCacheSize, kMaxImageCacheSize);
}

TextureDimensions CalculateSkiaGlyphAtlasTextureSize(
    const math::Size& ui_resolution) {
  // LinearRemap defines a mapping function which will map the number
  // of ui_resolution pixels to the number of texture atlas pixels such that:
  // 1080p (1920x1080) => maps to => 2048x2048 texture atlas pixels
  // 4k    (3840x2160) => maps to => 8192x4096 texture atlas pixels
  LinearRemap remap(1920 * 1080, 3840 * 2160, 2048 * 2048, 4096 * 8192);

  // Apply mapping.
  const int num_ui_pixels = ui_resolution.GetArea();
  const int64_t num_atlas_pixels =
      static_cast<int64_t>(remap.Map(num_ui_pixels));

  // Texture atlas sizes are generated in powers of two. This function will
  // produce such a texture.
  math::Size atlas_texture = ExpandTextureSizeToContain(num_atlas_pixels);

  // Clamp the atlas texture to be within a minimum range.
  math::Size clamped_atlas_texture(
      std::max<int>(kMinSkiaGlyphTextureAtlasWidth, atlas_texture.width()),
      std::max<int>(kMinSkiaGlyphTextureAtlasWidth, atlas_texture.height()));

  TextureDimensions texture_dimensions(clamped_atlas_texture.width(),
                                       clamped_atlas_texture.height(),
                                       kSkiaGlyphAtlasTextureBytesPerPixel);
  return texture_dimensions;
}

int64_t CalculateSoftwareSurfaceCacheSizeInBytes(
    const math::Size& ui_resolution) {
  // LinearRemap defines a mapping function which will map the number
  // of ui_resolution pixels to the number of surface texture cache such:
  // 720p (1280x720)   => maps to => 4MB &
  // 1080p (1920x1080) => maps to => 9MB
  LinearRemap remap(1280 * 720, 1920 * 1080, 4 * 1024 * 1024, 9 * 1024 * 1024);

  int64_t surface_cache_size_in_bytes =
      static_cast<int64_t>(remap.Map(ui_resolution.GetArea()));

  return surface_cache_size_in_bytes;
}

int64_t CalculateOffscreenTargetCacheSizeInBytes(
    const math::Size& ui_resolution) {
  // The offscreen target cache size should be at least half the ui_resolution
  // rounded to the nearest power of 2.
  int width = NearestPowerOf2(ui_resolution.width());
  int height = NearestPowerOf2(ui_resolution.height());

  // The surface cache uses RGBA format so requires 4 bytes per pixel.
  return (width * height / 2) * 4;
}

int64_t CalculateSkiaCacheSize(const math::Size& ui_resolution) {
  // This is normalized return 4MB @ 1080p and scales accordingly.
  LinearRemap remap(0, 1920 * 1080, 0, 4 * 1024 * 1024);
  int64_t output = static_cast<int64_t>(remap.Map(ui_resolution.GetArea()));
  return std::max<int64_t>(output, kMinSkiaCacheSize);
}

int64_t CalculateMiscCobaltGpuSize(const math::Size& ui_resolution) {
  // LinearRemap defines a mapping function which will map the number
  // of ui_resolution pixels to the misc memory of the GPU. This mapping
  // is linear such that:
  // 1080p (1920x1080) => maps to => 24MB
  LinearRemap remap(0, 1920 * 1080, 0, 24 * 1024 * 1024);

  return static_cast<int64_t>(remap.Map(ui_resolution.GetArea()));
}

}  // namespace memory_settings
}  // namespace browser
}  // namespace cobalt
