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 |