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_
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"
18 class CC_EXPORT ResourceUtil
{
20 // Returns true if the width is valid and fits in bytes, false otherwise.
22 static bool VerifyWidthInBytes(int width
, ResourceFormat format
);
23 // Returns true if the size is valid and fits in bytes, false otherwise.
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
30 static T
CheckedWidthInBytes(int width
, ResourceFormat format
);
31 // Dies with a CRASH() if the size can not be represented as a positive
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.
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.
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.
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.
51 static T
UncheckedSizeInBytesAligned(const gfx::Size
& size
,
52 ResourceFormat format
);
55 // TODO(prashant.n): Replace IsSameType with std::is_same once C++11 is used
57 template <typename T
, typename U
>
59 static const bool value
= false;
63 struct IsSameType
<T
, T
> {
64 static const bool value
= true;
68 static inline void VerifyType();
71 static bool VerifyFitsInBytesInternal(int width
,
73 ResourceFormat format
,
78 static T
BytesInternal(int width
,
80 ResourceFormat format
,
84 DISALLOW_COPY_AND_ASSIGN(ResourceUtil
);
88 bool ResourceUtil::VerifyWidthInBytes(int width
, ResourceFormat format
) {
90 return VerifyFitsInBytesInternal
<T
>(width
, 0, format
, false, false);
94 bool ResourceUtil::VerifySizeInBytes(const gfx::Size
& size
,
95 ResourceFormat format
) {
97 return VerifyFitsInBytesInternal
<T
>(size
.width(), size
.height(), format
, true,
101 template <typename T
>
102 T
ResourceUtil::CheckedWidthInBytes(int width
, ResourceFormat format
) {
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);
109 return checked_value
.ValueOrDie();
112 template <typename T
>
113 T
ResourceUtil::CheckedSizeInBytes(const gfx::Size
& size
,
114 ResourceFormat format
) {
116 DCHECK(VerifyFitsInBytesInternal
<T
>(size
.width(), size
.height(), format
, true,
118 base::CheckedNumeric
<T
> checked_value
= BitsPerPixel(format
);
119 checked_value
*= size
.width();
120 checked_value
= MathUtil::CheckedRoundUp
<T
>(checked_value
.ValueOrDie(), 8);
122 checked_value
*= size
.height();
123 return checked_value
.ValueOrDie();
126 template <typename T
>
127 T
ResourceUtil::UncheckedWidthInBytes(int width
, ResourceFormat format
) {
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
) {
137 DCHECK(VerifyFitsInBytesInternal
<T
>(size
.width(), size
.height(), format
, true,
139 return BytesInternal
<T
>(size
.width(), size
.height(), format
, true, false);
142 template <typename T
>
143 T
ResourceUtil::UncheckedWidthInBytesAligned(int width
, ResourceFormat format
) {
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
) {
153 DCHECK(VerifyFitsInBytesInternal
<T
>(size
.width(), size
.height(), format
, true,
155 return BytesInternal
<T
>(size
.width(), size
.height(), format
, true, true);
158 template <typename T
>
159 void ResourceUtil::VerifyType() {
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
,
168 ResourceFormat format
,
171 base::CheckedNumeric
<T
> checked_value
= BitsPerPixel(format
);
172 checked_value
*= width
;
173 if (!checked_value
.IsValid())
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.
185 if (!checked_value
.IsValid())
188 MathUtil::UncheckedRoundUp
<T
>(checked_value
.ValueOrDie(), 4);
193 checked_value
*= height
;
194 if (!checked_value
.IsValid())
196 T value
= checked_value
.ValueOrDie();
197 if ((value
% 8) != 0)
202 template <typename T
>
203 T
ResourceUtil::BytesInternal(int width
,
205 ResourceFormat format
,
208 T bytes
= BitsPerPixel(format
);
210 bytes
= MathUtil::UncheckedRoundUp
<T
>(bytes
, 8);
213 bytes
= MathUtil::UncheckedRoundUp
<T
>(bytes
, 4);
222 #endif // CC_RESOURCES_RESOURCE_UTIL_H_