| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CC_RESOURCES_RESOURCE_UTIL_H_ | 5 #ifndef CC_RESOURCES_RESOURCE_UTIL_H_ |
| 6 #define CC_RESOURCES_RESOURCE_UTIL_H_ | 6 #define CC_RESOURCES_RESOURCE_UTIL_H_ |
| 7 | 7 |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/numerics/safe_math.h" | 10 #include "base/numerics/safe_math.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 template <typename T> | 62 template <typename T> |
| 63 struct IsSameType<T, T> { | 63 struct IsSameType<T, T> { |
| 64 static const bool value = true; | 64 static const bool value = true; |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 template <typename T> | 67 template <typename T> |
| 68 static inline void VerifyType(); | 68 static inline void VerifyType(); |
| 69 | 69 |
| 70 template <typename T> | 70 template <typename T> |
| 71 static bool VerifyRoundUp(T value, T round_up); | |
| 72 | |
| 73 template <typename T> | |
| 74 static bool VerifyFitsInBytesInternal(int width, | 71 static bool VerifyFitsInBytesInternal(int width, |
| 75 int height, | 72 int height, |
| 76 ResourceFormat format, | 73 ResourceFormat format, |
| 77 bool verify_size, | 74 bool verify_size, |
| 78 bool aligned); | 75 bool aligned); |
| 79 | 76 |
| 80 template <typename T> | 77 template <typename T> |
| 81 static T BytesInternal(int width, | 78 static T BytesInternal(int width, |
| 82 int height, | 79 int height, |
| 83 ResourceFormat format, | 80 ResourceFormat format, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 100 return VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | 97 return VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, |
| 101 false); | 98 false); |
| 102 } | 99 } |
| 103 | 100 |
| 104 template <typename T> | 101 template <typename T> |
| 105 T ResourceUtil::CheckedWidthInBytes(int width, ResourceFormat format) { | 102 T ResourceUtil::CheckedWidthInBytes(int width, ResourceFormat format) { |
| 106 VerifyType<T>(); | 103 VerifyType<T>(); |
| 107 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false)); | 104 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false)); |
| 108 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | 105 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); |
| 109 checked_value *= width; | 106 checked_value *= width; |
| 110 // TODO(prashant.n): Move the value roundup overflow to MathUtil class. | 107 checked_value = MathUtil::CheckedRoundUp<T>(checked_value.ValueOrDie(), 8); |
| 111 // http://crbug.com/515566 | |
| 112 CHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8))); | |
| 113 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
| 114 checked_value /= 8; | 108 checked_value /= 8; |
| 115 return checked_value.ValueOrDie(); | 109 return checked_value.ValueOrDie(); |
| 116 } | 110 } |
| 117 | 111 |
| 118 template <typename T> | 112 template <typename T> |
| 119 T ResourceUtil::CheckedSizeInBytes(const gfx::Size& size, | 113 T ResourceUtil::CheckedSizeInBytes(const gfx::Size& size, |
| 120 ResourceFormat format) { | 114 ResourceFormat format) { |
| 121 VerifyType<T>(); | 115 VerifyType<T>(); |
| 122 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | 116 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, |
| 123 false)); | 117 false)); |
| 124 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | 118 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); |
| 125 checked_value *= size.width(); | 119 checked_value *= size.width(); |
| 126 CHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8))); | 120 checked_value = MathUtil::CheckedRoundUp<T>(checked_value.ValueOrDie(), 8); |
| 127 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
| 128 checked_value /= 8; | 121 checked_value /= 8; |
| 129 checked_value *= size.height(); | 122 checked_value *= size.height(); |
| 130 return checked_value.ValueOrDie(); | 123 return checked_value.ValueOrDie(); |
| 131 } | 124 } |
| 132 | 125 |
| 133 template <typename T> | 126 template <typename T> |
| 134 T ResourceUtil::UncheckedWidthInBytes(int width, ResourceFormat format) { | 127 T ResourceUtil::UncheckedWidthInBytes(int width, ResourceFormat format) { |
| 135 VerifyType<T>(); | 128 VerifyType<T>(); |
| 136 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false)); | 129 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false)); |
| 137 return BytesInternal<T>(width, 0, format, false, false); | 130 return BytesInternal<T>(width, 0, format, false, false); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 163 } | 156 } |
| 164 | 157 |
| 165 template <typename T> | 158 template <typename T> |
| 166 void ResourceUtil::VerifyType() { | 159 void ResourceUtil::VerifyType() { |
| 167 static_assert( | 160 static_assert( |
| 168 std::numeric_limits<T>::is_integer && !IsSameType<T, bool>::value, | 161 std::numeric_limits<T>::is_integer && !IsSameType<T, bool>::value, |
| 169 "T must be non-bool integer type. Preferred type is size_t."); | 162 "T must be non-bool integer type. Preferred type is size_t."); |
| 170 } | 163 } |
| 171 | 164 |
| 172 template <typename T> | 165 template <typename T> |
| 173 bool ResourceUtil::VerifyRoundUp(T value, T round_up) { | |
| 174 if (round_up == 0) | |
| 175 return false; | |
| 176 if (value == round_up) | |
| 177 return true; | |
| 178 if ((std::numeric_limits<T>::max() - (value - (value % round_up))) >= | |
| 179 round_up) | |
| 180 return true; | |
| 181 return false; | |
| 182 } | |
| 183 | |
| 184 template <typename T> | |
| 185 bool ResourceUtil::VerifyFitsInBytesInternal(int width, | 166 bool ResourceUtil::VerifyFitsInBytesInternal(int width, |
| 186 int height, | 167 int height, |
| 187 ResourceFormat format, | 168 ResourceFormat format, |
| 188 bool verify_size, | 169 bool verify_size, |
| 189 bool aligned) { | 170 bool aligned) { |
| 190 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | 171 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); |
| 191 checked_value *= width; | 172 checked_value *= width; |
| 192 if (!checked_value.IsValid()) | 173 if (!checked_value.IsValid()) |
| 193 return false; | 174 return false; |
| 194 | 175 |
| 195 // Roundup bits to byte (8 bits) boundary. If width is 3 and BitsPerPixel is | 176 // Roundup bits to byte (8 bits) boundary. If width is 3 and BitsPerPixel is |
| 196 // 4, then it should return 16, so that row pixels do not get truncated. | 177 // 4, then it should return 16, so that row pixels do not get truncated. |
| 197 DCHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8))); | 178 checked_value = MathUtil::UncheckedRoundUp<T>(checked_value.ValueOrDie(), 8); |
| 198 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
| 199 | 179 |
| 200 // If aligned is true, bytes are aligned on 4-bytes boundaries for upload | 180 // If aligned is true, bytes are aligned on 4-bytes boundaries for upload |
| 201 // performance, assuming that GL_PACK_ALIGNMENT or GL_UNPACK_ALIGNMENT have | 181 // performance, assuming that GL_PACK_ALIGNMENT or GL_UNPACK_ALIGNMENT have |
| 202 // not changed from default. | 182 // not changed from default. |
| 203 if (aligned) { | 183 if (aligned) { |
| 204 checked_value /= 8; | 184 checked_value /= 8; |
| 205 if (!checked_value.IsValid()) | 185 if (!checked_value.IsValid()) |
| 206 return false; | 186 return false; |
| 207 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 4); | 187 checked_value = |
| 188 MathUtil::UncheckedRoundUp<T>(checked_value.ValueOrDie(), 4); |
| 208 checked_value *= 8; | 189 checked_value *= 8; |
| 209 } | 190 } |
| 210 | 191 |
| 211 if (verify_size) | 192 if (verify_size) |
| 212 checked_value *= height; | 193 checked_value *= height; |
| 213 if (!checked_value.IsValid()) | 194 if (!checked_value.IsValid()) |
| 214 return false; | 195 return false; |
| 215 T value = checked_value.ValueOrDie(); | 196 T value = checked_value.ValueOrDie(); |
| 216 if ((value % 8) != 0) | 197 if ((value % 8) != 0) |
| 217 return false; | 198 return false; |
| 218 return true; | 199 return true; |
| 219 } | 200 } |
| 220 | 201 |
| 221 template <typename T> | 202 template <typename T> |
| 222 T ResourceUtil::BytesInternal(int width, | 203 T ResourceUtil::BytesInternal(int width, |
| 223 int height, | 204 int height, |
| 224 ResourceFormat format, | 205 ResourceFormat format, |
| 225 bool verify_size, | 206 bool verify_size, |
| 226 bool aligned) { | 207 bool aligned) { |
| 227 T bytes = BitsPerPixel(format); | 208 T bytes = BitsPerPixel(format); |
| 228 bytes *= width; | 209 bytes *= width; |
| 229 DCHECK(VerifyRoundUp(bytes, static_cast<T>(8))); | 210 bytes = MathUtil::UncheckedRoundUp<T>(bytes, 8); |
| 230 bytes = MathUtil::RoundUp<T>(bytes, 8); | |
| 231 bytes /= 8; | 211 bytes /= 8; |
| 232 if (aligned) | 212 if (aligned) |
| 233 bytes = MathUtil::RoundUp<T>(bytes, 4); | 213 bytes = MathUtil::UncheckedRoundUp<T>(bytes, 4); |
| 234 if (verify_size) | 214 if (verify_size) |
| 235 bytes *= height; | 215 bytes *= height; |
| 236 | 216 |
| 237 return bytes; | 217 return bytes; |
| 238 } | 218 } |
| 239 | 219 |
| 240 } // namespace cc | 220 } // namespace cc |
| 241 | 221 |
| 242 #endif // CC_RESOURCES_RESOURCE_UTIL_H_ | 222 #endif // CC_RESOURCES_RESOURCE_UTIL_H_ |
| OLD | NEW |