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 namespace cc { | |
17 | |
18 class CC_EXPORT ResourceUtil { | |
19 public: | |
20 // Returns true if the width is valid and fits in bytes, false otherwise. | |
21 template <typename T> | |
22 static bool VerifyWidthInBytes(int width, ResourceFormat format); | |
23 // Returns true if the size is valid and fits in bytes, false otherwise. | |
24 template <typename T> | |
25 static bool VerifySizeInBytes(const gfx::Size& size, ResourceFormat format); | |
26 | |
27 // Dies with a CRASH() if the width can not be represented as a positive | |
28 // number of bytes. | |
29 template <typename T> | |
30 static T CheckedWidthInBytes(int width, ResourceFormat format); | |
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 inline void VerifyType(); | |
57 | |
58 template <typename T> | |
59 static bool VerifyRoundUp(T value, T round_up); | |
60 | |
61 template <typename T> | |
62 static bool VerifyFitsInBytesInternal(int width, | |
63 int height, | |
64 ResourceFormat format, | |
65 bool verify_size, | |
66 bool aligned); | |
67 | |
68 template <typename T> | |
69 static T BytesInternal(int width, | |
70 int height, | |
71 ResourceFormat format, | |
72 bool verify_size, | |
73 bool aligned); | |
74 | |
75 DISALLOW_COPY_AND_ASSIGN(ResourceUtil); | |
76 }; | |
77 | |
78 template <typename T> | |
79 bool ResourceUtil::VerifyWidthInBytes(int width, ResourceFormat format) { | |
80 VerifyType<T>(); | |
81 return VerifyFitsInBytesInternal<T>(width, 0, format, false, false); | |
82 } | |
83 | |
84 template <typename T> | |
85 bool ResourceUtil::VerifySizeInBytes(const gfx::Size& size, | |
86 ResourceFormat format) { | |
87 VerifyType<T>(); | |
88 return VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
89 false); | |
90 } | |
91 | |
92 template <typename T> | |
93 T ResourceUtil::CheckedWidthInBytes(int width, ResourceFormat format) { | |
94 VerifyType<T>(); | |
95 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false)); | |
96 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | |
97 checked_value *= width; | |
98 // TODO(prashant.n): Move the value roundup overflow to MathUtil class. | |
99 // http://crbug.com/515566 | |
100 CHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8))); | |
101 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
102 checked_value /= 8; | |
103 return checked_value.ValueOrDie(); | |
104 } | |
105 | |
106 template <typename T> | |
107 T ResourceUtil::CheckedSizeInBytes(const gfx::Size& size, | |
108 ResourceFormat format) { | |
109 VerifyType<T>(); | |
110 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
111 false)); | |
112 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | |
113 checked_value *= size.width(); | |
114 CHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8))); | |
115 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
116 checked_value /= 8; | |
117 checked_value *= size.height(); | |
118 return checked_value.ValueOrDie(); | |
119 } | |
120 | |
121 template <typename T> | |
122 T ResourceUtil::UncheckedWidthInBytes(int width, ResourceFormat format) { | |
123 VerifyType<T>(); | |
124 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false)); | |
125 return BytesInternal<T>(width, 0, format, false, false); | |
126 } | |
127 | |
128 template <typename T> | |
129 T ResourceUtil::UncheckedSizeInBytes(const gfx::Size& size, | |
130 ResourceFormat format) { | |
131 VerifyType<T>(); | |
132 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
133 false)); | |
134 return BytesInternal<T>(size.width(), size.height(), format, true, false); | |
135 } | |
136 | |
137 template <typename T> | |
138 T ResourceUtil::UncheckedWidthInBytesAligned(int width, ResourceFormat format) { | |
139 VerifyType<T>(); | |
140 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, true)); | |
141 return BytesInternal<T>(width, 0, format, false, true); | |
142 } | |
143 | |
144 template <typename T> | |
145 T ResourceUtil::UncheckedSizeInBytesAligned(const gfx::Size& size, | |
146 ResourceFormat format) { | |
147 VerifyType<T>(); | |
148 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true, | |
149 true)); | |
150 return BytesInternal<T>(size.width(), size.height(), format, true, true); | |
151 } | |
152 | |
153 template <typename T> | |
154 void ResourceUtil::VerifyType() { | |
155 static_assert( | |
156 std::numeric_limits<T>::is_integer && !std::is_same<T, bool>::value, | |
vmpstr
2015/07/30 20:50:58
std::is_same is a c++11 library feature, which we
| |
157 "T must be non-bool integer type. Preferred type is size_t."); | |
158 } | |
159 | |
160 template <typename T> | |
161 bool ResourceUtil::VerifyRoundUp(T value, T round_up) { | |
162 if (round_up == 0) | |
163 return false; | |
164 if (value == round_up) | |
165 return true; | |
166 if ((std::numeric_limits<T>::max() - (value - (value % round_up))) >= | |
167 round_up) | |
168 return true; | |
169 return false; | |
170 } | |
171 | |
172 template <typename T> | |
173 bool ResourceUtil::VerifyFitsInBytesInternal(int width, | |
174 int height, | |
175 ResourceFormat format, | |
176 bool verify_size, | |
177 bool aligned) { | |
178 base::CheckedNumeric<T> checked_value = BitsPerPixel(format); | |
179 checked_value *= width; | |
180 if (!checked_value.IsValid()) | |
181 return false; | |
182 | |
183 // Roundup bits to byte (8 bits) boundary. If width is 3 and BitsPerPixel is | |
184 // 4, then it should return 16, so that row pixels do not get truncated. | |
185 DCHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8))); | |
186 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8); | |
187 | |
188 // If aligned is true, bytes are aligned on 4-bytes boundaries for upload | |
189 // performance, assuming that GL_PACK_ALIGNMENT or GL_UNPACK_ALIGNMENT have | |
190 // not changed from default. | |
191 if (aligned) { | |
192 checked_value /= 8; | |
193 if (!checked_value.IsValid()) | |
194 return false; | |
195 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 4); | |
196 checked_value *= 8; | |
197 } | |
198 | |
199 if (verify_size) | |
200 checked_value *= height; | |
201 if (!checked_value.IsValid()) | |
202 return false; | |
203 T value = checked_value.ValueOrDie(); | |
204 if ((value % 8) != 0) | |
205 return false; | |
206 return true; | |
207 } | |
208 | |
209 template <typename T> | |
210 T ResourceUtil::BytesInternal(int width, | |
211 int height, | |
212 ResourceFormat format, | |
213 bool verify_size, | |
214 bool aligned) { | |
215 T bytes = BitsPerPixel(format); | |
216 bytes *= width; | |
217 DCHECK(VerifyRoundUp(bytes, static_cast<T>(8))); | |
218 bytes = MathUtil::RoundUp<T>(bytes, 8); | |
219 bytes /= 8; | |
220 if (aligned) | |
221 bytes = MathUtil::RoundUp<T>(bytes, 4); | |
222 if (verify_size) | |
223 bytes *= height; | |
224 | |
225 return bytes; | |
226 } | |
227 | |
228 } // namespace cc | |
229 | |
230 #endif // CC_RESOURCES_RESOURCE_UTIL_H_ | |
OLD | NEW |