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