Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / cc / resources / resource_util.h
blob9d9905b47d5d8644a20472fd08eab8da2913ca21
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.
5 #ifndef CC_RESOURCES_RESOURCE_UTIL_H_
6 #define CC_RESOURCES_RESOURCE_UTIL_H_
8 #include <limits>
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"
16 namespace cc {
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);
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);
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);
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;
62 template <typename T>
63 struct IsSameType<T, T> {
64 static const bool value = true;
67 template <typename T>
68 static inline void VerifyType();
70 template <typename T>
71 static bool VerifyFitsInBytesInternal(int width,
72 int height,
73 ResourceFormat format,
74 bool verify_size,
75 bool aligned);
77 template <typename T>
78 static T BytesInternal(int width,
79 int height,
80 ResourceFormat format,
81 bool verify_size,
82 bool aligned);
84 DISALLOW_COPY_AND_ASSIGN(ResourceUtil);
87 template <typename T>
88 bool ResourceUtil::VerifyWidthInBytes(int width, ResourceFormat format) {
89 VerifyType<T>();
90 return VerifyFitsInBytesInternal<T>(width, 0, format, false, false);
93 template <typename T>
94 bool ResourceUtil::VerifySizeInBytes(const gfx::Size& size,
95 ResourceFormat format) {
96 VerifyType<T>();
97 return VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
98 false);
101 template <typename T>
102 T ResourceUtil::CheckedWidthInBytes(int width, ResourceFormat format) {
103 VerifyType<T>();
104 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false));
105 base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
106 checked_value *= width;
107 checked_value = MathUtil::CheckedRoundUp<T>(checked_value.ValueOrDie(), 8);
108 checked_value /= 8;
109 return checked_value.ValueOrDie();
112 template <typename T>
113 T ResourceUtil::CheckedSizeInBytes(const gfx::Size& size,
114 ResourceFormat format) {
115 VerifyType<T>();
116 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
117 false));
118 base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
119 checked_value *= size.width();
120 checked_value = MathUtil::CheckedRoundUp<T>(checked_value.ValueOrDie(), 8);
121 checked_value /= 8;
122 checked_value *= size.height();
123 return checked_value.ValueOrDie();
126 template <typename T>
127 T ResourceUtil::UncheckedWidthInBytes(int width, ResourceFormat format) {
128 VerifyType<T>();
129 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, false));
130 return BytesInternal<T>(width, 0, format, false, false);
133 template <typename T>
134 T ResourceUtil::UncheckedSizeInBytes(const gfx::Size& size,
135 ResourceFormat format) {
136 VerifyType<T>();
137 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
138 false));
139 return BytesInternal<T>(size.width(), size.height(), format, true, false);
142 template <typename T>
143 T ResourceUtil::UncheckedWidthInBytesAligned(int width, ResourceFormat format) {
144 VerifyType<T>();
145 DCHECK(VerifyFitsInBytesInternal<T>(width, 0, format, false, true));
146 return BytesInternal<T>(width, 0, format, false, true);
149 template <typename T>
150 T ResourceUtil::UncheckedSizeInBytesAligned(const gfx::Size& size,
151 ResourceFormat format) {
152 VerifyType<T>();
153 DCHECK(VerifyFitsInBytesInternal<T>(size.width(), size.height(), format, true,
154 true));
155 return BytesInternal<T>(size.width(), size.height(), format, true, true);
158 template <typename T>
159 void ResourceUtil::VerifyType() {
160 static_assert(
161 std::numeric_limits<T>::is_integer && !IsSameType<T, bool>::value,
162 "T must be non-bool integer type. Preferred type is size_t.");
165 template <typename T>
166 bool ResourceUtil::VerifyFitsInBytesInternal(int width,
167 int height,
168 ResourceFormat format,
169 bool verify_size,
170 bool aligned) {
171 base::CheckedNumeric<T> checked_value = BitsPerPixel(format);
172 checked_value *= width;
173 if (!checked_value.IsValid())
174 return false;
176 // Roundup bits to byte (8 bits) boundary. If width is 3 and BitsPerPixel is
177 // 4, then it should return 16, so that row pixels do not get truncated.
178 checked_value = MathUtil::UncheckedRoundUp<T>(checked_value.ValueOrDie(), 8);
180 // If aligned is true, bytes are aligned on 4-bytes boundaries for upload
181 // performance, assuming that GL_PACK_ALIGNMENT or GL_UNPACK_ALIGNMENT have
182 // not changed from default.
183 if (aligned) {
184 checked_value /= 8;
185 if (!checked_value.IsValid())
186 return false;
187 checked_value =
188 MathUtil::UncheckedRoundUp<T>(checked_value.ValueOrDie(), 4);
189 checked_value *= 8;
192 if (verify_size)
193 checked_value *= height;
194 if (!checked_value.IsValid())
195 return false;
196 T value = checked_value.ValueOrDie();
197 if ((value % 8) != 0)
198 return false;
199 return true;
202 template <typename T>
203 T ResourceUtil::BytesInternal(int width,
204 int height,
205 ResourceFormat format,
206 bool verify_size,
207 bool aligned) {
208 T bytes = BitsPerPixel(format);
209 bytes *= width;
210 bytes = MathUtil::UncheckedRoundUp<T>(bytes, 8);
211 bytes /= 8;
212 if (aligned)
213 bytes = MathUtil::UncheckedRoundUp<T>(bytes, 4);
214 if (verify_size)
215 bytes *= height;
217 return bytes;
220 } // namespace cc
222 #endif // CC_RESOURCES_RESOURCE_UTIL_H_