Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CC_RESOURCES_RESOURCE_UTIL_H_ | |
| 6 #define CC_RESOURCES_RESOURCE_UTIL_H_ | |
| 7 | |
| 8 #include <limits> | |
| 9 | |
| 10 #include "base/numerics/safe_math.h" | |
| 11 #include "cc/base/cc_export.h" | |
| 12 #include "cc/base/math_util.h" | |
| 13 #include "cc/resources/resource_format.h" | |
| 14 #include "ui/gfx/geometry/size.h" | |
| 15 | |
| 16 #define VERIFY_INTEGER_TYPE \ | |
|
ericrk
2015/07/29 18:19:24
This should be undefined at the end of the file to
enne (OOO)
2015/07/29 18:21:21
Yeah, I'd prefer not having a #define in a header
prashant.n
2015/07/30 18:45:02
1. Removed macro.
2. Moving functions in .cc woul
| |
| 17 static_assert(std::numeric_limits<T>::is_integer, \ | |
| 18 "T must be an integer type. Preferred type is size_t.") | |
| 19 | |
| 20 namespace cc { | |
| 21 | |
| 22 class CC_EXPORT ResourceUtil { | |
| 23 public: | |
| 24 // Returns true if the width is valid and fits in bytes, false otherwise. | |
| 25 template <typename T> | |
| 26 static bool VerifyWidthInBytes(int width, ResourceFormat format); | |
| 27 // Returns true if the size is valid and fits in bytes, false otherwise. | |
| 28 template <typename T> | |
| 29 static bool VerifySizeInBytes(const gfx::Size& size, ResourceFormat format); | |
| 30 | |
| 31 // Dies with a CRASH() if the size can not be represented as a positive | |
| 32 // number of bytes. | |
| 33 template <typename T> | |
| 34 static T CheckedSizeInBytes(const gfx::Size& size, ResourceFormat format); | |
| 35 | |
| 36 // Returns the width in bytes but may overflow or return 0. Only do this for | |
| 37 // computing widths for sizes that have already been checked. | |
| 38 template <typename T> | |
| 39 static T UncheckedWidthInBytes(int width, ResourceFormat format); | |
| 40 // Returns the size in bytes but may overflow or return 0. Only do this for | |
| 41 // sizes that have already been checked. | |
| 42 template <typename T> | |
| 43 static T UncheckedSizeInBytes(const gfx::Size& size, ResourceFormat format); | |
| 44 // Returns the width in bytes aligned but may overflow or return 0. Only do | |
| 45 // this for computing widths for sizes that have already been checked. | |
| 46 template <typename T> | |
| 47 static T UncheckedWidthInBytesAligned(int width, ResourceFormat format); | |
| 48 // Returns the size in bytes aligned but may overflow or return 0. Only do | |
| 49 // this for sizes that have already been checked. | |
| 50 template <typename T> | |
| 51 static T UncheckedSizeInBytesAligned(const gfx::Size& size, | |
| 52 ResourceFormat format); | |
| 53 | |
| 54 private: | |
| 55 template <typename T> | |
| 56 static bool VerifyFitsInBytesInternal(int width, | |
| 57 int height, | |
| 58 ResourceFormat format, | |
| 59 bool verify_size, | |
| 60 bool aligned); | |
| 61 | |
| 62 template <typename T> | |
| 63 static T BytesInternal(int width, | |
| 64 int height, | |
| 65 ResourceFormat format, | |
| 66 bool verify_size, | |
| 67 bool aligned); | |
| 68 | |
| 69 DISALLOW_COPY_AND_ASSIGN(ResourceUtil); | |
| 70 }; | |
| 71 | |
| 72 template <typename T> | |
| 73 bool ResourceUtil::VerifyWidthInBytes(int width, ResourceFormat format) { | |
| 74 VERIFY_INTEGER_TYPE; | |
| 75 return VerifyFitsInBytesInternal<T>(width, 0, format, false, false); | |
| 76 } | |
| 77 | |
| 78 template <typename T> | |
| 79 bool ResourceUtil::VerifySizeInBytes(const gfx::Size& size, | |
| 80 ResourceFormat format) { | |
| 81 VERIFY_INTEGER_TYPE; | |
| 82 return VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
| 83 false); | |
| 84 } | |
| 85 | |
| 86 template <typename T> | |
| 87 T ResourceUtil::CheckedSizeInBytes(const gfx::Size& size, | |
| 88 ResourceFormat format) { | |
| 89 VERIFY_INTEGER_TYPE; | |
| 90 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
| 91 false)); | |
| 92 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | |
| 93 checked_value *= size.width(); | |
| 94 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
|
prashant.n
2015/07/28 15:47:32
Need to ensure that width is integral value.
If B
ericrk
2015/07/29 18:19:24
If we were within 8 of MAX_INT, RoundUp could over
prashant.n
2015/07/30 18:45:02
Handled and TODO added.
| |
| 95 checked_value /= 8; | |
| 96 checked_value *= size.height(); | |
| 97 return checked_value.ValueOrDie(); | |
| 98 } | |
| 99 | |
| 100 template <typename T> | |
| 101 T ResourceUtil::UncheckedWidthInBytes(int width, ResourceFormat format) { | |
| 102 VERIFY_INTEGER_TYPE; | |
| 103 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false)); | |
| 104 return BytesInternal<T>(width, 0, format, false, false); | |
| 105 } | |
| 106 | |
| 107 template <typename T> | |
| 108 T ResourceUtil::UncheckedSizeInBytes(const gfx::Size& size, | |
| 109 ResourceFormat format) { | |
| 110 VERIFY_INTEGER_TYPE; | |
| 111 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
| 112 false)); | |
| 113 return BytesInternal<T>(size.width(), size.height(), format, true, false); | |
| 114 } | |
| 115 | |
| 116 template <typename T> | |
| 117 T ResourceUtil::UncheckedWidthInBytesAligned(int width, ResourceFormat format) { | |
| 118 VERIFY_INTEGER_TYPE; | |
| 119 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, true)); | |
| 120 return BytesInternal<T>(width, 0, format, false, true); | |
| 121 } | |
| 122 | |
| 123 template <typename T> | |
| 124 T ResourceUtil::UncheckedSizeInBytesAligned(const gfx::Size& size, | |
| 125 ResourceFormat format) { | |
| 126 VERIFY_INTEGER_TYPE; | |
| 127 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
| 128 true)); | |
| 129 return BytesInternal<T>(size.width(), size.height(), format, true, true); | |
| 130 } | |
| 131 | |
| 132 template <typename T> | |
| 133 bool ResourceUtil::VerifyFitsInBytesInternal(int width, | |
| 134 int height, | |
| 135 ResourceFormat format, | |
| 136 bool verify_size, | |
| 137 bool aligned) { | |
| 138 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | |
| 139 checked_value *= width; | |
| 140 if (!checked_value.IsValid()) | |
| 141 return false; | |
| 142 | |
| 143 // Roundup bits to byte (8 bits) boundary. If width is 3 and BitsPerPixel is | |
| 144 // 4, then it should return 16, so that row pixels do not get truncated. | |
| 145 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
|
ericrk
2015/07/29 18:19:24
same as above
| |
| 146 | |
| 147 // If aligned is true, bytes are aligned on 4-bytes boundaries for upload | |
| 148 // performance, assuming that GL_PACK_ALIGNMENT or GL_UNPACK_ALIGNMENT have | |
| 149 // not changed from default. | |
| 150 if (aligned) { | |
| 151 checked_value /= 8; | |
| 152 if (!checked_value.IsValid()) | |
| 153 return false; | |
| 154 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 4); | |
| 155 } | |
| 156 | |
| 157 if (verify_size) | |
| 158 checked_value *= height; | |
| 159 if (!checked_value.IsValid()) | |
| 160 return false; | |
| 161 T value = checked_value.ValueOrDie(); | |
| 162 if ((value % 8) != 0) | |
| 163 return false; | |
| 164 return true; | |
| 165 } | |
| 166 | |
| 167 template <typename T> | |
| 168 T ResourceUtil::BytesInternal(int width, | |
| 169 int height, | |
| 170 ResourceFormat format, | |
| 171 bool verify_size, | |
| 172 bool aligned) { | |
| 173 T bytes = BitsPerPixel(format); | |
| 174 bytes *= width; | |
| 175 bytes = MathUtil::RoundUp<T>(bytes, 8); | |
| 176 bytes /= 8; | |
| 177 if (aligned) | |
| 178 bytes = MathUtil::RoundUp<T>(bytes, 4); | |
| 179 if (verify_size) | |
| 180 bytes *= height; | |
| 181 | |
| 182 return bytes; | |
| 183 } | |
| 184 | |
| 185 } // namespace cc | |
| 186 | |
| 187 #endif // CC_RESOURCES_RESOURCE_UTIL_H_ | |
| OLD | NEW |