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 |