Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: cc/resources/resource_util.h

Issue 1202843008: cc: Fix BytesPerPixel issue and refactor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed Android build break. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/resources/resource_provider.cc ('k') | cc/resources/resource_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 // TODO(prashant.n): Replace IsSameType with std::is_same once C++11 is used
56 // on all platforms.
57 template <typename T, typename U>
58 struct IsSameType {
59 static const bool value = false;
60 };
61
62 template <typename T>
63 struct IsSameType<T, T> {
64 static const bool value = true;
65 };
66
67 template <typename T>
68 static inline void VerifyType();
69
70 template <typename T>
71 static bool VerifyRoundUp(T value, T round_up);
72
73 template <typename T>
74 static bool VerifyFitsInBytesInternal(int width,
75 int height,
76 ResourceFormat format,
77 bool verify_size,
78 bool aligned);
79
80 template <typename T>
81 static T BytesInternal(int width,
82 int height,
83 ResourceFormat format,
84 bool verify_size,
85 bool aligned);
86
87 DISALLOW_COPY_AND_ASSIGN(ResourceUtil);
88 };
89
90 template <typename T>
91 bool ResourceUtil::VerifyWidthInBytes(int width, ResourceFormat format) {
92 VerifyType<T>();
93 return VerifyFitsInBytesInternal<T>(width, 0, format, false, false);
94 }
95
96 template <typename T>
97 bool ResourceUtil::VerifySizeInBytes(const gfx::Size& size,
98 ResourceFormat format) {
99 VerifyType<T>();
100 return VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
101 false);
102 }
103
104 template <typename T>
105 T ResourceUtil::CheckedWidthInBytes(int width, ResourceFormat format) {
106 VerifyType<T>();
107 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false));
108 base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
109 checked_value *= width;
110 // TODO(prashant.n): Move the value roundup overflow to MathUtil class.
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;
115 return checked_value.ValueOrDie();
116 }
117
118 template <typename T>
119 T ResourceUtil::CheckedSizeInBytes(const gfx::Size& size,
120 ResourceFormat format) {
121 VerifyType<T>();
122 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
123 false));
124 base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
125 checked_value *= size.width();
126 CHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8)));
127 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8);
128 checked_value /= 8;
129 checked_value *= size.height();
130 return checked_value.ValueOrDie();
131 }
132
133 template <typename T>
134 T ResourceUtil::UncheckedWidthInBytes(int width, ResourceFormat format) {
135 VerifyType<T>();
136 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false));
137 return BytesInternal<T>(width, 0, format, false, false);
138 }
139
140 template <typename T>
141 T ResourceUtil::UncheckedSizeInBytes(const gfx::Size& size,
142 ResourceFormat format) {
143 VerifyType<T>();
144 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
145 false));
146 return BytesInternal<T>(size.width(), size.height(), format, true, false);
147 }
148
149 template <typename T>
150 T ResourceUtil::UncheckedWidthInBytesAligned(int width, ResourceFormat format) {
151 VerifyType<T>();
152 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, true));
153 return BytesInternal<T>(width, 0, format, false, true);
154 }
155
156 template <typename T>
157 T ResourceUtil::UncheckedSizeInBytesAligned(const gfx::Size& size,
158 ResourceFormat format) {
159 VerifyType<T>();
160 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
161 true));
162 return BytesInternal<T>(size.width(), size.height(), format, true, true);
163 }
164
165 template <typename T>
166 void ResourceUtil::VerifyType() {
167 static_assert(
168 std::numeric_limits<T>::is_integer && !IsSameType<T, bool>::value,
169 "T must be non-bool integer type. Preferred type is size_t.");
170 }
171
172 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,
186 int height,
187 ResourceFormat format,
188 bool verify_size,
189 bool aligned) {
190 base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
191 checked_value *= width;
192 if (!checked_value.IsValid())
193 return false;
194
195 // 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.
197 DCHECK(VerifyRoundUp(checked_value.ValueOrDie(), static_cast<T>(8)));
198 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 8);
199
200 // 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
202 // not changed from default.
203 if (aligned) {
204 checked_value /= 8;
205 if (!checked_value.IsValid())
206 return false;
207 checked_value = MathUtil::RoundUp<T>(checked_value.ValueOrDie(), 4);
208 checked_value *= 8;
209 }
210
211 if (verify_size)
212 checked_value *= height;
213 if (!checked_value.IsValid())
214 return false;
215 T value = checked_value.ValueOrDie();
216 if ((value % 8) != 0)
217 return false;
218 return true;
219 }
220
221 template <typename T>
222 T ResourceUtil::BytesInternal(int width,
223 int height,
224 ResourceFormat format,
225 bool verify_size,
226 bool aligned) {
227 T bytes = BitsPerPixel(format);
228 bytes *= width;
229 DCHECK(VerifyRoundUp(bytes, static_cast<T>(8)));
230 bytes = MathUtil::RoundUp<T>(bytes, 8);
231 bytes /= 8;
232 if (aligned)
233 bytes = MathUtil::RoundUp<T>(bytes, 4);
234 if (verify_size)
235 bytes *= height;
236
237 return bytes;
238 }
239
240 } // namespace cc
241
242 #endif // CC_RESOURCES_RESOURCE_UTIL_H_
OLDNEW
« no previous file with comments | « cc/resources/resource_provider.cc ('k') | cc/resources/resource_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698