1 /*
2 * Copyright 2012 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/cpu_id.h"
15 #include "libyuv/rotate_argb.h"
16 #include "../unit_test/unit_test.h"
17
18 namespace libyuv {
19
ARGBTestRotate(int src_width,int src_height,int dst_width,int dst_height,libyuv::RotationMode mode,int runs)20 static int ARGBTestRotate(int src_width, int src_height,
21 int dst_width, int dst_height,
22 libyuv::RotationMode mode, int runs) {
23 const int b = 128;
24 int src_argb_plane_size = (src_width + b * 2) * (src_height + b * 2) * 4;
25 int src_stride_argb = (b * 2 + src_width) * 4;
26
27 align_buffer_16(src_argb, src_argb_plane_size)
28 memset(src_argb, 1, src_argb_plane_size);
29
30 int dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4;
31 int dst_stride_argb = (b * 2 + dst_width) * 4;
32
33 srandom(time(NULL));
34
35 int i, j;
36 for (i = b; i < (src_height + b); ++i) {
37 for (j = b; j < (src_width + b) * 4; ++j) {
38 src_argb[(i * src_stride_argb) + j] = (random() & 0xff);
39 }
40 }
41
42 align_buffer_16(dst_argb_c, dst_argb_plane_size)
43 align_buffer_16(dst_argb_opt, dst_argb_plane_size)
44 memset(dst_argb_c, 2, dst_argb_plane_size);
45 memset(dst_argb_opt, 3, dst_argb_plane_size);
46
47 // Warm up both versions for consistent benchmarks.
48 MaskCpuFlags(0); // Disable all CPU optimization.
49 ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
50 dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
51 src_width, src_height, mode);
52 MaskCpuFlags(-1); // Enable all CPU optimization.
53 ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
54 dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
55 src_width, src_height, mode);
56
57 MaskCpuFlags(0); // Disable all CPU optimization.
58 double c_time = get_time();
59 for (i = 0; i < runs; ++i) {
60 ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
61 dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
62 src_width, src_height, mode);
63 }
64 c_time = (get_time() - c_time) / runs;
65
66 MaskCpuFlags(-1); // Enable all CPU optimization.
67 double opt_time = get_time();
68 for (i = 0; i < runs; ++i) {
69 ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
70 dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
71 src_width, src_height, mode);
72 }
73 opt_time = (get_time() - opt_time) / runs;
74
75 // Report performance of C vs OPT
76 printf("filter %d - %8d us C - %8d us OPT\n",
77 mode, static_cast<int>(c_time*1e6), static_cast<int>(opt_time*1e6));
78
79 // C version may be a little off from the optimized. Order of
80 // operations may introduce rounding somewhere. So do a difference
81 // of the buffers and look to see that the max difference isn't
82 // over 2.
83 int max_diff = 0;
84 for (i = b; i < (dst_height + b); ++i) {
85 for (j = b * 4; j < (dst_width + b) * 4; ++j) {
86 int abs_diff = abs(dst_argb_c[(i * dst_stride_argb) + j] -
87 dst_argb_opt[(i * dst_stride_argb) + j]);
88 if (abs_diff > max_diff)
89 max_diff = abs_diff;
90 }
91 }
92
93 free_aligned_buffer_16(dst_argb_c)
94 free_aligned_buffer_16(dst_argb_opt)
95 free_aligned_buffer_16(src_argb)
96 return max_diff;
97 }
98
TEST_F(libyuvTest,ARGBRotate0)99 TEST_F(libyuvTest, ARGBRotate0) {
100 const int src_width = 1280;
101 const int src_height = 720;
102 const int dst_width = 1280;
103 const int dst_height = 720;
104
105 int err = ARGBTestRotate(src_width, src_height,
106 dst_width, dst_height, kRotate0,
107 benchmark_iterations_);
108 EXPECT_GE(1, err);
109 }
110
TEST_F(libyuvTest,ARGBRotate90)111 TEST_F(libyuvTest, ARGBRotate90) {
112 const int src_width = 1280;
113 const int src_height = 720;
114 const int dst_width = 720;
115 const int dst_height = 1280;
116
117 int err = ARGBTestRotate(src_width, src_height,
118 dst_width, dst_height, kRotate90,
119 benchmark_iterations_);
120 EXPECT_GE(1, err);
121 }
122
TEST_F(libyuvTest,ARGBRotate180)123 TEST_F(libyuvTest, ARGBRotate180) {
124 const int src_width = 1280;
125 const int src_height = 720;
126 const int dst_width = 1280;
127 const int dst_height = 720;
128
129 int err = ARGBTestRotate(src_width, src_height,
130 dst_width, dst_height, kRotate180,
131 benchmark_iterations_);
132 EXPECT_GE(1, err);
133 }
134
TEST_F(libyuvTest,ARGBRotate270)135 TEST_F(libyuvTest, ARGBRotate270) {
136 const int src_width = 1280;
137 const int src_height = 720;
138 const int dst_width = 720;
139 const int dst_height = 1280;
140
141 int err = ARGBTestRotate(src_width, src_height,
142 dst_width, dst_height, kRotate270,
143 benchmark_iterations_);
144 EXPECT_GE(1, err);
145 }
146
TEST_F(libyuvTest,ARGBRotate0_Odd)147 TEST_F(libyuvTest, ARGBRotate0_Odd) {
148 const int src_width = 1277;
149 const int src_height = 719;
150 const int dst_width = 1277;
151 const int dst_height = 719;
152
153 int err = ARGBTestRotate(src_width, src_height,
154 dst_width, dst_height, kRotate0,
155 benchmark_iterations_);
156 EXPECT_GE(1, err);
157 }
158
TEST_F(libyuvTest,ARGBRotate90_Odd)159 TEST_F(libyuvTest, ARGBRotate90_Odd) {
160 const int src_width = 1277;
161 const int src_height = 719;
162 const int dst_width = 719;
163 const int dst_height = 1277;
164
165 int err = ARGBTestRotate(src_width, src_height,
166 dst_width, dst_height, kRotate90,
167 benchmark_iterations_);
168 EXPECT_GE(1, err);
169 }
170
TEST_F(libyuvTest,ARGBRotate180_Odd)171 TEST_F(libyuvTest, ARGBRotate180_Odd) {
172 const int src_width = 1277;
173 const int src_height = 719;
174 const int dst_width = 1277;
175 const int dst_height = 719;
176
177 int err = ARGBTestRotate(src_width, src_height,
178 dst_width, dst_height, kRotate180,
179 benchmark_iterations_);
180 EXPECT_GE(1, err);
181 }
182
TEST_F(libyuvTest,ARGBRotate270_Odd)183 TEST_F(libyuvTest, ARGBRotate270_Odd) {
184 const int src_width = 1277;
185 const int src_height = 719;
186 const int dst_width = 719;
187 const int dst_height = 1277;
188
189 int err = ARGBTestRotate(src_width, src_height,
190 dst_width, dst_height, kRotate270,
191 benchmark_iterations_);
192 EXPECT_GE(1, err);
193 }
194
195 } // namespace libyuv
196