|
1 /* |
|
2 * Copyright 2011 The LibYuv Project Authors. All rights reserved. |
|
3 * |
|
4 * Use of this source code is governed by a BSD-style license |
|
5 * that can be found in the LICENSE file in the root of the source |
|
6 * tree. An additional intellectual property rights grant can be found |
|
7 * in the file PATENTS. All contributing project authors may |
|
8 * be found in the AUTHORS file in the root of the source tree. |
|
9 */ |
|
10 |
|
11 #include <stdlib.h> |
|
12 #include <time.h> |
|
13 |
|
14 #include "libyuv/compare.h" |
|
15 #include "libyuv/convert.h" |
|
16 #include "libyuv/convert_argb.h" |
|
17 #include "libyuv/convert_from.h" |
|
18 #include "libyuv/convert_from_argb.h" |
|
19 #include "libyuv/cpu_id.h" |
|
20 #include "libyuv/format_conversion.h" |
|
21 #include "libyuv/planar_functions.h" |
|
22 #include "libyuv/rotate.h" |
|
23 #include "libyuv/row.h" // For Sobel |
|
24 #include "../unit_test/unit_test.h" |
|
25 |
|
26 #if defined(_MSC_VER) |
|
27 #define SIMD_ALIGNED(var) __declspec(align(16)) var |
|
28 #else // __GNUC__ |
|
29 #define SIMD_ALIGNED(var) var __attribute__((aligned(16))) |
|
30 #endif |
|
31 |
|
32 namespace libyuv { |
|
33 |
|
34 TEST_F(libyuvTest, TestAttenuate) { |
|
35 const int kSize = 1280 * 4; |
|
36 align_buffer_64(orig_pixels, kSize); |
|
37 align_buffer_64(atten_pixels, kSize); |
|
38 align_buffer_64(unatten_pixels, kSize); |
|
39 align_buffer_64(atten2_pixels, kSize); |
|
40 |
|
41 // Test unattenuation clamps |
|
42 orig_pixels[0 * 4 + 0] = 200u; |
|
43 orig_pixels[0 * 4 + 1] = 129u; |
|
44 orig_pixels[0 * 4 + 2] = 127u; |
|
45 orig_pixels[0 * 4 + 3] = 128u; |
|
46 // Test unattenuation transparent and opaque are unaffected |
|
47 orig_pixels[1 * 4 + 0] = 16u; |
|
48 orig_pixels[1 * 4 + 1] = 64u; |
|
49 orig_pixels[1 * 4 + 2] = 192u; |
|
50 orig_pixels[1 * 4 + 3] = 0u; |
|
51 orig_pixels[2 * 4 + 0] = 16u; |
|
52 orig_pixels[2 * 4 + 1] = 64u; |
|
53 orig_pixels[2 * 4 + 2] = 192u; |
|
54 orig_pixels[2 * 4 + 3] = 255u; |
|
55 orig_pixels[3 * 4 + 0] = 16u; |
|
56 orig_pixels[3 * 4 + 1] = 64u; |
|
57 orig_pixels[3 * 4 + 2] = 192u; |
|
58 orig_pixels[3 * 4 + 3] = 128u; |
|
59 ARGBUnattenuate(orig_pixels, 0, unatten_pixels, 0, 4, 1); |
|
60 EXPECT_EQ(255u, unatten_pixels[0 * 4 + 0]); |
|
61 EXPECT_EQ(255u, unatten_pixels[0 * 4 + 1]); |
|
62 EXPECT_EQ(254u, unatten_pixels[0 * 4 + 2]); |
|
63 EXPECT_EQ(128u, unatten_pixels[0 * 4 + 3]); |
|
64 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 0]); |
|
65 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 1]); |
|
66 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 2]); |
|
67 EXPECT_EQ(0u, unatten_pixels[1 * 4 + 3]); |
|
68 EXPECT_EQ(16u, unatten_pixels[2 * 4 + 0]); |
|
69 EXPECT_EQ(64u, unatten_pixels[2 * 4 + 1]); |
|
70 EXPECT_EQ(192u, unatten_pixels[2 * 4 + 2]); |
|
71 EXPECT_EQ(255u, unatten_pixels[2 * 4 + 3]); |
|
72 EXPECT_EQ(32u, unatten_pixels[3 * 4 + 0]); |
|
73 EXPECT_EQ(128u, unatten_pixels[3 * 4 + 1]); |
|
74 EXPECT_EQ(255u, unatten_pixels[3 * 4 + 2]); |
|
75 EXPECT_EQ(128u, unatten_pixels[3 * 4 + 3]); |
|
76 |
|
77 for (int i = 0; i < 1280; ++i) { |
|
78 orig_pixels[i * 4 + 0] = i; |
|
79 orig_pixels[i * 4 + 1] = i / 2; |
|
80 orig_pixels[i * 4 + 2] = i / 3; |
|
81 orig_pixels[i * 4 + 3] = i; |
|
82 } |
|
83 ARGBAttenuate(orig_pixels, 0, atten_pixels, 0, 1280, 1); |
|
84 ARGBUnattenuate(atten_pixels, 0, unatten_pixels, 0, 1280, 1); |
|
85 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
86 ARGBAttenuate(unatten_pixels, 0, atten2_pixels, 0, 1280, 1); |
|
87 } |
|
88 for (int i = 0; i < 1280; ++i) { |
|
89 EXPECT_NEAR(atten_pixels[i * 4 + 0], atten2_pixels[i * 4 + 0], 2); |
|
90 EXPECT_NEAR(atten_pixels[i * 4 + 1], atten2_pixels[i * 4 + 1], 2); |
|
91 EXPECT_NEAR(atten_pixels[i * 4 + 2], atten2_pixels[i * 4 + 2], 2); |
|
92 EXPECT_NEAR(atten_pixels[i * 4 + 3], atten2_pixels[i * 4 + 3], 2); |
|
93 } |
|
94 // Make sure transparent, 50% and opaque are fully accurate. |
|
95 EXPECT_EQ(0, atten_pixels[0 * 4 + 0]); |
|
96 EXPECT_EQ(0, atten_pixels[0 * 4 + 1]); |
|
97 EXPECT_EQ(0, atten_pixels[0 * 4 + 2]); |
|
98 EXPECT_EQ(0, atten_pixels[0 * 4 + 3]); |
|
99 EXPECT_EQ(64, atten_pixels[128 * 4 + 0]); |
|
100 EXPECT_EQ(32, atten_pixels[128 * 4 + 1]); |
|
101 EXPECT_EQ(21, atten_pixels[128 * 4 + 2]); |
|
102 EXPECT_EQ(128, atten_pixels[128 * 4 + 3]); |
|
103 EXPECT_NEAR(255, atten_pixels[255 * 4 + 0], 1); |
|
104 EXPECT_NEAR(127, atten_pixels[255 * 4 + 1], 1); |
|
105 EXPECT_NEAR(85, atten_pixels[255 * 4 + 2], 1); |
|
106 EXPECT_EQ(255, atten_pixels[255 * 4 + 3]); |
|
107 |
|
108 free_aligned_buffer_64(atten2_pixels); |
|
109 free_aligned_buffer_64(unatten_pixels); |
|
110 free_aligned_buffer_64(atten_pixels); |
|
111 free_aligned_buffer_64(orig_pixels); |
|
112 } |
|
113 |
|
114 static int TestAttenuateI(int width, int height, int benchmark_iterations, |
|
115 int invert, int off) { |
|
116 if (width < 1) { |
|
117 width = 1; |
|
118 } |
|
119 const int kBpp = 4; |
|
120 const int kStride = (width * kBpp + 15) & ~15; |
|
121 align_buffer_64(src_argb, kStride * height + off); |
|
122 align_buffer_64(dst_argb_c, kStride * height); |
|
123 align_buffer_64(dst_argb_opt, kStride * height); |
|
124 srandom(time(NULL)); |
|
125 for (int i = 0; i < kStride * height; ++i) { |
|
126 src_argb[i + off] = (random() & 0xff); |
|
127 } |
|
128 memset(dst_argb_c, 0, kStride * height); |
|
129 memset(dst_argb_opt, 0, kStride * height); |
|
130 |
|
131 MaskCpuFlags(0); |
|
132 ARGBAttenuate(src_argb + off, kStride, |
|
133 dst_argb_c, kStride, |
|
134 width, invert * height); |
|
135 MaskCpuFlags(-1); |
|
136 for (int i = 0; i < benchmark_iterations; ++i) { |
|
137 ARGBAttenuate(src_argb + off, kStride, |
|
138 dst_argb_opt, kStride, |
|
139 width, invert * height); |
|
140 } |
|
141 int max_diff = 0; |
|
142 for (int i = 0; i < kStride * height; ++i) { |
|
143 int abs_diff = |
|
144 abs(static_cast<int>(dst_argb_c[i]) - |
|
145 static_cast<int>(dst_argb_opt[i])); |
|
146 if (abs_diff > max_diff) { |
|
147 max_diff = abs_diff; |
|
148 } |
|
149 } |
|
150 free_aligned_buffer_64(src_argb); |
|
151 free_aligned_buffer_64(dst_argb_c); |
|
152 free_aligned_buffer_64(dst_argb_opt); |
|
153 return max_diff; |
|
154 } |
|
155 |
|
156 TEST_F(libyuvTest, ARGBAttenuate_Any) { |
|
157 int max_diff = TestAttenuateI(benchmark_width_ - 1, benchmark_height_, |
|
158 benchmark_iterations_, +1, 0); |
|
159 EXPECT_LE(max_diff, 2); |
|
160 } |
|
161 |
|
162 TEST_F(libyuvTest, ARGBAttenuate_Unaligned) { |
|
163 int max_diff = TestAttenuateI(benchmark_width_, benchmark_height_, |
|
164 benchmark_iterations_, +1, 1); |
|
165 EXPECT_LE(max_diff, 2); |
|
166 } |
|
167 |
|
168 TEST_F(libyuvTest, ARGBAttenuate_Invert) { |
|
169 int max_diff = TestAttenuateI(benchmark_width_, benchmark_height_, |
|
170 benchmark_iterations_, -1, 0); |
|
171 EXPECT_LE(max_diff, 2); |
|
172 } |
|
173 |
|
174 TEST_F(libyuvTest, ARGBAttenuate_Opt) { |
|
175 int max_diff = TestAttenuateI(benchmark_width_, benchmark_height_, |
|
176 benchmark_iterations_, +1, 0); |
|
177 EXPECT_LE(max_diff, 2); |
|
178 } |
|
179 |
|
180 static int TestUnattenuateI(int width, int height, int benchmark_iterations, |
|
181 int invert, int off) { |
|
182 if (width < 1) { |
|
183 width = 1; |
|
184 } |
|
185 const int kBpp = 4; |
|
186 const int kStride = (width * kBpp + 15) & ~15; |
|
187 align_buffer_64(src_argb, kStride * height + off); |
|
188 align_buffer_64(dst_argb_c, kStride * height); |
|
189 align_buffer_64(dst_argb_opt, kStride * height); |
|
190 srandom(time(NULL)); |
|
191 for (int i = 0; i < kStride * height; ++i) { |
|
192 src_argb[i + off] = (random() & 0xff); |
|
193 } |
|
194 ARGBAttenuate(src_argb + off, kStride, |
|
195 src_argb + off, kStride, |
|
196 width, height); |
|
197 memset(dst_argb_c, 0, kStride * height); |
|
198 memset(dst_argb_opt, 0, kStride * height); |
|
199 |
|
200 MaskCpuFlags(0); |
|
201 ARGBUnattenuate(src_argb + off, kStride, |
|
202 dst_argb_c, kStride, |
|
203 width, invert * height); |
|
204 MaskCpuFlags(-1); |
|
205 for (int i = 0; i < benchmark_iterations; ++i) { |
|
206 ARGBUnattenuate(src_argb + off, kStride, |
|
207 dst_argb_opt, kStride, |
|
208 width, invert * height); |
|
209 } |
|
210 int max_diff = 0; |
|
211 for (int i = 0; i < kStride * height; ++i) { |
|
212 int abs_diff = |
|
213 abs(static_cast<int>(dst_argb_c[i]) - |
|
214 static_cast<int>(dst_argb_opt[i])); |
|
215 if (abs_diff > max_diff) { |
|
216 max_diff = abs_diff; |
|
217 } |
|
218 } |
|
219 free_aligned_buffer_64(src_argb); |
|
220 free_aligned_buffer_64(dst_argb_c); |
|
221 free_aligned_buffer_64(dst_argb_opt); |
|
222 return max_diff; |
|
223 } |
|
224 |
|
225 TEST_F(libyuvTest, ARGBUnattenuate_Any) { |
|
226 int max_diff = TestUnattenuateI(benchmark_width_ - 1, benchmark_height_, |
|
227 benchmark_iterations_, +1, 0); |
|
228 EXPECT_LE(max_diff, 2); |
|
229 } |
|
230 |
|
231 TEST_F(libyuvTest, ARGBUnattenuate_Unaligned) { |
|
232 int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_, |
|
233 benchmark_iterations_, +1, 1); |
|
234 EXPECT_LE(max_diff, 2); |
|
235 } |
|
236 |
|
237 TEST_F(libyuvTest, ARGBUnattenuate_Invert) { |
|
238 int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_, |
|
239 benchmark_iterations_, -1, 0); |
|
240 EXPECT_LE(max_diff, 2); |
|
241 } |
|
242 |
|
243 TEST_F(libyuvTest, ARGBUnattenuate_Opt) { |
|
244 int max_diff = TestUnattenuateI(benchmark_width_, benchmark_height_, |
|
245 benchmark_iterations_, +1, 0); |
|
246 EXPECT_LE(max_diff, 2); |
|
247 } |
|
248 |
|
249 TEST_F(libyuvTest, TestARGBComputeCumulativeSum) { |
|
250 SIMD_ALIGNED(uint8 orig_pixels[16][16][4]); |
|
251 SIMD_ALIGNED(int32 added_pixels[16][16][4]); |
|
252 |
|
253 for (int y = 0; y < 16; ++y) { |
|
254 for (int x = 0; x < 16; ++x) { |
|
255 orig_pixels[y][x][0] = 1u; |
|
256 orig_pixels[y][x][1] = 2u; |
|
257 orig_pixels[y][x][2] = 3u; |
|
258 orig_pixels[y][x][3] = 255u; |
|
259 } |
|
260 } |
|
261 |
|
262 ARGBComputeCumulativeSum(&orig_pixels[0][0][0], 16 * 4, |
|
263 &added_pixels[0][0][0], 16 * 4, |
|
264 16, 16); |
|
265 |
|
266 for (int y = 0; y < 16; ++y) { |
|
267 for (int x = 0; x < 16; ++x) { |
|
268 EXPECT_EQ((x + 1) * (y + 1), added_pixels[y][x][0]); |
|
269 EXPECT_EQ((x + 1) * (y + 1) * 2, added_pixels[y][x][1]); |
|
270 EXPECT_EQ((x + 1) * (y + 1) * 3, added_pixels[y][x][2]); |
|
271 EXPECT_EQ((x + 1) * (y + 1) * 255, added_pixels[y][x][3]); |
|
272 } |
|
273 } |
|
274 } |
|
275 |
|
276 TEST_F(libyuvTest, TestARGBGray) { |
|
277 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
278 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
279 |
|
280 // Test blue |
|
281 orig_pixels[0][0] = 255u; |
|
282 orig_pixels[0][1] = 0u; |
|
283 orig_pixels[0][2] = 0u; |
|
284 orig_pixels[0][3] = 128u; |
|
285 // Test green |
|
286 orig_pixels[1][0] = 0u; |
|
287 orig_pixels[1][1] = 255u; |
|
288 orig_pixels[1][2] = 0u; |
|
289 orig_pixels[1][3] = 0u; |
|
290 // Test red |
|
291 orig_pixels[2][0] = 0u; |
|
292 orig_pixels[2][1] = 0u; |
|
293 orig_pixels[2][2] = 255u; |
|
294 orig_pixels[2][3] = 255u; |
|
295 // Test black |
|
296 orig_pixels[3][0] = 0u; |
|
297 orig_pixels[3][1] = 0u; |
|
298 orig_pixels[3][2] = 0u; |
|
299 orig_pixels[3][3] = 255u; |
|
300 // Test white |
|
301 orig_pixels[4][0] = 255u; |
|
302 orig_pixels[4][1] = 255u; |
|
303 orig_pixels[4][2] = 255u; |
|
304 orig_pixels[4][3] = 255u; |
|
305 // Test color |
|
306 orig_pixels[5][0] = 16u; |
|
307 orig_pixels[5][1] = 64u; |
|
308 orig_pixels[5][2] = 192u; |
|
309 orig_pixels[5][3] = 224u; |
|
310 // Do 16 to test asm version. |
|
311 ARGBGray(&orig_pixels[0][0], 0, 0, 0, 16, 1); |
|
312 EXPECT_EQ(30u, orig_pixels[0][0]); |
|
313 EXPECT_EQ(30u, orig_pixels[0][1]); |
|
314 EXPECT_EQ(30u, orig_pixels[0][2]); |
|
315 EXPECT_EQ(128u, orig_pixels[0][3]); |
|
316 EXPECT_EQ(149u, orig_pixels[1][0]); |
|
317 EXPECT_EQ(149u, orig_pixels[1][1]); |
|
318 EXPECT_EQ(149u, orig_pixels[1][2]); |
|
319 EXPECT_EQ(0u, orig_pixels[1][3]); |
|
320 EXPECT_EQ(76u, orig_pixels[2][0]); |
|
321 EXPECT_EQ(76u, orig_pixels[2][1]); |
|
322 EXPECT_EQ(76u, orig_pixels[2][2]); |
|
323 EXPECT_EQ(255u, orig_pixels[2][3]); |
|
324 EXPECT_EQ(0u, orig_pixels[3][0]); |
|
325 EXPECT_EQ(0u, orig_pixels[3][1]); |
|
326 EXPECT_EQ(0u, orig_pixels[3][2]); |
|
327 EXPECT_EQ(255u, orig_pixels[3][3]); |
|
328 EXPECT_EQ(255u, orig_pixels[4][0]); |
|
329 EXPECT_EQ(255u, orig_pixels[4][1]); |
|
330 EXPECT_EQ(255u, orig_pixels[4][2]); |
|
331 EXPECT_EQ(255u, orig_pixels[4][3]); |
|
332 EXPECT_EQ(96u, orig_pixels[5][0]); |
|
333 EXPECT_EQ(96u, orig_pixels[5][1]); |
|
334 EXPECT_EQ(96u, orig_pixels[5][2]); |
|
335 EXPECT_EQ(224u, orig_pixels[5][3]); |
|
336 for (int i = 0; i < 1280; ++i) { |
|
337 orig_pixels[i][0] = i; |
|
338 orig_pixels[i][1] = i / 2; |
|
339 orig_pixels[i][2] = i / 3; |
|
340 orig_pixels[i][3] = i; |
|
341 } |
|
342 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
343 ARGBGray(&orig_pixels[0][0], 0, 0, 0, 1280, 1); |
|
344 } |
|
345 } |
|
346 |
|
347 TEST_F(libyuvTest, TestARGBGrayTo) { |
|
348 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
349 SIMD_ALIGNED(uint8 gray_pixels[1280][4]); |
|
350 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
351 |
|
352 // Test blue |
|
353 orig_pixels[0][0] = 255u; |
|
354 orig_pixels[0][1] = 0u; |
|
355 orig_pixels[0][2] = 0u; |
|
356 orig_pixels[0][3] = 128u; |
|
357 // Test green |
|
358 orig_pixels[1][0] = 0u; |
|
359 orig_pixels[1][1] = 255u; |
|
360 orig_pixels[1][2] = 0u; |
|
361 orig_pixels[1][3] = 0u; |
|
362 // Test red |
|
363 orig_pixels[2][0] = 0u; |
|
364 orig_pixels[2][1] = 0u; |
|
365 orig_pixels[2][2] = 255u; |
|
366 orig_pixels[2][3] = 255u; |
|
367 // Test black |
|
368 orig_pixels[3][0] = 0u; |
|
369 orig_pixels[3][1] = 0u; |
|
370 orig_pixels[3][2] = 0u; |
|
371 orig_pixels[3][3] = 255u; |
|
372 // Test white |
|
373 orig_pixels[4][0] = 255u; |
|
374 orig_pixels[4][1] = 255u; |
|
375 orig_pixels[4][2] = 255u; |
|
376 orig_pixels[4][3] = 255u; |
|
377 // Test color |
|
378 orig_pixels[5][0] = 16u; |
|
379 orig_pixels[5][1] = 64u; |
|
380 orig_pixels[5][2] = 192u; |
|
381 orig_pixels[5][3] = 224u; |
|
382 // Do 16 to test asm version. |
|
383 ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 16, 1); |
|
384 EXPECT_EQ(30u, gray_pixels[0][0]); |
|
385 EXPECT_EQ(30u, gray_pixels[0][1]); |
|
386 EXPECT_EQ(30u, gray_pixels[0][2]); |
|
387 EXPECT_EQ(128u, gray_pixels[0][3]); |
|
388 EXPECT_EQ(149u, gray_pixels[1][0]); |
|
389 EXPECT_EQ(149u, gray_pixels[1][1]); |
|
390 EXPECT_EQ(149u, gray_pixels[1][2]); |
|
391 EXPECT_EQ(0u, gray_pixels[1][3]); |
|
392 EXPECT_EQ(76u, gray_pixels[2][0]); |
|
393 EXPECT_EQ(76u, gray_pixels[2][1]); |
|
394 EXPECT_EQ(76u, gray_pixels[2][2]); |
|
395 EXPECT_EQ(255u, gray_pixels[2][3]); |
|
396 EXPECT_EQ(0u, gray_pixels[3][0]); |
|
397 EXPECT_EQ(0u, gray_pixels[3][1]); |
|
398 EXPECT_EQ(0u, gray_pixels[3][2]); |
|
399 EXPECT_EQ(255u, gray_pixels[3][3]); |
|
400 EXPECT_EQ(255u, gray_pixels[4][0]); |
|
401 EXPECT_EQ(255u, gray_pixels[4][1]); |
|
402 EXPECT_EQ(255u, gray_pixels[4][2]); |
|
403 EXPECT_EQ(255u, gray_pixels[4][3]); |
|
404 EXPECT_EQ(96u, gray_pixels[5][0]); |
|
405 EXPECT_EQ(96u, gray_pixels[5][1]); |
|
406 EXPECT_EQ(96u, gray_pixels[5][2]); |
|
407 EXPECT_EQ(224u, gray_pixels[5][3]); |
|
408 for (int i = 0; i < 1280; ++i) { |
|
409 orig_pixels[i][0] = i; |
|
410 orig_pixels[i][1] = i / 2; |
|
411 orig_pixels[i][2] = i / 3; |
|
412 orig_pixels[i][3] = i; |
|
413 } |
|
414 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
415 ARGBGrayTo(&orig_pixels[0][0], 0, &gray_pixels[0][0], 0, 1280, 1); |
|
416 } |
|
417 } |
|
418 |
|
419 TEST_F(libyuvTest, TestARGBSepia) { |
|
420 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
421 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
422 |
|
423 // Test blue |
|
424 orig_pixels[0][0] = 255u; |
|
425 orig_pixels[0][1] = 0u; |
|
426 orig_pixels[0][2] = 0u; |
|
427 orig_pixels[0][3] = 128u; |
|
428 // Test green |
|
429 orig_pixels[1][0] = 0u; |
|
430 orig_pixels[1][1] = 255u; |
|
431 orig_pixels[1][2] = 0u; |
|
432 orig_pixels[1][3] = 0u; |
|
433 // Test red |
|
434 orig_pixels[2][0] = 0u; |
|
435 orig_pixels[2][1] = 0u; |
|
436 orig_pixels[2][2] = 255u; |
|
437 orig_pixels[2][3] = 255u; |
|
438 // Test black |
|
439 orig_pixels[3][0] = 0u; |
|
440 orig_pixels[3][1] = 0u; |
|
441 orig_pixels[3][2] = 0u; |
|
442 orig_pixels[3][3] = 255u; |
|
443 // Test white |
|
444 orig_pixels[4][0] = 255u; |
|
445 orig_pixels[4][1] = 255u; |
|
446 orig_pixels[4][2] = 255u; |
|
447 orig_pixels[4][3] = 255u; |
|
448 // Test color |
|
449 orig_pixels[5][0] = 16u; |
|
450 orig_pixels[5][1] = 64u; |
|
451 orig_pixels[5][2] = 192u; |
|
452 orig_pixels[5][3] = 224u; |
|
453 // Do 16 to test asm version. |
|
454 ARGBSepia(&orig_pixels[0][0], 0, 0, 0, 16, 1); |
|
455 EXPECT_EQ(33u, orig_pixels[0][0]); |
|
456 EXPECT_EQ(43u, orig_pixels[0][1]); |
|
457 EXPECT_EQ(47u, orig_pixels[0][2]); |
|
458 EXPECT_EQ(128u, orig_pixels[0][3]); |
|
459 EXPECT_EQ(135u, orig_pixels[1][0]); |
|
460 EXPECT_EQ(175u, orig_pixels[1][1]); |
|
461 EXPECT_EQ(195u, orig_pixels[1][2]); |
|
462 EXPECT_EQ(0u, orig_pixels[1][3]); |
|
463 EXPECT_EQ(69u, orig_pixels[2][0]); |
|
464 EXPECT_EQ(89u, orig_pixels[2][1]); |
|
465 EXPECT_EQ(99u, orig_pixels[2][2]); |
|
466 EXPECT_EQ(255u, orig_pixels[2][3]); |
|
467 EXPECT_EQ(0u, orig_pixels[3][0]); |
|
468 EXPECT_EQ(0u, orig_pixels[3][1]); |
|
469 EXPECT_EQ(0u, orig_pixels[3][2]); |
|
470 EXPECT_EQ(255u, orig_pixels[3][3]); |
|
471 EXPECT_EQ(239u, orig_pixels[4][0]); |
|
472 EXPECT_EQ(255u, orig_pixels[4][1]); |
|
473 EXPECT_EQ(255u, orig_pixels[4][2]); |
|
474 EXPECT_EQ(255u, orig_pixels[4][3]); |
|
475 EXPECT_EQ(88u, orig_pixels[5][0]); |
|
476 EXPECT_EQ(114u, orig_pixels[5][1]); |
|
477 EXPECT_EQ(127u, orig_pixels[5][2]); |
|
478 EXPECT_EQ(224u, orig_pixels[5][3]); |
|
479 |
|
480 for (int i = 0; i < 1280; ++i) { |
|
481 orig_pixels[i][0] = i; |
|
482 orig_pixels[i][1] = i / 2; |
|
483 orig_pixels[i][2] = i / 3; |
|
484 orig_pixels[i][3] = i; |
|
485 } |
|
486 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
487 ARGBSepia(&orig_pixels[0][0], 0, 0, 0, 1280, 1); |
|
488 } |
|
489 } |
|
490 |
|
491 TEST_F(libyuvTest, TestARGBColorMatrix) { |
|
492 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
493 SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); |
|
494 SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); |
|
495 |
|
496 // Matrix for Sepia. |
|
497 SIMD_ALIGNED(static const int8 kRGBToSepia[]) = { |
|
498 17 / 2, 68 / 2, 35 / 2, 0, |
|
499 22 / 2, 88 / 2, 45 / 2, 0, |
|
500 24 / 2, 98 / 2, 50 / 2, 0, |
|
501 0, 0, 0, 64, // Copy alpha. |
|
502 }; |
|
503 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
504 |
|
505 // Test blue |
|
506 orig_pixels[0][0] = 255u; |
|
507 orig_pixels[0][1] = 0u; |
|
508 orig_pixels[0][2] = 0u; |
|
509 orig_pixels[0][3] = 128u; |
|
510 // Test green |
|
511 orig_pixels[1][0] = 0u; |
|
512 orig_pixels[1][1] = 255u; |
|
513 orig_pixels[1][2] = 0u; |
|
514 orig_pixels[1][3] = 0u; |
|
515 // Test red |
|
516 orig_pixels[2][0] = 0u; |
|
517 orig_pixels[2][1] = 0u; |
|
518 orig_pixels[2][2] = 255u; |
|
519 orig_pixels[2][3] = 255u; |
|
520 // Test color |
|
521 orig_pixels[3][0] = 16u; |
|
522 orig_pixels[3][1] = 64u; |
|
523 orig_pixels[3][2] = 192u; |
|
524 orig_pixels[3][3] = 224u; |
|
525 // Do 16 to test asm version. |
|
526 ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, |
|
527 &kRGBToSepia[0], 16, 1); |
|
528 EXPECT_EQ(31u, dst_pixels_opt[0][0]); |
|
529 EXPECT_EQ(43u, dst_pixels_opt[0][1]); |
|
530 EXPECT_EQ(47u, dst_pixels_opt[0][2]); |
|
531 EXPECT_EQ(128u, dst_pixels_opt[0][3]); |
|
532 EXPECT_EQ(135u, dst_pixels_opt[1][0]); |
|
533 EXPECT_EQ(175u, dst_pixels_opt[1][1]); |
|
534 EXPECT_EQ(195u, dst_pixels_opt[1][2]); |
|
535 EXPECT_EQ(0u, dst_pixels_opt[1][3]); |
|
536 EXPECT_EQ(67u, dst_pixels_opt[2][0]); |
|
537 EXPECT_EQ(87u, dst_pixels_opt[2][1]); |
|
538 EXPECT_EQ(99u, dst_pixels_opt[2][2]); |
|
539 EXPECT_EQ(255u, dst_pixels_opt[2][3]); |
|
540 EXPECT_EQ(87u, dst_pixels_opt[3][0]); |
|
541 EXPECT_EQ(112u, dst_pixels_opt[3][1]); |
|
542 EXPECT_EQ(127u, dst_pixels_opt[3][2]); |
|
543 EXPECT_EQ(224u, dst_pixels_opt[3][3]); |
|
544 |
|
545 for (int i = 0; i < 1280; ++i) { |
|
546 orig_pixels[i][0] = i; |
|
547 orig_pixels[i][1] = i / 2; |
|
548 orig_pixels[i][2] = i / 3; |
|
549 orig_pixels[i][3] = i; |
|
550 } |
|
551 MaskCpuFlags(0); |
|
552 ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0, |
|
553 &kRGBToSepia[0], 1280, 1); |
|
554 MaskCpuFlags(-1); |
|
555 |
|
556 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
557 ARGBColorMatrix(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, |
|
558 &kRGBToSepia[0], 1280, 1); |
|
559 } |
|
560 |
|
561 for (int i = 0; i < 1280; ++i) { |
|
562 EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]); |
|
563 EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]); |
|
564 EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]); |
|
565 EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]); |
|
566 } |
|
567 } |
|
568 |
|
569 TEST_F(libyuvTest, TestRGBColorMatrix) { |
|
570 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
571 |
|
572 // Matrix for Sepia. |
|
573 SIMD_ALIGNED(static const int8 kRGBToSepia[]) = { |
|
574 17, 68, 35, 0, |
|
575 22, 88, 45, 0, |
|
576 24, 98, 50, 0, |
|
577 0, 0, 0, 0, // Unused but makes matrix 16 bytes. |
|
578 }; |
|
579 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
580 |
|
581 // Test blue |
|
582 orig_pixels[0][0] = 255u; |
|
583 orig_pixels[0][1] = 0u; |
|
584 orig_pixels[0][2] = 0u; |
|
585 orig_pixels[0][3] = 128u; |
|
586 // Test green |
|
587 orig_pixels[1][0] = 0u; |
|
588 orig_pixels[1][1] = 255u; |
|
589 orig_pixels[1][2] = 0u; |
|
590 orig_pixels[1][3] = 0u; |
|
591 // Test red |
|
592 orig_pixels[2][0] = 0u; |
|
593 orig_pixels[2][1] = 0u; |
|
594 orig_pixels[2][2] = 255u; |
|
595 orig_pixels[2][3] = 255u; |
|
596 // Test color |
|
597 orig_pixels[3][0] = 16u; |
|
598 orig_pixels[3][1] = 64u; |
|
599 orig_pixels[3][2] = 192u; |
|
600 orig_pixels[3][3] = 224u; |
|
601 // Do 16 to test asm version. |
|
602 RGBColorMatrix(&orig_pixels[0][0], 0, &kRGBToSepia[0], 0, 0, 16, 1); |
|
603 EXPECT_EQ(31u, orig_pixels[0][0]); |
|
604 EXPECT_EQ(43u, orig_pixels[0][1]); |
|
605 EXPECT_EQ(47u, orig_pixels[0][2]); |
|
606 EXPECT_EQ(128u, orig_pixels[0][3]); |
|
607 EXPECT_EQ(135u, orig_pixels[1][0]); |
|
608 EXPECT_EQ(175u, orig_pixels[1][1]); |
|
609 EXPECT_EQ(195u, orig_pixels[1][2]); |
|
610 EXPECT_EQ(0u, orig_pixels[1][3]); |
|
611 EXPECT_EQ(67u, orig_pixels[2][0]); |
|
612 EXPECT_EQ(87u, orig_pixels[2][1]); |
|
613 EXPECT_EQ(99u, orig_pixels[2][2]); |
|
614 EXPECT_EQ(255u, orig_pixels[2][3]); |
|
615 EXPECT_EQ(87u, orig_pixels[3][0]); |
|
616 EXPECT_EQ(112u, orig_pixels[3][1]); |
|
617 EXPECT_EQ(127u, orig_pixels[3][2]); |
|
618 EXPECT_EQ(224u, orig_pixels[3][3]); |
|
619 |
|
620 for (int i = 0; i < 1280; ++i) { |
|
621 orig_pixels[i][0] = i; |
|
622 orig_pixels[i][1] = i / 2; |
|
623 orig_pixels[i][2] = i / 3; |
|
624 orig_pixels[i][3] = i; |
|
625 } |
|
626 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
627 RGBColorMatrix(&orig_pixels[0][0], 0, &kRGBToSepia[0], 0, 0, 1280, 1); |
|
628 } |
|
629 } |
|
630 |
|
631 TEST_F(libyuvTest, TestARGBColorTable) { |
|
632 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
633 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
634 |
|
635 // Matrix for Sepia. |
|
636 static const uint8 kARGBTable[256 * 4] = { |
|
637 1u, 2u, 3u, 4u, |
|
638 5u, 6u, 7u, 8u, |
|
639 9u, 10u, 11u, 12u, |
|
640 13u, 14u, 15u, 16u, |
|
641 }; |
|
642 |
|
643 orig_pixels[0][0] = 0u; |
|
644 orig_pixels[0][1] = 0u; |
|
645 orig_pixels[0][2] = 0u; |
|
646 orig_pixels[0][3] = 0u; |
|
647 orig_pixels[1][0] = 1u; |
|
648 orig_pixels[1][1] = 1u; |
|
649 orig_pixels[1][2] = 1u; |
|
650 orig_pixels[1][3] = 1u; |
|
651 orig_pixels[2][0] = 2u; |
|
652 orig_pixels[2][1] = 2u; |
|
653 orig_pixels[2][2] = 2u; |
|
654 orig_pixels[2][3] = 2u; |
|
655 orig_pixels[3][0] = 0u; |
|
656 orig_pixels[3][1] = 1u; |
|
657 orig_pixels[3][2] = 2u; |
|
658 orig_pixels[3][3] = 3u; |
|
659 // Do 16 to test asm version. |
|
660 ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1); |
|
661 EXPECT_EQ(1u, orig_pixels[0][0]); |
|
662 EXPECT_EQ(2u, orig_pixels[0][1]); |
|
663 EXPECT_EQ(3u, orig_pixels[0][2]); |
|
664 EXPECT_EQ(4u, orig_pixels[0][3]); |
|
665 EXPECT_EQ(5u, orig_pixels[1][0]); |
|
666 EXPECT_EQ(6u, orig_pixels[1][1]); |
|
667 EXPECT_EQ(7u, orig_pixels[1][2]); |
|
668 EXPECT_EQ(8u, orig_pixels[1][3]); |
|
669 EXPECT_EQ(9u, orig_pixels[2][0]); |
|
670 EXPECT_EQ(10u, orig_pixels[2][1]); |
|
671 EXPECT_EQ(11u, orig_pixels[2][2]); |
|
672 EXPECT_EQ(12u, orig_pixels[2][3]); |
|
673 EXPECT_EQ(1u, orig_pixels[3][0]); |
|
674 EXPECT_EQ(6u, orig_pixels[3][1]); |
|
675 EXPECT_EQ(11u, orig_pixels[3][2]); |
|
676 EXPECT_EQ(16u, orig_pixels[3][3]); |
|
677 |
|
678 for (int i = 0; i < 1280; ++i) { |
|
679 orig_pixels[i][0] = i; |
|
680 orig_pixels[i][1] = i / 2; |
|
681 orig_pixels[i][2] = i / 3; |
|
682 orig_pixels[i][3] = i; |
|
683 } |
|
684 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
685 ARGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 1280, 1); |
|
686 } |
|
687 } |
|
688 |
|
689 // Same as TestARGBColorTable except alpha does not change. |
|
690 TEST_F(libyuvTest, TestRGBColorTable) { |
|
691 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
692 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
693 |
|
694 // Matrix for Sepia. |
|
695 static const uint8 kARGBTable[256 * 4] = { |
|
696 1u, 2u, 3u, 4u, |
|
697 5u, 6u, 7u, 8u, |
|
698 9u, 10u, 11u, 12u, |
|
699 13u, 14u, 15u, 16u, |
|
700 }; |
|
701 |
|
702 orig_pixels[0][0] = 0u; |
|
703 orig_pixels[0][1] = 0u; |
|
704 orig_pixels[0][2] = 0u; |
|
705 orig_pixels[0][3] = 0u; |
|
706 orig_pixels[1][0] = 1u; |
|
707 orig_pixels[1][1] = 1u; |
|
708 orig_pixels[1][2] = 1u; |
|
709 orig_pixels[1][3] = 1u; |
|
710 orig_pixels[2][0] = 2u; |
|
711 orig_pixels[2][1] = 2u; |
|
712 orig_pixels[2][2] = 2u; |
|
713 orig_pixels[2][3] = 2u; |
|
714 orig_pixels[3][0] = 0u; |
|
715 orig_pixels[3][1] = 1u; |
|
716 orig_pixels[3][2] = 2u; |
|
717 orig_pixels[3][3] = 3u; |
|
718 // Do 16 to test asm version. |
|
719 RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1); |
|
720 EXPECT_EQ(1u, orig_pixels[0][0]); |
|
721 EXPECT_EQ(2u, orig_pixels[0][1]); |
|
722 EXPECT_EQ(3u, orig_pixels[0][2]); |
|
723 EXPECT_EQ(0u, orig_pixels[0][3]); // Alpha unchanged. |
|
724 EXPECT_EQ(5u, orig_pixels[1][0]); |
|
725 EXPECT_EQ(6u, orig_pixels[1][1]); |
|
726 EXPECT_EQ(7u, orig_pixels[1][2]); |
|
727 EXPECT_EQ(1u, orig_pixels[1][3]); // Alpha unchanged. |
|
728 EXPECT_EQ(9u, orig_pixels[2][0]); |
|
729 EXPECT_EQ(10u, orig_pixels[2][1]); |
|
730 EXPECT_EQ(11u, orig_pixels[2][2]); |
|
731 EXPECT_EQ(2u, orig_pixels[2][3]); // Alpha unchanged. |
|
732 EXPECT_EQ(1u, orig_pixels[3][0]); |
|
733 EXPECT_EQ(6u, orig_pixels[3][1]); |
|
734 EXPECT_EQ(11u, orig_pixels[3][2]); |
|
735 EXPECT_EQ(3u, orig_pixels[3][3]); // Alpha unchanged. |
|
736 |
|
737 for (int i = 0; i < 1280; ++i) { |
|
738 orig_pixels[i][0] = i; |
|
739 orig_pixels[i][1] = i / 2; |
|
740 orig_pixels[i][2] = i / 3; |
|
741 orig_pixels[i][3] = i; |
|
742 } |
|
743 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
744 RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 1280, 1); |
|
745 } |
|
746 } |
|
747 |
|
748 TEST_F(libyuvTest, TestARGBQuantize) { |
|
749 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
750 |
|
751 for (int i = 0; i < 1280; ++i) { |
|
752 orig_pixels[i][0] = i; |
|
753 orig_pixels[i][1] = i / 2; |
|
754 orig_pixels[i][2] = i / 3; |
|
755 orig_pixels[i][3] = i; |
|
756 } |
|
757 ARGBQuantize(&orig_pixels[0][0], 0, |
|
758 (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0, 1280, 1); |
|
759 |
|
760 for (int i = 0; i < 1280; ++i) { |
|
761 EXPECT_EQ((i / 8 * 8 + 8 / 2) & 255, orig_pixels[i][0]); |
|
762 EXPECT_EQ((i / 2 / 8 * 8 + 8 / 2) & 255, orig_pixels[i][1]); |
|
763 EXPECT_EQ((i / 3 / 8 * 8 + 8 / 2) & 255, orig_pixels[i][2]); |
|
764 EXPECT_EQ(i & 255, orig_pixels[i][3]); |
|
765 } |
|
766 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
767 ARGBQuantize(&orig_pixels[0][0], 0, |
|
768 (65536 + (8 / 2)) / 8, 8, 8 / 2, 0, 0, 1280, 1); |
|
769 } |
|
770 } |
|
771 |
|
772 TEST_F(libyuvTest, TestARGBMirror) { |
|
773 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
774 SIMD_ALIGNED(uint8 dst_pixels[1280][4]); |
|
775 |
|
776 for (int i = 0; i < 1280; ++i) { |
|
777 orig_pixels[i][0] = i; |
|
778 orig_pixels[i][1] = i / 2; |
|
779 orig_pixels[i][2] = i / 3; |
|
780 orig_pixels[i][3] = i / 4; |
|
781 } |
|
782 ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 1280, 1); |
|
783 |
|
784 for (int i = 0; i < 1280; ++i) { |
|
785 EXPECT_EQ(i & 255, dst_pixels[1280 - 1 - i][0]); |
|
786 EXPECT_EQ((i / 2) & 255, dst_pixels[1280 - 1 - i][1]); |
|
787 EXPECT_EQ((i / 3) & 255, dst_pixels[1280 - 1 - i][2]); |
|
788 EXPECT_EQ((i / 4) & 255, dst_pixels[1280 - 1 - i][3]); |
|
789 } |
|
790 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
791 ARGBMirror(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0, 1280, 1); |
|
792 } |
|
793 } |
|
794 |
|
795 TEST_F(libyuvTest, TestShade) { |
|
796 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
797 SIMD_ALIGNED(uint8 shade_pixels[1280][4]); |
|
798 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
799 |
|
800 orig_pixels[0][0] = 10u; |
|
801 orig_pixels[0][1] = 20u; |
|
802 orig_pixels[0][2] = 40u; |
|
803 orig_pixels[0][3] = 80u; |
|
804 orig_pixels[1][0] = 0u; |
|
805 orig_pixels[1][1] = 0u; |
|
806 orig_pixels[1][2] = 0u; |
|
807 orig_pixels[1][3] = 255u; |
|
808 orig_pixels[2][0] = 0u; |
|
809 orig_pixels[2][1] = 0u; |
|
810 orig_pixels[2][2] = 0u; |
|
811 orig_pixels[2][3] = 0u; |
|
812 orig_pixels[3][0] = 0u; |
|
813 orig_pixels[3][1] = 0u; |
|
814 orig_pixels[3][2] = 0u; |
|
815 orig_pixels[3][3] = 0u; |
|
816 // Do 8 pixels to allow opt version to be used. |
|
817 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x80ffffff); |
|
818 EXPECT_EQ(10u, shade_pixels[0][0]); |
|
819 EXPECT_EQ(20u, shade_pixels[0][1]); |
|
820 EXPECT_EQ(40u, shade_pixels[0][2]); |
|
821 EXPECT_EQ(40u, shade_pixels[0][3]); |
|
822 EXPECT_EQ(0u, shade_pixels[1][0]); |
|
823 EXPECT_EQ(0u, shade_pixels[1][1]); |
|
824 EXPECT_EQ(0u, shade_pixels[1][2]); |
|
825 EXPECT_EQ(128u, shade_pixels[1][3]); |
|
826 EXPECT_EQ(0u, shade_pixels[2][0]); |
|
827 EXPECT_EQ(0u, shade_pixels[2][1]); |
|
828 EXPECT_EQ(0u, shade_pixels[2][2]); |
|
829 EXPECT_EQ(0u, shade_pixels[2][3]); |
|
830 EXPECT_EQ(0u, shade_pixels[3][0]); |
|
831 EXPECT_EQ(0u, shade_pixels[3][1]); |
|
832 EXPECT_EQ(0u, shade_pixels[3][2]); |
|
833 EXPECT_EQ(0u, shade_pixels[3][3]); |
|
834 |
|
835 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x80808080); |
|
836 EXPECT_EQ(5u, shade_pixels[0][0]); |
|
837 EXPECT_EQ(10u, shade_pixels[0][1]); |
|
838 EXPECT_EQ(20u, shade_pixels[0][2]); |
|
839 EXPECT_EQ(40u, shade_pixels[0][3]); |
|
840 |
|
841 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 8, 1, 0x10204080); |
|
842 EXPECT_EQ(5u, shade_pixels[0][0]); |
|
843 EXPECT_EQ(5u, shade_pixels[0][1]); |
|
844 EXPECT_EQ(5u, shade_pixels[0][2]); |
|
845 EXPECT_EQ(5u, shade_pixels[0][3]); |
|
846 |
|
847 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
848 ARGBShade(&orig_pixels[0][0], 0, &shade_pixels[0][0], 0, 1280, 1, |
|
849 0x80808080); |
|
850 } |
|
851 } |
|
852 |
|
853 TEST_F(libyuvTest, TestInterpolate) { |
|
854 SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]); |
|
855 SIMD_ALIGNED(uint8 orig_pixels_1[1280][4]); |
|
856 SIMD_ALIGNED(uint8 interpolate_pixels[1280][4]); |
|
857 memset(orig_pixels_0, 0, sizeof(orig_pixels_0)); |
|
858 memset(orig_pixels_1, 0, sizeof(orig_pixels_1)); |
|
859 |
|
860 orig_pixels_0[0][0] = 16u; |
|
861 orig_pixels_0[0][1] = 32u; |
|
862 orig_pixels_0[0][2] = 64u; |
|
863 orig_pixels_0[0][3] = 128u; |
|
864 orig_pixels_0[1][0] = 0u; |
|
865 orig_pixels_0[1][1] = 0u; |
|
866 orig_pixels_0[1][2] = 0u; |
|
867 orig_pixels_0[1][3] = 255u; |
|
868 orig_pixels_0[2][0] = 0u; |
|
869 orig_pixels_0[2][1] = 0u; |
|
870 orig_pixels_0[2][2] = 0u; |
|
871 orig_pixels_0[2][3] = 0u; |
|
872 orig_pixels_0[3][0] = 0u; |
|
873 orig_pixels_0[3][1] = 0u; |
|
874 orig_pixels_0[3][2] = 0u; |
|
875 orig_pixels_0[3][3] = 0u; |
|
876 |
|
877 orig_pixels_1[0][0] = 0u; |
|
878 orig_pixels_1[0][1] = 0u; |
|
879 orig_pixels_1[0][2] = 0u; |
|
880 orig_pixels_1[0][3] = 0u; |
|
881 orig_pixels_1[1][0] = 0u; |
|
882 orig_pixels_1[1][1] = 0u; |
|
883 orig_pixels_1[1][2] = 0u; |
|
884 orig_pixels_1[1][3] = 0u; |
|
885 orig_pixels_1[2][0] = 0u; |
|
886 orig_pixels_1[2][1] = 0u; |
|
887 orig_pixels_1[2][2] = 0u; |
|
888 orig_pixels_1[2][3] = 0u; |
|
889 orig_pixels_1[3][0] = 255u; |
|
890 orig_pixels_1[3][1] = 255u; |
|
891 orig_pixels_1[3][2] = 255u; |
|
892 orig_pixels_1[3][3] = 255u; |
|
893 |
|
894 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, |
|
895 &interpolate_pixels[0][0], 0, 4, 1, 128); |
|
896 EXPECT_EQ(8u, interpolate_pixels[0][0]); |
|
897 EXPECT_EQ(16u, interpolate_pixels[0][1]); |
|
898 EXPECT_EQ(32u, interpolate_pixels[0][2]); |
|
899 EXPECT_EQ(64u, interpolate_pixels[0][3]); |
|
900 EXPECT_EQ(0u, interpolate_pixels[1][0]); |
|
901 EXPECT_EQ(0u, interpolate_pixels[1][1]); |
|
902 EXPECT_EQ(0u, interpolate_pixels[1][2]); |
|
903 EXPECT_NEAR(128u, interpolate_pixels[1][3], 1); // C = 127, SSE = 128. |
|
904 EXPECT_EQ(0u, interpolate_pixels[2][0]); |
|
905 EXPECT_EQ(0u, interpolate_pixels[2][1]); |
|
906 EXPECT_EQ(0u, interpolate_pixels[2][2]); |
|
907 EXPECT_EQ(0u, interpolate_pixels[2][3]); |
|
908 EXPECT_NEAR(128u, interpolate_pixels[3][0], 1); |
|
909 EXPECT_NEAR(128u, interpolate_pixels[3][1], 1); |
|
910 EXPECT_NEAR(128u, interpolate_pixels[3][2], 1); |
|
911 EXPECT_NEAR(128u, interpolate_pixels[3][3], 1); |
|
912 |
|
913 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, |
|
914 &interpolate_pixels[0][0], 0, 4, 1, 0); |
|
915 EXPECT_EQ(16u, interpolate_pixels[0][0]); |
|
916 EXPECT_EQ(32u, interpolate_pixels[0][1]); |
|
917 EXPECT_EQ(64u, interpolate_pixels[0][2]); |
|
918 EXPECT_EQ(128u, interpolate_pixels[0][3]); |
|
919 |
|
920 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, |
|
921 &interpolate_pixels[0][0], 0, 4, 1, 192); |
|
922 |
|
923 EXPECT_EQ(4u, interpolate_pixels[0][0]); |
|
924 EXPECT_EQ(8u, interpolate_pixels[0][1]); |
|
925 EXPECT_EQ(16u, interpolate_pixels[0][2]); |
|
926 EXPECT_EQ(32u, interpolate_pixels[0][3]); |
|
927 |
|
928 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
929 ARGBInterpolate(&orig_pixels_0[0][0], 0, &orig_pixels_1[0][0], 0, |
|
930 &interpolate_pixels[0][0], 0, 1280, 1, 128); |
|
931 } |
|
932 } |
|
933 |
|
934 #define TESTTERP(FMT_A, BPP_A, STRIDE_A, \ |
|
935 FMT_B, BPP_B, STRIDE_B, \ |
|
936 W1280, TERP, DIFF, N, NEG, OFF) \ |
|
937 TEST_F(libyuvTest, ARGBInterpolate##TERP##N) { \ |
|
938 const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ |
|
939 const int kHeight = benchmark_height_; \ |
|
940 const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \ |
|
941 const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \ |
|
942 align_buffer_64(src_argb_a, kStrideA * kHeight + OFF); \ |
|
943 align_buffer_64(src_argb_b, kStrideA * kHeight + OFF); \ |
|
944 align_buffer_64(dst_argb_c, kStrideB * kHeight); \ |
|
945 align_buffer_64(dst_argb_opt, kStrideB * kHeight); \ |
|
946 srandom(time(NULL)); \ |
|
947 for (int i = 0; i < kStrideA * kHeight; ++i) { \ |
|
948 src_argb_a[i + OFF] = (random() & 0xff); \ |
|
949 src_argb_b[i + OFF] = (random() & 0xff); \ |
|
950 } \ |
|
951 MaskCpuFlags(0); \ |
|
952 ARGBInterpolate(src_argb_a + OFF, kStrideA, \ |
|
953 src_argb_b + OFF, kStrideA, \ |
|
954 dst_argb_c, kStrideB, \ |
|
955 kWidth, NEG kHeight, TERP); \ |
|
956 MaskCpuFlags(-1); \ |
|
957 for (int i = 0; i < benchmark_iterations_; ++i) { \ |
|
958 ARGBInterpolate(src_argb_a + OFF, kStrideA, \ |
|
959 src_argb_b + OFF, kStrideA, \ |
|
960 dst_argb_opt, kStrideB, \ |
|
961 kWidth, NEG kHeight, TERP); \ |
|
962 } \ |
|
963 int max_diff = 0; \ |
|
964 for (int i = 0; i < kStrideB * kHeight; ++i) { \ |
|
965 int abs_diff = \ |
|
966 abs(static_cast<int>(dst_argb_c[i]) - \ |
|
967 static_cast<int>(dst_argb_opt[i])); \ |
|
968 if (abs_diff > max_diff) { \ |
|
969 max_diff = abs_diff; \ |
|
970 } \ |
|
971 } \ |
|
972 EXPECT_LE(max_diff, DIFF); \ |
|
973 free_aligned_buffer_64(src_argb_a); \ |
|
974 free_aligned_buffer_64(src_argb_b); \ |
|
975 free_aligned_buffer_64(dst_argb_c); \ |
|
976 free_aligned_buffer_64(dst_argb_opt); \ |
|
977 } |
|
978 |
|
979 #define TESTINTERPOLATE(TERP) \ |
|
980 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ |
|
981 benchmark_width_ - 1, TERP, 1, _Any, +, 0) \ |
|
982 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ |
|
983 benchmark_width_, TERP, 1, _Unaligned, +, 1) \ |
|
984 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ |
|
985 benchmark_width_, TERP, 1, _Invert, -, 0) \ |
|
986 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ |
|
987 benchmark_width_, TERP, 1, _Opt, +, 0) \ |
|
988 TESTTERP(ARGB, 4, 1, ARGB, 4, 1, \ |
|
989 benchmark_width_ - 1, TERP, 1, _Any_Invert, -, 0) |
|
990 |
|
991 TESTINTERPOLATE(0) |
|
992 TESTINTERPOLATE(64) |
|
993 TESTINTERPOLATE(128) |
|
994 TESTINTERPOLATE(192) |
|
995 TESTINTERPOLATE(255) |
|
996 |
|
997 static int TestBlend(int width, int height, int benchmark_iterations, |
|
998 int invert, int off) { |
|
999 if (width < 1) { |
|
1000 width = 1; |
|
1001 } |
|
1002 const int kBpp = 4; |
|
1003 const int kStride = width * kBpp; |
|
1004 align_buffer_64(src_argb_a, kStride * height + off); |
|
1005 align_buffer_64(src_argb_b, kStride * height + off); |
|
1006 align_buffer_64(dst_argb_c, kStride * height); |
|
1007 align_buffer_64(dst_argb_opt, kStride * height); |
|
1008 srandom(time(NULL)); |
|
1009 for (int i = 0; i < kStride * height; ++i) { |
|
1010 src_argb_a[i + off] = (random() & 0xff); |
|
1011 src_argb_b[i + off] = (random() & 0xff); |
|
1012 } |
|
1013 ARGBAttenuate(src_argb_a + off, kStride, src_argb_a + off, kStride, width, |
|
1014 height); |
|
1015 ARGBAttenuate(src_argb_b + off, kStride, src_argb_b + off, kStride, width, |
|
1016 height); |
|
1017 memset(dst_argb_c, 255, kStride * height); |
|
1018 memset(dst_argb_opt, 255, kStride * height); |
|
1019 |
|
1020 MaskCpuFlags(0); |
|
1021 ARGBBlend(src_argb_a + off, kStride, |
|
1022 src_argb_b + off, kStride, |
|
1023 dst_argb_c, kStride, |
|
1024 width, invert * height); |
|
1025 MaskCpuFlags(-1); |
|
1026 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1027 ARGBBlend(src_argb_a + off, kStride, |
|
1028 src_argb_b + off, kStride, |
|
1029 dst_argb_opt, kStride, |
|
1030 width, invert * height); |
|
1031 } |
|
1032 int max_diff = 0; |
|
1033 for (int i = 0; i < kStride * height; ++i) { |
|
1034 int abs_diff = |
|
1035 abs(static_cast<int>(dst_argb_c[i]) - |
|
1036 static_cast<int>(dst_argb_opt[i])); |
|
1037 if (abs_diff > max_diff) { |
|
1038 max_diff = abs_diff; |
|
1039 } |
|
1040 } |
|
1041 free_aligned_buffer_64(src_argb_a); |
|
1042 free_aligned_buffer_64(src_argb_b); |
|
1043 free_aligned_buffer_64(dst_argb_c); |
|
1044 free_aligned_buffer_64(dst_argb_opt); |
|
1045 return max_diff; |
|
1046 } |
|
1047 |
|
1048 TEST_F(libyuvTest, ARGBBlend_Any) { |
|
1049 int max_diff = TestBlend(benchmark_width_ - 4, benchmark_height_, |
|
1050 benchmark_iterations_, +1, 0); |
|
1051 EXPECT_LE(max_diff, 1); |
|
1052 } |
|
1053 |
|
1054 TEST_F(libyuvTest, ARGBBlend_Unaligned) { |
|
1055 int max_diff = TestBlend(benchmark_width_, benchmark_height_, |
|
1056 benchmark_iterations_, +1, 1); |
|
1057 EXPECT_LE(max_diff, 1); |
|
1058 } |
|
1059 |
|
1060 TEST_F(libyuvTest, ARGBBlend_Invert) { |
|
1061 int max_diff = TestBlend(benchmark_width_, benchmark_height_, |
|
1062 benchmark_iterations_, -1, 0); |
|
1063 EXPECT_LE(max_diff, 1); |
|
1064 } |
|
1065 |
|
1066 TEST_F(libyuvTest, ARGBBlend_Opt) { |
|
1067 int max_diff = TestBlend(benchmark_width_, benchmark_height_, |
|
1068 benchmark_iterations_, +1, 0); |
|
1069 EXPECT_LE(max_diff, 1); |
|
1070 } |
|
1071 |
|
1072 TEST_F(libyuvTest, TestAffine) { |
|
1073 SIMD_ALIGNED(uint8 orig_pixels_0[1280][4]); |
|
1074 SIMD_ALIGNED(uint8 interpolate_pixels_C[1280][4]); |
|
1075 |
|
1076 for (int i = 0; i < 1280; ++i) { |
|
1077 for (int j = 0; j < 4; ++j) { |
|
1078 orig_pixels_0[i][j] = i; |
|
1079 } |
|
1080 } |
|
1081 |
|
1082 float uv_step[4] = { 0.f, 0.f, 0.75f, 0.f }; |
|
1083 |
|
1084 ARGBAffineRow_C(&orig_pixels_0[0][0], 0, &interpolate_pixels_C[0][0], |
|
1085 uv_step, 1280); |
|
1086 EXPECT_EQ(0u, interpolate_pixels_C[0][0]); |
|
1087 EXPECT_EQ(96u, interpolate_pixels_C[128][0]); |
|
1088 EXPECT_EQ(191u, interpolate_pixels_C[255][3]); |
|
1089 |
|
1090 #if defined(HAS_ARGBAFFINEROW_SSE2) |
|
1091 SIMD_ALIGNED(uint8 interpolate_pixels_Opt[1280][4]); |
|
1092 ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0], |
|
1093 uv_step, 1280); |
|
1094 EXPECT_EQ(0, memcmp(interpolate_pixels_Opt, interpolate_pixels_C, 1280 * 4)); |
|
1095 |
|
1096 int has_sse2 = TestCpuFlag(kCpuHasSSE2); |
|
1097 if (has_sse2) { |
|
1098 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
1099 ARGBAffineRow_SSE2(&orig_pixels_0[0][0], 0, &interpolate_pixels_Opt[0][0], |
|
1100 uv_step, 1280); |
|
1101 } |
|
1102 } |
|
1103 #endif |
|
1104 } |
|
1105 |
|
1106 TEST_F(libyuvTest, TestSobelX) { |
|
1107 SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]); |
|
1108 SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]); |
|
1109 SIMD_ALIGNED(uint8 orig_pixels_2[1280 + 2]); |
|
1110 SIMD_ALIGNED(uint8 sobel_pixels_c[1280]); |
|
1111 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]); |
|
1112 |
|
1113 for (int i = 0; i < 1280 + 2; ++i) { |
|
1114 orig_pixels_0[i] = i; |
|
1115 orig_pixels_1[i] = i * 2; |
|
1116 orig_pixels_2[i] = i * 3; |
|
1117 } |
|
1118 |
|
1119 SobelXRow_C(orig_pixels_0, orig_pixels_1, orig_pixels_2, |
|
1120 sobel_pixels_c, 1280); |
|
1121 |
|
1122 EXPECT_EQ(16u, sobel_pixels_c[0]); |
|
1123 EXPECT_EQ(16u, sobel_pixels_c[100]); |
|
1124 EXPECT_EQ(255u, sobel_pixels_c[255]); |
|
1125 |
|
1126 void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1, |
|
1127 const uint8* src_y2, uint8* dst_sobely, int width) = |
|
1128 SobelXRow_C; |
|
1129 #if defined(HAS_SOBELXROW_SSE2) |
|
1130 if (TestCpuFlag(kCpuHasSSE2)) { |
|
1131 SobelXRow = SobelXRow_SSE2; |
|
1132 } |
|
1133 #endif |
|
1134 #if defined(HAS_SOBELXROW_NEON) |
|
1135 if (TestCpuFlag(kCpuHasNEON)) { |
|
1136 SobelXRow = SobelXRow_NEON; |
|
1137 } |
|
1138 #endif |
|
1139 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
1140 SobelXRow(orig_pixels_0, orig_pixels_1, orig_pixels_2, |
|
1141 sobel_pixels_opt, 1280); |
|
1142 } |
|
1143 for (int i = 0; i < 1280; ++i) { |
|
1144 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); |
|
1145 } |
|
1146 } |
|
1147 |
|
1148 TEST_F(libyuvTest, TestSobelY) { |
|
1149 SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]); |
|
1150 SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]); |
|
1151 SIMD_ALIGNED(uint8 sobel_pixels_c[1280]); |
|
1152 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]); |
|
1153 |
|
1154 for (int i = 0; i < 1280 + 2; ++i) { |
|
1155 orig_pixels_0[i] = i; |
|
1156 orig_pixels_1[i] = i * 2; |
|
1157 } |
|
1158 |
|
1159 SobelYRow_C(orig_pixels_0, orig_pixels_1, sobel_pixels_c, 1280); |
|
1160 |
|
1161 EXPECT_EQ(4u, sobel_pixels_c[0]); |
|
1162 EXPECT_EQ(255u, sobel_pixels_c[100]); |
|
1163 EXPECT_EQ(0u, sobel_pixels_c[255]); |
|
1164 void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1, |
|
1165 uint8* dst_sobely, int width) = SobelYRow_C; |
|
1166 #if defined(HAS_SOBELYROW_SSE2) |
|
1167 if (TestCpuFlag(kCpuHasSSE2)) { |
|
1168 SobelYRow = SobelYRow_SSE2; |
|
1169 } |
|
1170 #endif |
|
1171 #if defined(HAS_SOBELYROW_NEON) |
|
1172 if (TestCpuFlag(kCpuHasNEON)) { |
|
1173 SobelYRow = SobelYRow_NEON; |
|
1174 } |
|
1175 #endif |
|
1176 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
1177 SobelYRow(orig_pixels_0, orig_pixels_1, sobel_pixels_opt, 1280); |
|
1178 } |
|
1179 for (int i = 0; i < 1280; ++i) { |
|
1180 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); |
|
1181 } |
|
1182 } |
|
1183 |
|
1184 TEST_F(libyuvTest, TestSobel) { |
|
1185 SIMD_ALIGNED(uint8 orig_sobelx[1280]); |
|
1186 SIMD_ALIGNED(uint8 orig_sobely[1280]); |
|
1187 SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]); |
|
1188 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]); |
|
1189 |
|
1190 for (int i = 0; i < 1280; ++i) { |
|
1191 orig_sobelx[i] = i; |
|
1192 orig_sobely[i] = i * 2; |
|
1193 } |
|
1194 |
|
1195 SobelRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280); |
|
1196 |
|
1197 EXPECT_EQ(0u, sobel_pixels_c[0]); |
|
1198 EXPECT_EQ(3u, sobel_pixels_c[4]); |
|
1199 EXPECT_EQ(3u, sobel_pixels_c[5]); |
|
1200 EXPECT_EQ(3u, sobel_pixels_c[6]); |
|
1201 EXPECT_EQ(255u, sobel_pixels_c[7]); |
|
1202 EXPECT_EQ(6u, sobel_pixels_c[8]); |
|
1203 EXPECT_EQ(6u, sobel_pixels_c[9]); |
|
1204 EXPECT_EQ(6u, sobel_pixels_c[10]); |
|
1205 EXPECT_EQ(255u, sobel_pixels_c[7]); |
|
1206 EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]); |
|
1207 EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]); |
|
1208 void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely, |
|
1209 uint8* dst_argb, int width) = SobelRow_C; |
|
1210 #if defined(HAS_SOBELROW_SSE2) |
|
1211 if (TestCpuFlag(kCpuHasSSE2)) { |
|
1212 SobelRow = SobelRow_SSE2; |
|
1213 } |
|
1214 #endif |
|
1215 #if defined(HAS_SOBELROW_NEON) |
|
1216 if (TestCpuFlag(kCpuHasNEON)) { |
|
1217 SobelRow = SobelRow_NEON; |
|
1218 } |
|
1219 #endif |
|
1220 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
1221 SobelRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280); |
|
1222 } |
|
1223 for (int i = 0; i < 1280 * 4; ++i) { |
|
1224 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); |
|
1225 } |
|
1226 } |
|
1227 |
|
1228 TEST_F(libyuvTest, TestSobelToPlane) { |
|
1229 SIMD_ALIGNED(uint8 orig_sobelx[1280]); |
|
1230 SIMD_ALIGNED(uint8 orig_sobely[1280]); |
|
1231 SIMD_ALIGNED(uint8 sobel_pixels_c[1280]); |
|
1232 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]); |
|
1233 |
|
1234 for (int i = 0; i < 1280; ++i) { |
|
1235 orig_sobelx[i] = i; |
|
1236 orig_sobely[i] = i * 2; |
|
1237 } |
|
1238 |
|
1239 SobelToPlaneRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280); |
|
1240 |
|
1241 EXPECT_EQ(0u, sobel_pixels_c[0]); |
|
1242 EXPECT_EQ(3u, sobel_pixels_c[1]); |
|
1243 EXPECT_EQ(6u, sobel_pixels_c[2]); |
|
1244 EXPECT_EQ(99u, sobel_pixels_c[33]); |
|
1245 EXPECT_EQ(255u, sobel_pixels_c[100]); |
|
1246 void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely, |
|
1247 uint8* dst_y, int width) = SobelToPlaneRow_C; |
|
1248 #if defined(HAS_SOBELTOPLANEROW_SSE2) |
|
1249 if (TestCpuFlag(kCpuHasSSE2)) { |
|
1250 SobelToPlaneRow = SobelToPlaneRow_SSE2; |
|
1251 } |
|
1252 #endif |
|
1253 #if defined(HAS_SOBELTOPLANEROW_NEON) |
|
1254 if (TestCpuFlag(kCpuHasNEON)) { |
|
1255 SobelToPlaneRow = SobelToPlaneRow_NEON; |
|
1256 } |
|
1257 #endif |
|
1258 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
1259 SobelToPlaneRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280); |
|
1260 } |
|
1261 for (int i = 0; i < 1280; ++i) { |
|
1262 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); |
|
1263 } |
|
1264 } |
|
1265 |
|
1266 TEST_F(libyuvTest, TestSobelXY) { |
|
1267 SIMD_ALIGNED(uint8 orig_sobelx[1280]); |
|
1268 SIMD_ALIGNED(uint8 orig_sobely[1280]); |
|
1269 SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]); |
|
1270 SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]); |
|
1271 |
|
1272 for (int i = 0; i < 1280; ++i) { |
|
1273 orig_sobelx[i] = i; |
|
1274 orig_sobely[i] = i * 2; |
|
1275 } |
|
1276 |
|
1277 SobelXYRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280); |
|
1278 |
|
1279 EXPECT_EQ(0u, sobel_pixels_c[0]); |
|
1280 EXPECT_EQ(2u, sobel_pixels_c[4]); |
|
1281 EXPECT_EQ(3u, sobel_pixels_c[5]); |
|
1282 EXPECT_EQ(1u, sobel_pixels_c[6]); |
|
1283 EXPECT_EQ(255u, sobel_pixels_c[7]); |
|
1284 EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]); |
|
1285 EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]); |
|
1286 void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely, |
|
1287 uint8* dst_argb, int width) = SobelXYRow_C; |
|
1288 #if defined(HAS_SOBELXYROW_SSE2) |
|
1289 if (TestCpuFlag(kCpuHasSSE2)) { |
|
1290 SobelXYRow = SobelXYRow_SSE2; |
|
1291 } |
|
1292 #endif |
|
1293 #if defined(HAS_SOBELXYROW_NEON) |
|
1294 if (TestCpuFlag(kCpuHasNEON)) { |
|
1295 SobelXYRow = SobelXYRow_NEON; |
|
1296 } |
|
1297 #endif |
|
1298 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
1299 SobelXYRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280); |
|
1300 } |
|
1301 for (int i = 0; i < 1280 * 4; ++i) { |
|
1302 EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]); |
|
1303 } |
|
1304 } |
|
1305 |
|
1306 TEST_F(libyuvTest, TestCopyPlane) { |
|
1307 int err = 0; |
|
1308 int yw = benchmark_width_; |
|
1309 int yh = benchmark_height_; |
|
1310 int b = 12; |
|
1311 int i, j; |
|
1312 |
|
1313 int y_plane_size = (yw + b * 2) * (yh + b * 2); |
|
1314 srandom(time(NULL)); |
|
1315 align_buffer_64(orig_y, y_plane_size); |
|
1316 align_buffer_64(dst_c, y_plane_size); |
|
1317 align_buffer_64(dst_opt, y_plane_size); |
|
1318 |
|
1319 memset(orig_y, 0, y_plane_size); |
|
1320 memset(dst_c, 0, y_plane_size); |
|
1321 memset(dst_opt, 0, y_plane_size); |
|
1322 |
|
1323 // Fill image buffers with random data. |
|
1324 for (i = b; i < (yh + b); ++i) { |
|
1325 for (j = b; j < (yw + b); ++j) { |
|
1326 orig_y[i * (yw + b * 2) + j] = random() & 0xff; |
|
1327 } |
|
1328 } |
|
1329 |
|
1330 // Fill destination buffers with random data. |
|
1331 for (i = 0; i < y_plane_size; ++i) { |
|
1332 uint8 random_number = random() & 0x7f; |
|
1333 dst_c[i] = random_number; |
|
1334 dst_opt[i] = dst_c[i]; |
|
1335 } |
|
1336 |
|
1337 int y_off = b * (yw + b * 2) + b; |
|
1338 |
|
1339 int y_st = yw + b * 2; |
|
1340 int stride = 8; |
|
1341 |
|
1342 // Disable all optimizations. |
|
1343 MaskCpuFlags(0); |
|
1344 double c_time = get_time(); |
|
1345 for (j = 0; j < benchmark_iterations_; j++) { |
|
1346 CopyPlane(orig_y + y_off, y_st, dst_c + y_off, stride, yw, yh); |
|
1347 } |
|
1348 c_time = (get_time() - c_time) / benchmark_iterations_; |
|
1349 |
|
1350 // Enable optimizations. |
|
1351 MaskCpuFlags(-1); |
|
1352 double opt_time = get_time(); |
|
1353 for (j = 0; j < benchmark_iterations_; j++) { |
|
1354 CopyPlane(orig_y + y_off, y_st, dst_opt + y_off, stride, yw, yh); |
|
1355 } |
|
1356 opt_time = (get_time() - opt_time) / benchmark_iterations_; |
|
1357 |
|
1358 for (i = 0; i < y_plane_size; ++i) { |
|
1359 if (dst_c[i] != dst_opt[i]) |
|
1360 ++err; |
|
1361 } |
|
1362 |
|
1363 free_aligned_buffer_64(orig_y); |
|
1364 free_aligned_buffer_64(dst_c); |
|
1365 free_aligned_buffer_64(dst_opt); |
|
1366 |
|
1367 EXPECT_EQ(0, err); |
|
1368 } |
|
1369 |
|
1370 static int TestMultiply(int width, int height, int benchmark_iterations, |
|
1371 int invert, int off) { |
|
1372 if (width < 1) { |
|
1373 width = 1; |
|
1374 } |
|
1375 const int kBpp = 4; |
|
1376 const int kStride = (width * kBpp + 15) & ~15; |
|
1377 align_buffer_64(src_argb_a, kStride * height + off); |
|
1378 align_buffer_64(src_argb_b, kStride * height + off); |
|
1379 align_buffer_64(dst_argb_c, kStride * height); |
|
1380 align_buffer_64(dst_argb_opt, kStride * height); |
|
1381 srandom(time(NULL)); |
|
1382 for (int i = 0; i < kStride * height; ++i) { |
|
1383 src_argb_a[i + off] = (random() & 0xff); |
|
1384 src_argb_b[i + off] = (random() & 0xff); |
|
1385 } |
|
1386 memset(dst_argb_c, 0, kStride * height); |
|
1387 memset(dst_argb_opt, 0, kStride * height); |
|
1388 |
|
1389 MaskCpuFlags(0); |
|
1390 ARGBMultiply(src_argb_a + off, kStride, |
|
1391 src_argb_b + off, kStride, |
|
1392 dst_argb_c, kStride, |
|
1393 width, invert * height); |
|
1394 MaskCpuFlags(-1); |
|
1395 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1396 ARGBMultiply(src_argb_a + off, kStride, |
|
1397 src_argb_b + off, kStride, |
|
1398 dst_argb_opt, kStride, |
|
1399 width, invert * height); |
|
1400 } |
|
1401 int max_diff = 0; |
|
1402 for (int i = 0; i < kStride * height; ++i) { |
|
1403 int abs_diff = |
|
1404 abs(static_cast<int>(dst_argb_c[i]) - |
|
1405 static_cast<int>(dst_argb_opt[i])); |
|
1406 if (abs_diff > max_diff) { |
|
1407 max_diff = abs_diff; |
|
1408 } |
|
1409 } |
|
1410 free_aligned_buffer_64(src_argb_a); |
|
1411 free_aligned_buffer_64(src_argb_b); |
|
1412 free_aligned_buffer_64(dst_argb_c); |
|
1413 free_aligned_buffer_64(dst_argb_opt); |
|
1414 return max_diff; |
|
1415 } |
|
1416 |
|
1417 TEST_F(libyuvTest, ARGBMultiply_Any) { |
|
1418 int max_diff = TestMultiply(benchmark_width_ - 1, benchmark_height_, |
|
1419 benchmark_iterations_, +1, 0); |
|
1420 EXPECT_LE(max_diff, 1); |
|
1421 } |
|
1422 |
|
1423 TEST_F(libyuvTest, ARGBMultiply_Unaligned) { |
|
1424 int max_diff = TestMultiply(benchmark_width_, benchmark_height_, |
|
1425 benchmark_iterations_, +1, 1); |
|
1426 EXPECT_LE(max_diff, 1); |
|
1427 } |
|
1428 |
|
1429 TEST_F(libyuvTest, ARGBMultiply_Invert) { |
|
1430 int max_diff = TestMultiply(benchmark_width_, benchmark_height_, |
|
1431 benchmark_iterations_, -1, 0); |
|
1432 EXPECT_LE(max_diff, 1); |
|
1433 } |
|
1434 |
|
1435 TEST_F(libyuvTest, ARGBMultiply_Opt) { |
|
1436 int max_diff = TestMultiply(benchmark_width_, benchmark_height_, |
|
1437 benchmark_iterations_, +1, 0); |
|
1438 EXPECT_LE(max_diff, 1); |
|
1439 } |
|
1440 |
|
1441 static int TestAdd(int width, int height, int benchmark_iterations, |
|
1442 int invert, int off) { |
|
1443 if (width < 1) { |
|
1444 width = 1; |
|
1445 } |
|
1446 const int kBpp = 4; |
|
1447 const int kStride = (width * kBpp + 15) & ~15; |
|
1448 align_buffer_64(src_argb_a, kStride * height + off); |
|
1449 align_buffer_64(src_argb_b, kStride * height + off); |
|
1450 align_buffer_64(dst_argb_c, kStride * height); |
|
1451 align_buffer_64(dst_argb_opt, kStride * height); |
|
1452 srandom(time(NULL)); |
|
1453 for (int i = 0; i < kStride * height; ++i) { |
|
1454 src_argb_a[i + off] = (random() & 0xff); |
|
1455 src_argb_b[i + off] = (random() & 0xff); |
|
1456 } |
|
1457 memset(dst_argb_c, 0, kStride * height); |
|
1458 memset(dst_argb_opt, 0, kStride * height); |
|
1459 |
|
1460 MaskCpuFlags(0); |
|
1461 ARGBAdd(src_argb_a + off, kStride, |
|
1462 src_argb_b + off, kStride, |
|
1463 dst_argb_c, kStride, |
|
1464 width, invert * height); |
|
1465 MaskCpuFlags(-1); |
|
1466 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1467 ARGBAdd(src_argb_a + off, kStride, |
|
1468 src_argb_b + off, kStride, |
|
1469 dst_argb_opt, kStride, |
|
1470 width, invert * height); |
|
1471 } |
|
1472 int max_diff = 0; |
|
1473 for (int i = 0; i < kStride * height; ++i) { |
|
1474 int abs_diff = |
|
1475 abs(static_cast<int>(dst_argb_c[i]) - |
|
1476 static_cast<int>(dst_argb_opt[i])); |
|
1477 if (abs_diff > max_diff) { |
|
1478 max_diff = abs_diff; |
|
1479 } |
|
1480 } |
|
1481 free_aligned_buffer_64(src_argb_a); |
|
1482 free_aligned_buffer_64(src_argb_b); |
|
1483 free_aligned_buffer_64(dst_argb_c); |
|
1484 free_aligned_buffer_64(dst_argb_opt); |
|
1485 return max_diff; |
|
1486 } |
|
1487 |
|
1488 TEST_F(libyuvTest, ARGBAdd_Any) { |
|
1489 int max_diff = TestAdd(benchmark_width_ - 1, benchmark_height_, |
|
1490 benchmark_iterations_, +1, 0); |
|
1491 EXPECT_LE(max_diff, 1); |
|
1492 } |
|
1493 |
|
1494 TEST_F(libyuvTest, ARGBAdd_Unaligned) { |
|
1495 int max_diff = TestAdd(benchmark_width_, benchmark_height_, |
|
1496 benchmark_iterations_, +1, 1); |
|
1497 EXPECT_LE(max_diff, 1); |
|
1498 } |
|
1499 |
|
1500 TEST_F(libyuvTest, ARGBAdd_Invert) { |
|
1501 int max_diff = TestAdd(benchmark_width_, benchmark_height_, |
|
1502 benchmark_iterations_, -1, 0); |
|
1503 EXPECT_LE(max_diff, 1); |
|
1504 } |
|
1505 |
|
1506 TEST_F(libyuvTest, ARGBAdd_Opt) { |
|
1507 int max_diff = TestAdd(benchmark_width_, benchmark_height_, |
|
1508 benchmark_iterations_, +1, 0); |
|
1509 EXPECT_LE(max_diff, 1); |
|
1510 } |
|
1511 |
|
1512 static int TestSubtract(int width, int height, int benchmark_iterations, |
|
1513 int invert, int off) { |
|
1514 if (width < 1) { |
|
1515 width = 1; |
|
1516 } |
|
1517 const int kBpp = 4; |
|
1518 const int kStride = (width * kBpp + 15) & ~15; |
|
1519 align_buffer_64(src_argb_a, kStride * height + off); |
|
1520 align_buffer_64(src_argb_b, kStride * height + off); |
|
1521 align_buffer_64(dst_argb_c, kStride * height); |
|
1522 align_buffer_64(dst_argb_opt, kStride * height); |
|
1523 srandom(time(NULL)); |
|
1524 for (int i = 0; i < kStride * height; ++i) { |
|
1525 src_argb_a[i + off] = (random() & 0xff); |
|
1526 src_argb_b[i + off] = (random() & 0xff); |
|
1527 } |
|
1528 memset(dst_argb_c, 0, kStride * height); |
|
1529 memset(dst_argb_opt, 0, kStride * height); |
|
1530 |
|
1531 MaskCpuFlags(0); |
|
1532 ARGBSubtract(src_argb_a + off, kStride, |
|
1533 src_argb_b + off, kStride, |
|
1534 dst_argb_c, kStride, |
|
1535 width, invert * height); |
|
1536 MaskCpuFlags(-1); |
|
1537 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1538 ARGBSubtract(src_argb_a + off, kStride, |
|
1539 src_argb_b + off, kStride, |
|
1540 dst_argb_opt, kStride, |
|
1541 width, invert * height); |
|
1542 } |
|
1543 int max_diff = 0; |
|
1544 for (int i = 0; i < kStride * height; ++i) { |
|
1545 int abs_diff = |
|
1546 abs(static_cast<int>(dst_argb_c[i]) - |
|
1547 static_cast<int>(dst_argb_opt[i])); |
|
1548 if (abs_diff > max_diff) { |
|
1549 max_diff = abs_diff; |
|
1550 } |
|
1551 } |
|
1552 free_aligned_buffer_64(src_argb_a); |
|
1553 free_aligned_buffer_64(src_argb_b); |
|
1554 free_aligned_buffer_64(dst_argb_c); |
|
1555 free_aligned_buffer_64(dst_argb_opt); |
|
1556 return max_diff; |
|
1557 } |
|
1558 |
|
1559 TEST_F(libyuvTest, ARGBSubtract_Any) { |
|
1560 int max_diff = TestSubtract(benchmark_width_ - 1, benchmark_height_, |
|
1561 benchmark_iterations_, +1, 0); |
|
1562 EXPECT_LE(max_diff, 1); |
|
1563 } |
|
1564 |
|
1565 TEST_F(libyuvTest, ARGBSubtract_Unaligned) { |
|
1566 int max_diff = TestSubtract(benchmark_width_, benchmark_height_, |
|
1567 benchmark_iterations_, +1, 1); |
|
1568 EXPECT_LE(max_diff, 1); |
|
1569 } |
|
1570 |
|
1571 TEST_F(libyuvTest, ARGBSubtract_Invert) { |
|
1572 int max_diff = TestSubtract(benchmark_width_, benchmark_height_, |
|
1573 benchmark_iterations_, -1, 0); |
|
1574 EXPECT_LE(max_diff, 1); |
|
1575 } |
|
1576 |
|
1577 TEST_F(libyuvTest, ARGBSubtract_Opt) { |
|
1578 int max_diff = TestSubtract(benchmark_width_, benchmark_height_, |
|
1579 benchmark_iterations_, +1, 0); |
|
1580 EXPECT_LE(max_diff, 1); |
|
1581 } |
|
1582 |
|
1583 static int TestSobel(int width, int height, int benchmark_iterations, |
|
1584 int invert, int off) { |
|
1585 if (width < 1) { |
|
1586 width = 1; |
|
1587 } |
|
1588 const int kBpp = 4; |
|
1589 const int kStride = (width * kBpp + 15) & ~15; |
|
1590 align_buffer_64(src_argb_a, kStride * height + off); |
|
1591 align_buffer_64(dst_argb_c, kStride * height); |
|
1592 align_buffer_64(dst_argb_opt, kStride * height); |
|
1593 memset(src_argb_a, 0, kStride * height + off); |
|
1594 srandom(time(NULL)); |
|
1595 for (int i = 0; i < kStride * height; ++i) { |
|
1596 src_argb_a[i + off] = (random() & 0xff); |
|
1597 } |
|
1598 memset(dst_argb_c, 0, kStride * height); |
|
1599 memset(dst_argb_opt, 0, kStride * height); |
|
1600 |
|
1601 MaskCpuFlags(0); |
|
1602 ARGBSobel(src_argb_a + off, kStride, |
|
1603 dst_argb_c, kStride, |
|
1604 width, invert * height); |
|
1605 MaskCpuFlags(-1); |
|
1606 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1607 ARGBSobel(src_argb_a + off, kStride, |
|
1608 dst_argb_opt, kStride, |
|
1609 width, invert * height); |
|
1610 } |
|
1611 int max_diff = 0; |
|
1612 for (int i = 0; i < kStride * height; ++i) { |
|
1613 int abs_diff = |
|
1614 abs(static_cast<int>(dst_argb_c[i]) - |
|
1615 static_cast<int>(dst_argb_opt[i])); |
|
1616 if (abs_diff > max_diff) { |
|
1617 max_diff = abs_diff; |
|
1618 } |
|
1619 } |
|
1620 free_aligned_buffer_64(src_argb_a); |
|
1621 free_aligned_buffer_64(dst_argb_c); |
|
1622 free_aligned_buffer_64(dst_argb_opt); |
|
1623 return max_diff; |
|
1624 } |
|
1625 |
|
1626 TEST_F(libyuvTest, ARGBSobel_Any) { |
|
1627 int max_diff = TestSobel(benchmark_width_ - 1, benchmark_height_, |
|
1628 benchmark_iterations_, +1, 0); |
|
1629 EXPECT_EQ(0, max_diff); |
|
1630 } |
|
1631 |
|
1632 TEST_F(libyuvTest, ARGBSobel_Unaligned) { |
|
1633 int max_diff = TestSobel(benchmark_width_, benchmark_height_, |
|
1634 benchmark_iterations_, +1, 1); |
|
1635 EXPECT_EQ(0, max_diff); |
|
1636 } |
|
1637 |
|
1638 TEST_F(libyuvTest, ARGBSobel_Invert) { |
|
1639 int max_diff = TestSobel(benchmark_width_, benchmark_height_, |
|
1640 benchmark_iterations_, -1, 0); |
|
1641 EXPECT_EQ(0, max_diff); |
|
1642 } |
|
1643 |
|
1644 TEST_F(libyuvTest, ARGBSobel_Opt) { |
|
1645 int max_diff = TestSobel(benchmark_width_, benchmark_height_, |
|
1646 benchmark_iterations_, +1, 0); |
|
1647 EXPECT_EQ(0, max_diff); |
|
1648 } |
|
1649 |
|
1650 static int TestSobelToPlane(int width, int height, int benchmark_iterations, |
|
1651 int invert, int off) { |
|
1652 if (width < 1) { |
|
1653 width = 1; |
|
1654 } |
|
1655 const int kSrcBpp = 4; |
|
1656 const int kDstBpp = 1; |
|
1657 const int kSrcStride = (width * kSrcBpp + 15) & ~15; |
|
1658 const int kDstStride = (width * kDstBpp + 15) & ~15; |
|
1659 align_buffer_64(src_argb_a, kSrcStride * height + off); |
|
1660 align_buffer_64(dst_argb_c, kDstStride * height); |
|
1661 align_buffer_64(dst_argb_opt, kDstStride * height); |
|
1662 memset(src_argb_a, 0, kSrcStride * height + off); |
|
1663 srandom(time(NULL)); |
|
1664 for (int i = 0; i < kSrcStride * height; ++i) { |
|
1665 src_argb_a[i + off] = (random() & 0xff); |
|
1666 } |
|
1667 memset(dst_argb_c, 0, kDstStride * height); |
|
1668 memset(dst_argb_opt, 0, kDstStride * height); |
|
1669 |
|
1670 MaskCpuFlags(0); |
|
1671 ARGBSobelToPlane(src_argb_a + off, kSrcStride, |
|
1672 dst_argb_c, kDstStride, |
|
1673 width, invert * height); |
|
1674 MaskCpuFlags(-1); |
|
1675 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1676 ARGBSobelToPlane(src_argb_a + off, kSrcStride, |
|
1677 dst_argb_opt, kDstStride, |
|
1678 width, invert * height); |
|
1679 } |
|
1680 int max_diff = 0; |
|
1681 for (int i = 0; i < kDstStride * height; ++i) { |
|
1682 int abs_diff = |
|
1683 abs(static_cast<int>(dst_argb_c[i]) - |
|
1684 static_cast<int>(dst_argb_opt[i])); |
|
1685 if (abs_diff > max_diff) { |
|
1686 max_diff = abs_diff; |
|
1687 } |
|
1688 } |
|
1689 free_aligned_buffer_64(src_argb_a); |
|
1690 free_aligned_buffer_64(dst_argb_c); |
|
1691 free_aligned_buffer_64(dst_argb_opt); |
|
1692 return max_diff; |
|
1693 } |
|
1694 |
|
1695 TEST_F(libyuvTest, ARGBSobelToPlane_Any) { |
|
1696 int max_diff = TestSobelToPlane(benchmark_width_ - 1, benchmark_height_, |
|
1697 benchmark_iterations_, +1, 0); |
|
1698 EXPECT_EQ(0, max_diff); |
|
1699 } |
|
1700 |
|
1701 TEST_F(libyuvTest, ARGBSobelToPlane_Unaligned) { |
|
1702 int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_, |
|
1703 benchmark_iterations_, +1, 1); |
|
1704 EXPECT_EQ(0, max_diff); |
|
1705 } |
|
1706 |
|
1707 TEST_F(libyuvTest, ARGBSobelToPlane_Invert) { |
|
1708 int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_, |
|
1709 benchmark_iterations_, -1, 0); |
|
1710 EXPECT_EQ(0, max_diff); |
|
1711 } |
|
1712 |
|
1713 TEST_F(libyuvTest, ARGBSobelToPlane_Opt) { |
|
1714 int max_diff = TestSobelToPlane(benchmark_width_, benchmark_height_, |
|
1715 benchmark_iterations_, +1, 0); |
|
1716 EXPECT_EQ(0, max_diff); |
|
1717 } |
|
1718 |
|
1719 static int TestSobelXY(int width, int height, int benchmark_iterations, |
|
1720 int invert, int off) { |
|
1721 if (width < 1) { |
|
1722 width = 1; |
|
1723 } |
|
1724 const int kBpp = 4; |
|
1725 const int kStride = (width * kBpp + 15) & ~15; |
|
1726 align_buffer_64(src_argb_a, kStride * height + off); |
|
1727 align_buffer_64(dst_argb_c, kStride * height); |
|
1728 align_buffer_64(dst_argb_opt, kStride * height); |
|
1729 memset(src_argb_a, 0, kStride * height + off); |
|
1730 srandom(time(NULL)); |
|
1731 for (int i = 0; i < kStride * height; ++i) { |
|
1732 src_argb_a[i + off] = (random() & 0xff); |
|
1733 } |
|
1734 memset(dst_argb_c, 0, kStride * height); |
|
1735 memset(dst_argb_opt, 0, kStride * height); |
|
1736 |
|
1737 MaskCpuFlags(0); |
|
1738 ARGBSobelXY(src_argb_a + off, kStride, |
|
1739 dst_argb_c, kStride, |
|
1740 width, invert * height); |
|
1741 MaskCpuFlags(-1); |
|
1742 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1743 ARGBSobelXY(src_argb_a + off, kStride, |
|
1744 dst_argb_opt, kStride, |
|
1745 width, invert * height); |
|
1746 } |
|
1747 int max_diff = 0; |
|
1748 for (int i = 0; i < kStride * height; ++i) { |
|
1749 int abs_diff = |
|
1750 abs(static_cast<int>(dst_argb_c[i]) - |
|
1751 static_cast<int>(dst_argb_opt[i])); |
|
1752 if (abs_diff > max_diff) { |
|
1753 max_diff = abs_diff; |
|
1754 } |
|
1755 } |
|
1756 free_aligned_buffer_64(src_argb_a); |
|
1757 free_aligned_buffer_64(dst_argb_c); |
|
1758 free_aligned_buffer_64(dst_argb_opt); |
|
1759 return max_diff; |
|
1760 } |
|
1761 |
|
1762 TEST_F(libyuvTest, ARGBSobelXY_Any) { |
|
1763 int max_diff = TestSobelXY(benchmark_width_ - 1, benchmark_height_, |
|
1764 benchmark_iterations_, +1, 0); |
|
1765 EXPECT_EQ(0, max_diff); |
|
1766 } |
|
1767 |
|
1768 TEST_F(libyuvTest, ARGBSobelXY_Unaligned) { |
|
1769 int max_diff = TestSobelXY(benchmark_width_, benchmark_height_, |
|
1770 benchmark_iterations_, +1, 1); |
|
1771 EXPECT_EQ(0, max_diff); |
|
1772 } |
|
1773 |
|
1774 TEST_F(libyuvTest, ARGBSobelXY_Invert) { |
|
1775 int max_diff = TestSobelXY(benchmark_width_, benchmark_height_, |
|
1776 benchmark_iterations_, -1, 0); |
|
1777 EXPECT_EQ(0, max_diff); |
|
1778 } |
|
1779 |
|
1780 TEST_F(libyuvTest, ARGBSobelXY_Opt) { |
|
1781 int max_diff = TestSobelXY(benchmark_width_, benchmark_height_, |
|
1782 benchmark_iterations_, +1, 0); |
|
1783 EXPECT_EQ(0, max_diff); |
|
1784 } |
|
1785 |
|
1786 static int TestBlur(int width, int height, int benchmark_iterations, |
|
1787 int invert, int off, int radius) { |
|
1788 if (width < 1) { |
|
1789 width = 1; |
|
1790 } |
|
1791 const int kBpp = 4; |
|
1792 const int kStride = (width * kBpp + 15) & ~15; |
|
1793 align_buffer_64(src_argb_a, kStride * height + off); |
|
1794 align_buffer_64(dst_cumsum, width * height * 16); |
|
1795 align_buffer_64(dst_argb_c, kStride * height); |
|
1796 align_buffer_64(dst_argb_opt, kStride * height); |
|
1797 srandom(time(NULL)); |
|
1798 for (int i = 0; i < kStride * height; ++i) { |
|
1799 src_argb_a[i + off] = (random() & 0xff); |
|
1800 } |
|
1801 memset(dst_cumsum, 0, width * height * 16); |
|
1802 memset(dst_argb_c, 0, kStride * height); |
|
1803 memset(dst_argb_opt, 0, kStride * height); |
|
1804 |
|
1805 MaskCpuFlags(0); |
|
1806 ARGBBlur(src_argb_a + off, kStride, |
|
1807 dst_argb_c, kStride, |
|
1808 reinterpret_cast<int32*>(dst_cumsum), width * 4, |
|
1809 width, invert * height, radius); |
|
1810 MaskCpuFlags(-1); |
|
1811 for (int i = 0; i < benchmark_iterations; ++i) { |
|
1812 ARGBBlur(src_argb_a + off, kStride, |
|
1813 dst_argb_opt, kStride, |
|
1814 reinterpret_cast<int32*>(dst_cumsum), width * 4, |
|
1815 width, invert * height, radius); |
|
1816 } |
|
1817 int max_diff = 0; |
|
1818 for (int i = 0; i < kStride * height; ++i) { |
|
1819 int abs_diff = |
|
1820 abs(static_cast<int>(dst_argb_c[i]) - |
|
1821 static_cast<int>(dst_argb_opt[i])); |
|
1822 if (abs_diff > max_diff) { |
|
1823 max_diff = abs_diff; |
|
1824 } |
|
1825 } |
|
1826 free_aligned_buffer_64(src_argb_a); |
|
1827 free_aligned_buffer_64(dst_cumsum); |
|
1828 free_aligned_buffer_64(dst_argb_c); |
|
1829 free_aligned_buffer_64(dst_argb_opt); |
|
1830 return max_diff; |
|
1831 } |
|
1832 |
|
1833 static const int kBlurSize = 55; |
|
1834 TEST_F(libyuvTest, ARGBBlur_Any) { |
|
1835 int max_diff = TestBlur(benchmark_width_ - 1, benchmark_height_, |
|
1836 benchmark_iterations_, +1, 0, kBlurSize); |
|
1837 EXPECT_LE(max_diff, 1); |
|
1838 } |
|
1839 |
|
1840 TEST_F(libyuvTest, ARGBBlur_Unaligned) { |
|
1841 int max_diff = TestBlur(benchmark_width_, benchmark_height_, |
|
1842 benchmark_iterations_, +1, 1, kBlurSize); |
|
1843 EXPECT_LE(max_diff, 1); |
|
1844 } |
|
1845 |
|
1846 TEST_F(libyuvTest, ARGBBlur_Invert) { |
|
1847 int max_diff = TestBlur(benchmark_width_, benchmark_height_, |
|
1848 benchmark_iterations_, -1, 0, kBlurSize); |
|
1849 EXPECT_LE(max_diff, 1); |
|
1850 } |
|
1851 |
|
1852 TEST_F(libyuvTest, ARGBBlur_Opt) { |
|
1853 int max_diff = TestBlur(benchmark_width_, benchmark_height_, |
|
1854 benchmark_iterations_, +1, 0, kBlurSize); |
|
1855 EXPECT_LE(max_diff, 1); |
|
1856 } |
|
1857 |
|
1858 static const int kBlurSmallSize = 5; |
|
1859 TEST_F(libyuvTest, ARGBBlurSmall_Any) { |
|
1860 int max_diff = TestBlur(benchmark_width_ - 1, benchmark_height_, |
|
1861 benchmark_iterations_, +1, 0, kBlurSmallSize); |
|
1862 EXPECT_LE(max_diff, 1); |
|
1863 } |
|
1864 |
|
1865 TEST_F(libyuvTest, ARGBBlurSmall_Unaligned) { |
|
1866 int max_diff = TestBlur(benchmark_width_, benchmark_height_, |
|
1867 benchmark_iterations_, +1, 1, kBlurSmallSize); |
|
1868 EXPECT_LE(max_diff, 1); |
|
1869 } |
|
1870 |
|
1871 TEST_F(libyuvTest, ARGBBlurSmall_Invert) { |
|
1872 int max_diff = TestBlur(benchmark_width_, benchmark_height_, |
|
1873 benchmark_iterations_, -1, 0, kBlurSmallSize); |
|
1874 EXPECT_LE(max_diff, 1); |
|
1875 } |
|
1876 |
|
1877 TEST_F(libyuvTest, ARGBBlurSmall_Opt) { |
|
1878 int max_diff = TestBlur(benchmark_width_, benchmark_height_, |
|
1879 benchmark_iterations_, +1, 0, kBlurSmallSize); |
|
1880 EXPECT_LE(max_diff, 1); |
|
1881 } |
|
1882 |
|
1883 TEST_F(libyuvTest, TestARGBPolynomial) { |
|
1884 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
1885 SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); |
|
1886 SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); |
|
1887 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
1888 |
|
1889 SIMD_ALIGNED(static const float kWarmifyPolynomial[16]) = { |
|
1890 0.94230f, -3.03300f, -2.92500f, 0.f, // C0 |
|
1891 0.584500f, 1.112000f, 1.535000f, 1.f, // C1 x |
|
1892 0.001313f, -0.002503f, -0.004496f, 0.f, // C2 x * x |
|
1893 0.0f, 0.000006965f, 0.000008781f, 0.f, // C3 x * x * x |
|
1894 }; |
|
1895 |
|
1896 // Test blue |
|
1897 orig_pixels[0][0] = 255u; |
|
1898 orig_pixels[0][1] = 0u; |
|
1899 orig_pixels[0][2] = 0u; |
|
1900 orig_pixels[0][3] = 128u; |
|
1901 // Test green |
|
1902 orig_pixels[1][0] = 0u; |
|
1903 orig_pixels[1][1] = 255u; |
|
1904 orig_pixels[1][2] = 0u; |
|
1905 orig_pixels[1][3] = 0u; |
|
1906 // Test red |
|
1907 orig_pixels[2][0] = 0u; |
|
1908 orig_pixels[2][1] = 0u; |
|
1909 orig_pixels[2][2] = 255u; |
|
1910 orig_pixels[2][3] = 255u; |
|
1911 // Test white |
|
1912 orig_pixels[3][0] = 255u; |
|
1913 orig_pixels[3][1] = 255u; |
|
1914 orig_pixels[3][2] = 255u; |
|
1915 orig_pixels[3][3] = 255u; |
|
1916 // Test color |
|
1917 orig_pixels[4][0] = 16u; |
|
1918 orig_pixels[4][1] = 64u; |
|
1919 orig_pixels[4][2] = 192u; |
|
1920 orig_pixels[4][3] = 224u; |
|
1921 // Do 16 to test asm version. |
|
1922 ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, |
|
1923 &kWarmifyPolynomial[0], 16, 1); |
|
1924 EXPECT_EQ(235u, dst_pixels_opt[0][0]); |
|
1925 EXPECT_EQ(0u, dst_pixels_opt[0][1]); |
|
1926 EXPECT_EQ(0u, dst_pixels_opt[0][2]); |
|
1927 EXPECT_EQ(128u, dst_pixels_opt[0][3]); |
|
1928 EXPECT_EQ(0u, dst_pixels_opt[1][0]); |
|
1929 EXPECT_EQ(233u, dst_pixels_opt[1][1]); |
|
1930 EXPECT_EQ(0u, dst_pixels_opt[1][2]); |
|
1931 EXPECT_EQ(0u, dst_pixels_opt[1][3]); |
|
1932 EXPECT_EQ(0u, dst_pixels_opt[2][0]); |
|
1933 EXPECT_EQ(0u, dst_pixels_opt[2][1]); |
|
1934 EXPECT_EQ(241u, dst_pixels_opt[2][2]); |
|
1935 EXPECT_EQ(255u, dst_pixels_opt[2][3]); |
|
1936 EXPECT_EQ(235u, dst_pixels_opt[3][0]); |
|
1937 EXPECT_EQ(233u, dst_pixels_opt[3][1]); |
|
1938 EXPECT_EQ(241u, dst_pixels_opt[3][2]); |
|
1939 EXPECT_EQ(255u, dst_pixels_opt[3][3]); |
|
1940 EXPECT_EQ(10u, dst_pixels_opt[4][0]); |
|
1941 EXPECT_EQ(59u, dst_pixels_opt[4][1]); |
|
1942 EXPECT_EQ(188u, dst_pixels_opt[4][2]); |
|
1943 EXPECT_EQ(224u, dst_pixels_opt[4][3]); |
|
1944 |
|
1945 for (int i = 0; i < 1280; ++i) { |
|
1946 orig_pixels[i][0] = i; |
|
1947 orig_pixels[i][1] = i / 2; |
|
1948 orig_pixels[i][2] = i / 3; |
|
1949 orig_pixels[i][3] = i; |
|
1950 } |
|
1951 |
|
1952 MaskCpuFlags(0); |
|
1953 ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0, |
|
1954 &kWarmifyPolynomial[0], 1280, 1); |
|
1955 MaskCpuFlags(-1); |
|
1956 |
|
1957 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
1958 ARGBPolynomial(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, |
|
1959 &kWarmifyPolynomial[0], 1280, 1); |
|
1960 } |
|
1961 |
|
1962 for (int i = 0; i < 1280; ++i) { |
|
1963 EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]); |
|
1964 EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]); |
|
1965 EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]); |
|
1966 EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]); |
|
1967 } |
|
1968 } |
|
1969 |
|
1970 TEST_F(libyuvTest, TestARGBLumaColorTable) { |
|
1971 SIMD_ALIGNED(uint8 orig_pixels[1280][4]); |
|
1972 SIMD_ALIGNED(uint8 dst_pixels_opt[1280][4]); |
|
1973 SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); |
|
1974 memset(orig_pixels, 0, sizeof(orig_pixels)); |
|
1975 |
|
1976 align_buffer_64(lumacolortable, 32768); |
|
1977 int v = 0; |
|
1978 for (int i = 0; i < 32768; ++i) { |
|
1979 lumacolortable[i] = v; |
|
1980 v += 3; |
|
1981 } |
|
1982 // Test blue |
|
1983 orig_pixels[0][0] = 255u; |
|
1984 orig_pixels[0][1] = 0u; |
|
1985 orig_pixels[0][2] = 0u; |
|
1986 orig_pixels[0][3] = 128u; |
|
1987 // Test green |
|
1988 orig_pixels[1][0] = 0u; |
|
1989 orig_pixels[1][1] = 255u; |
|
1990 orig_pixels[1][2] = 0u; |
|
1991 orig_pixels[1][3] = 0u; |
|
1992 // Test red |
|
1993 orig_pixels[2][0] = 0u; |
|
1994 orig_pixels[2][1] = 0u; |
|
1995 orig_pixels[2][2] = 255u; |
|
1996 orig_pixels[2][3] = 255u; |
|
1997 // Test color |
|
1998 orig_pixels[3][0] = 16u; |
|
1999 orig_pixels[3][1] = 64u; |
|
2000 orig_pixels[3][2] = 192u; |
|
2001 orig_pixels[3][3] = 224u; |
|
2002 // Do 16 to test asm version. |
|
2003 ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, |
|
2004 &lumacolortable[0], 16, 1); |
|
2005 EXPECT_EQ(253u, dst_pixels_opt[0][0]); |
|
2006 EXPECT_EQ(0u, dst_pixels_opt[0][1]); |
|
2007 EXPECT_EQ(0u, dst_pixels_opt[0][2]); |
|
2008 EXPECT_EQ(128u, dst_pixels_opt[0][3]); |
|
2009 EXPECT_EQ(0u, dst_pixels_opt[1][0]); |
|
2010 EXPECT_EQ(253u, dst_pixels_opt[1][1]); |
|
2011 EXPECT_EQ(0u, dst_pixels_opt[1][2]); |
|
2012 EXPECT_EQ(0u, dst_pixels_opt[1][3]); |
|
2013 EXPECT_EQ(0u, dst_pixels_opt[2][0]); |
|
2014 EXPECT_EQ(0u, dst_pixels_opt[2][1]); |
|
2015 EXPECT_EQ(253u, dst_pixels_opt[2][2]); |
|
2016 EXPECT_EQ(255u, dst_pixels_opt[2][3]); |
|
2017 EXPECT_EQ(48u, dst_pixels_opt[3][0]); |
|
2018 EXPECT_EQ(192u, dst_pixels_opt[3][1]); |
|
2019 EXPECT_EQ(64u, dst_pixels_opt[3][2]); |
|
2020 EXPECT_EQ(224u, dst_pixels_opt[3][3]); |
|
2021 |
|
2022 for (int i = 0; i < 1280; ++i) { |
|
2023 orig_pixels[i][0] = i; |
|
2024 orig_pixels[i][1] = i / 2; |
|
2025 orig_pixels[i][2] = i / 3; |
|
2026 orig_pixels[i][3] = i; |
|
2027 } |
|
2028 |
|
2029 MaskCpuFlags(0); |
|
2030 ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_c[0][0], 0, |
|
2031 lumacolortable, 1280, 1); |
|
2032 MaskCpuFlags(-1); |
|
2033 |
|
2034 for (int i = 0; i < benchmark_pixels_div1280_; ++i) { |
|
2035 ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels_opt[0][0], 0, |
|
2036 lumacolortable, 1280, 1); |
|
2037 } |
|
2038 for (int i = 0; i < 1280; ++i) { |
|
2039 EXPECT_EQ(dst_pixels_c[i][0], dst_pixels_opt[i][0]); |
|
2040 EXPECT_EQ(dst_pixels_c[i][1], dst_pixels_opt[i][1]); |
|
2041 EXPECT_EQ(dst_pixels_c[i][2], dst_pixels_opt[i][2]); |
|
2042 EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]); |
|
2043 } |
|
2044 |
|
2045 free_aligned_buffer_64(lumacolortable); |
|
2046 } |
|
2047 |
|
2048 TEST_F(libyuvTest, TestARGBCopyAlpha) { |
|
2049 const int kSize = benchmark_width_ * benchmark_height_ * 4; |
|
2050 align_buffer_64(orig_pixels, kSize); |
|
2051 align_buffer_64(dst_pixels_opt, kSize); |
|
2052 align_buffer_64(dst_pixels_c, kSize); |
|
2053 |
|
2054 MemRandomize(orig_pixels, kSize); |
|
2055 MemRandomize(dst_pixels_opt, kSize); |
|
2056 memcpy(dst_pixels_c, dst_pixels_opt, kSize); |
|
2057 |
|
2058 MaskCpuFlags(0); |
|
2059 ARGBCopyAlpha(orig_pixels, benchmark_width_ * 4, |
|
2060 dst_pixels_c, benchmark_width_ * 4, |
|
2061 benchmark_width_, benchmark_height_); |
|
2062 MaskCpuFlags(-1); |
|
2063 |
|
2064 for (int i = 0; i < benchmark_iterations_; ++i) { |
|
2065 ARGBCopyAlpha(orig_pixels, benchmark_width_ * 4, |
|
2066 dst_pixels_opt, benchmark_width_ * 4, |
|
2067 benchmark_width_, benchmark_height_); |
|
2068 } |
|
2069 for (int i = 0; i < kSize; ++i) { |
|
2070 EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]); |
|
2071 } |
|
2072 |
|
2073 free_aligned_buffer_64(dst_pixels_c); |
|
2074 free_aligned_buffer_64(dst_pixels_opt); |
|
2075 free_aligned_buffer_64(orig_pixels); |
|
2076 } |
|
2077 |
|
2078 TEST_F(libyuvTest, TestARGBCopyYToAlpha) { |
|
2079 const int kPixels = benchmark_width_ * benchmark_height_; |
|
2080 align_buffer_64(orig_pixels, kPixels); |
|
2081 align_buffer_64(dst_pixels_opt, kPixels * 4); |
|
2082 align_buffer_64(dst_pixels_c, kPixels * 4); |
|
2083 |
|
2084 MemRandomize(orig_pixels, kPixels); |
|
2085 MemRandomize(dst_pixels_opt, kPixels * 4); |
|
2086 memcpy(dst_pixels_c, dst_pixels_opt, kPixels * 4); |
|
2087 |
|
2088 MaskCpuFlags(0); |
|
2089 ARGBCopyYToAlpha(orig_pixels, benchmark_width_, |
|
2090 dst_pixels_c, benchmark_width_ * 4, |
|
2091 benchmark_width_, benchmark_height_); |
|
2092 MaskCpuFlags(-1); |
|
2093 |
|
2094 for (int i = 0; i < benchmark_iterations_; ++i) { |
|
2095 ARGBCopyYToAlpha(orig_pixels, benchmark_width_, |
|
2096 dst_pixels_opt, benchmark_width_ * 4, |
|
2097 benchmark_width_, benchmark_height_); |
|
2098 } |
|
2099 for (int i = 0; i < kPixels * 4; ++i) { |
|
2100 EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]); |
|
2101 } |
|
2102 |
|
2103 free_aligned_buffer_64(dst_pixels_c); |
|
2104 free_aligned_buffer_64(dst_pixels_opt); |
|
2105 free_aligned_buffer_64(orig_pixels); |
|
2106 } |
|
2107 |
|
2108 } // namespace libyuv |