// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_RESOURCES_RESOURCE_UTIL_H_
#define CC_RESOURCES_RESOURCE_UTIL_H_

#include <stddef.h>

#include <limits>

#include "base/macros.h"
#include "base/numerics/safe_math.h"
#include "cc/base/math_util.h"
#include "cc/cc_export.h"
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "ui/gfx/geometry/size.h"

namespace cc {

class CC_EXPORT ResourceUtil {
 public:
  // Returns true if the width is valid and fits in bytes, false otherwise.
  template <typename T>
  static bool VerifyWidthInBytes(int width, viz::ResourceFormat format);
  // Returns true if the size is valid and fits in bytes, false otherwise.
  template <typename T>
  static bool VerifySizeInBytes(const gfx::Size& size,
                                viz::ResourceFormat format);

  // Dies with a CRASH() if the width can not be represented as a positive
  // number of bytes.
  template <typename T>
  static T CheckedWidthInBytes(int width, viz::ResourceFormat format);
  // Dies with a CRASH() if the size can not be represented as a positive
  // number of bytes.
  template <typename T>
  static T CheckedSizeInBytes(const gfx::Size& size,
                              viz::ResourceFormat format);

  // Returns the width in bytes but may overflow or return 0. Only do this for
  // computing widths for sizes that have already been checked.
  template <typename T>
  static T UncheckedWidthInBytes(int width, viz::ResourceFormat format);
  // Returns the size in bytes but may overflow or return 0. Only do this for
  // sizes that have already been checked.
  template <typename T>
  static T UncheckedSizeInBytes(const gfx::Size& size,
                                viz::ResourceFormat format);
  // Returns the width in bytes aligned but may overflow or return 0. Only do
  // this for computing widths for sizes that have already been checked.
  template <typename T>
  static T UncheckedWidthInBytesAligned(int width, viz::ResourceFormat format);
  // Returns the size in bytes aligned but may overflow or return 0. Only do
  // this for sizes that have already been checked.
  template <typename T>
  static T UncheckedSizeInBytesAligned(const gfx::Size& size,
                                       viz::ResourceFormat format);

 private:
  template <typename T>
  static inline void VerifyType();

  template <typename T>
  static bool VerifyFitsInBytesInternal(int width,
                                        int height,
                                        viz::ResourceFormat format,
                                        bool verify_size,
                                        bool aligned);

  template <typename T>
  static T BytesInternal(int width,
                         int height,
                         viz::ResourceFormat format,
                         bool verify_size,
                         bool aligned);

  DISALLOW_COPY_AND_ASSIGN(ResourceUtil);
};

template <typename T>
bool ResourceUtil::VerifyWidthInBytes(int width, viz::ResourceFormat format) {
  VerifyType<T>();
  return VerifyFitsInBytesInternal<T>(width, 0, format, false, false);
}

template <typename T>
bool ResourceUtil::VerifySizeInBytes(const gfx::Size& size,
                                     viz::ResourceFormat format) {
  VerifyType<T>();
  return VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
                                      false);
}

template <typename T>
T ResourceUtil::CheckedWidthInBytes(int width, viz::ResourceFormat format) {
  VerifyType<T>();
  DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false));
  base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
  checked_value *= width;
  checked_value = MathUtil::CheckedRoundUp<T>(checked_value.ValueOrDie(), 8);
  checked_value /= 8;
  return checked_value.ValueOrDie();
}

template <typename T>
T ResourceUtil::CheckedSizeInBytes(const gfx::Size& size,
                                   viz::ResourceFormat format) {
  VerifyType<T>();
  DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
                                      false));
  base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
  checked_value *= size.width();
  checked_value = MathUtil::CheckedRoundUp<T>(checked_value.ValueOrDie(), 8);
  checked_value /= 8;
  checked_value *= size.height();
  return checked_value.ValueOrDie();
}

template <typename T>
T ResourceUtil::UncheckedWidthInBytes(int width, viz::ResourceFormat format) {
  VerifyType<T>();
  DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false));
  return BytesInternal<T>(width, 0, format, false, false);
}

template <typename T>
T ResourceUtil::UncheckedSizeInBytes(const gfx::Size& size,
                                     viz::ResourceFormat format) {
  VerifyType<T>();
  DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
                                      false));
  return BytesInternal<T>(size.width(), size.height(), format, true, false);
}

template <typename T>
T ResourceUtil::UncheckedWidthInBytesAligned(int width,
                                             viz::ResourceFormat format) {
  VerifyType<T>();
  DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, true));
  return BytesInternal<T>(width, 0, format, false, true);
}

template <typename T>
T ResourceUtil::UncheckedSizeInBytesAligned(const gfx::Size& size,
                                            viz::ResourceFormat format) {
  VerifyType<T>();
  DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
                                      true));
  return BytesInternal<T>(size.width(), size.height(), format, true, true);
}

template <typename T>
void ResourceUtil::VerifyType() {
  static_assert(
      std::numeric_limits<T>::is_integer && !std::is_same<T, bool>::value,
      "T must be non-bool integer type. Preferred type is size_t.");
}

template <typename T>
bool ResourceUtil::VerifyFitsInBytesInternal(int width,
                                             int height,
                                             viz::ResourceFormat format,
                                             bool verify_size,
                                             bool aligned) {
  base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
  checked_value *= width;
  if (!checked_value.IsValid())
    return false;

  // Roundup bits to byte (8 bits) boundary. If width is 3 and BitsPerPixel is
  // 4, then it should return 16, so that row pixels do not get truncated.
  checked_value = MathUtil::UncheckedRoundUp<T>(checked_value.ValueOrDie(), 8);

  // If aligned is true, bytes are aligned on 4-bytes boundaries for upload
  // performance, assuming that GL_PACK_ALIGNMENT or GL_UNPACK_ALIGNMENT have
  // not changed from default.
  if (aligned) {
    checked_value /= 8;
    if (!checked_value.IsValid())
      return false;
    checked_value =
        MathUtil::UncheckedRoundUp<T>(checked_value.ValueOrDie(), 4);
    checked_value *= 8;
  }

  if (verify_size)
    checked_value *= height;
  if (!checked_value.IsValid())
    return false;
  T value = checked_value.ValueOrDie();
  if ((value % 8) != 0)
    return false;
  return true;
}

template <typename T>
T ResourceUtil::BytesInternal(int width,
                              int height,
                              viz::ResourceFormat format,
                              bool verify_size,
                              bool aligned) {
  T bytes = BitsPerPixel(format);
  bytes *= width;
  bytes = MathUtil::UncheckedRoundUp<T>(bytes, 8);
  bytes /= 8;
  if (aligned)
    bytes = MathUtil::UncheckedRoundUp<T>(bytes, 4);
  if (verify_size)
    bytes *= height;

  return bytes;
}

}  // namespace cc

#endif  // CC_RESOURCES_RESOURCE_UTIL_H_
