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 #include <stddef.h>
6
7 #include "components/viz/common/resources/resource_sizes.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9
10 namespace viz {
11 namespace {
12
13 struct TestFormat {
14 ResourceFormat format;
15 size_t expected_bytes;
16 size_t expected_bytes_aligned;
17 };
18
19 // Modify this constant as per TestFormat variables defined in following tests.
20 const int kTestFormats = 4;
21
22 class ResourceUtilTest : public testing::Test {
23 public:
TestVerifyWidthInBytes(int width,const TestFormat * test_formats)24 void TestVerifyWidthInBytes(int width, const TestFormat* test_formats) {
25 for (int i = 0; i < kTestFormats; ++i) {
26 EXPECT_TRUE(ResourceSizes::VerifyWidthInBytes<size_t>(
27 width, test_formats[i].format));
28 }
29 }
30
TestCheckedWidthInBytes(int width,const TestFormat * test_formats)31 void TestCheckedWidthInBytes(int width, const TestFormat* test_formats) {
32 for (int i = 0; i < kTestFormats; ++i) {
33 size_t bytes = ResourceSizes::CheckedWidthInBytes<size_t>(
34 width, test_formats[i].format);
35 EXPECT_EQ(bytes, test_formats[i].expected_bytes);
36 }
37 }
38
TestUncheckedWidthInBytes(int width,const TestFormat * test_formats)39 void TestUncheckedWidthInBytes(int width, const TestFormat* test_formats) {
40 for (int i = 0; i < kTestFormats; ++i) {
41 size_t bytes = ResourceSizes::UncheckedWidthInBytes<size_t>(
42 width, test_formats[i].format);
43 EXPECT_EQ(bytes, test_formats[i].expected_bytes);
44 }
45 }
46
TestUncheckedWidthInBytesAligned(int width,const TestFormat * test_formats)47 void TestUncheckedWidthInBytesAligned(int width,
48 const TestFormat* test_formats) {
49 for (int i = 0; i < kTestFormats; ++i) {
50 size_t bytes = ResourceSizes::UncheckedWidthInBytesAligned<size_t>(
51 width, test_formats[i].format);
52 EXPECT_EQ(bytes, test_formats[i].expected_bytes_aligned);
53 }
54 }
55
TestVerifySizeInBytes(const gfx::Size & size,const TestFormat * test_formats)56 void TestVerifySizeInBytes(const gfx::Size& size,
57 const TestFormat* test_formats) {
58 for (int i = 0; i < kTestFormats; ++i) {
59 EXPECT_TRUE(ResourceSizes::VerifySizeInBytes<size_t>(
60 size, test_formats[i].format));
61 }
62 }
63
TestCheckedSizeInBytes(const gfx::Size & size,const TestFormat * test_formats)64 void TestCheckedSizeInBytes(const gfx::Size& size,
65 const TestFormat* test_formats) {
66 for (int i = 0; i < kTestFormats; ++i) {
67 size_t bytes = ResourceSizes::CheckedSizeInBytes<size_t>(
68 size, test_formats[i].format);
69 EXPECT_EQ(bytes, test_formats[i].expected_bytes);
70 }
71 }
72
TestUncheckedSizeInBytes(const gfx::Size & size,const TestFormat * test_formats)73 void TestUncheckedSizeInBytes(const gfx::Size& size,
74 const TestFormat* test_formats) {
75 for (int i = 0; i < kTestFormats; ++i) {
76 size_t bytes = ResourceSizes::UncheckedSizeInBytes<size_t>(
77 size, test_formats[i].format);
78 EXPECT_EQ(bytes, test_formats[i].expected_bytes);
79 }
80 }
81
TestUncheckedSizeInBytesAligned(const gfx::Size & size,const TestFormat * test_formats)82 void TestUncheckedSizeInBytesAligned(const gfx::Size& size,
83 const TestFormat* test_formats) {
84 for (int i = 0; i < kTestFormats; ++i) {
85 size_t bytes = ResourceSizes::UncheckedSizeInBytesAligned<size_t>(
86 size, test_formats[i].format);
87 EXPECT_EQ(bytes, test_formats[i].expected_bytes_aligned);
88 }
89 }
90 };
91
TEST_F(ResourceUtilTest,WidthInBytes)92 TEST_F(ResourceUtilTest, WidthInBytes) {
93 // Check bytes for even width.
94 int width = 10;
95 TestFormat test_formats[] = {
96 {RGBA_8888, 40, 40}, // for 32 bits
97 {RGBA_4444, 20, 20}, // for 16 bits
98 {ALPHA_8, 10, 12}, // for 8 bits
99 {ETC1, 5, 8} // for 4 bits
100 };
101
102 TestVerifyWidthInBytes(width, test_formats);
103 TestCheckedWidthInBytes(width, test_formats);
104 TestUncheckedWidthInBytes(width, test_formats);
105 TestUncheckedWidthInBytesAligned(width, test_formats);
106
107 // Check bytes for odd width.
108 int width_odd = 11;
109 TestFormat test_formats_odd[] = {
110 {RGBA_8888, 44, 44}, // for 32 bits
111 {RGBA_4444, 22, 24}, // for 16 bits
112 {ALPHA_8, 11, 12}, // for 8 bits
113 {ETC1, 6, 8} // for 4 bits
114 };
115
116 TestVerifyWidthInBytes(width_odd, test_formats_odd);
117 TestCheckedWidthInBytes(width_odd, test_formats_odd);
118 TestUncheckedWidthInBytes(width_odd, test_formats_odd);
119 TestUncheckedWidthInBytesAligned(width_odd, test_formats_odd);
120 }
121
TEST_F(ResourceUtilTest,SizeInBytes)122 TEST_F(ResourceUtilTest, SizeInBytes) {
123 // Check bytes for even size.
124 gfx::Size size(10, 10);
125 TestFormat test_formats[] = {
126 {RGBA_8888, 400, 400}, // for 32 bits
127 {RGBA_4444, 200, 200}, // for 16 bits
128 {ALPHA_8, 100, 120}, // for 8 bits
129 {ETC1, 50, 80} // for 4 bits
130 };
131
132 TestVerifySizeInBytes(size, test_formats);
133 TestCheckedSizeInBytes(size, test_formats);
134 TestUncheckedSizeInBytes(size, test_formats);
135 TestUncheckedSizeInBytesAligned(size, test_formats);
136
137 // Check bytes for odd size.
138 gfx::Size size_odd(11, 11);
139 TestFormat test_formats_odd[] = {
140 {RGBA_8888, 484, 484}, // for 32 bits
141 {RGBA_4444, 242, 264}, // for 16 bits
142 {ALPHA_8, 121, 132}, // for 8 bits
143 {ETC1, 66, 88} // for 4 bits
144 };
145
146 TestVerifySizeInBytes(size_odd, test_formats_odd);
147 TestCheckedSizeInBytes(size_odd, test_formats_odd);
148 TestUncheckedSizeInBytes(size_odd, test_formats_odd);
149 TestUncheckedSizeInBytesAligned(size_odd, test_formats_odd);
150 }
151
TEST_F(ResourceUtilTest,WidthInBytesOverflow)152 TEST_F(ResourceUtilTest, WidthInBytesOverflow) {
153 int width = 10;
154 // 10 * 16 = 160 bits, overflows in char, but fits in unsigned char.
155 EXPECT_FALSE(
156 ResourceSizes::VerifyWidthInBytes<signed char>(width, RGBA_4444));
157 EXPECT_TRUE(
158 ResourceSizes::VerifyWidthInBytes<unsigned char>(width, RGBA_4444));
159 }
160
TEST_F(ResourceUtilTest,SizeInBytesOverflow)161 TEST_F(ResourceUtilTest, SizeInBytesOverflow) {
162 gfx::Size size(10, 10);
163 // 10 * 16 * 10 = 1600 bits, overflows in char, but fits in int.
164 EXPECT_FALSE(ResourceSizes::VerifySizeInBytes<signed char>(size, RGBA_4444));
165 EXPECT_TRUE(ResourceSizes::VerifySizeInBytes<int>(size, RGBA_4444));
166 }
167
TEST_F(ResourceUtilTest,WidthOverflowDoesNotCrash)168 TEST_F(ResourceUtilTest, WidthOverflowDoesNotCrash) {
169 gfx::Size size(0x20000000, 1);
170 // 0x20000000 * 4 = 0x80000000 which overflows int. Should return false, not
171 // crash.
172 int bytes;
173 EXPECT_FALSE(
174 ResourceSizes::MaybeWidthInBytes<int>(size.width(), BGRA_8888, &bytes));
175 EXPECT_FALSE(ResourceSizes::MaybeSizeInBytes<int>(size, BGRA_8888, &bytes));
176 }
177
178 // Checks that we do not incorrectly indicate that a size has overflowed when
179 // only the size in bits overflows, but not the size in bytes.
TEST_F(ResourceUtilTest,SizeInBitsOverflowBytesOk)180 TEST_F(ResourceUtilTest, SizeInBitsOverflowBytesOk) {
181 gfx::Size size(10000, 10000);
182 // 8192 * 8192 * 32 = 0x80000000, overflows int.
183 // Bytes are /8 and do not overflow.
184 EXPECT_TRUE(ResourceSizes::VerifySizeInBytes<int>(size, BGRA_8888));
185 }
186
187 // Checks that we correctly identify overflow in cases caused by rounding.
TEST_F(ResourceUtilTest,RoundingOverflows)188 TEST_F(ResourceUtilTest, RoundingOverflows) {
189 gfx::Size size(0x1FFFFFFF, 1);
190 // 0x1FFFFFFF * 4 = 0x7FFFFFFC. Will overflow when rounded up.
191 EXPECT_FALSE(ResourceSizes::VerifySizeInBytes<int>(size, ETC1));
192 }
193
194 } // namespace
195 } // namespace viz
196