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/cpu_id.h"
15 #include "libyuv/scale_argb.h"
16 #include "../unit_test/unit_test.h"
17
18 namespace libyuv {
19
ARGBTestFilter(int src_width,int src_height,int dst_width,int dst_height,FilterMode f,int benchmark_iterations)20 static int ARGBTestFilter(int src_width, int src_height,
21 int dst_width, int dst_height,
22 FilterMode f, int benchmark_iterations) {
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 ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
50 src_width, src_height,
51 dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
52 dst_width, dst_height, f);
53 MaskCpuFlags(-1); // Enable all CPU optimization.
54 ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
55 src_width, src_height,
56 dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
57 dst_width, dst_height, f);
58
59 MaskCpuFlags(0); // Disable all CPU optimization.
60 double c_time = get_time();
61 for (i = 0; i < benchmark_iterations; ++i) {
62 ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
63 src_width, src_height,
64 dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb,
65 dst_width, dst_height, f);
66 }
67 c_time = (get_time() - c_time) / benchmark_iterations;
68
69 MaskCpuFlags(-1); // Enable all CPU optimization.
70 double opt_time = get_time();
71 for (i = 0; i < benchmark_iterations; ++i) {
72 ARGBScale(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb,
73 src_width, src_height,
74 dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb,
75 dst_width, dst_height, f);
76 }
77 opt_time = (get_time() - opt_time) / benchmark_iterations;
78
79 // Report performance of C vs OPT
80 printf("filter %d - %8d us C - %8d us OPT\n",
81 f, static_cast<int>(c_time*1e6), static_cast<int>(opt_time*1e6));
82
83 // C version may be a little off from the optimized. Order of
84 // operations may introduce rounding somewhere. So do a difference
85 // of the buffers and look to see that the max difference isn't
86 // over 2.
87 int max_diff = 0;
88 for (i = b; i < (dst_height + b); ++i) {
89 for (j = b * 4; j < (dst_width + b) * 4; ++j) {
90 int abs_diff = abs(dst_argb_c[(i * dst_stride_argb) + j] -
91 dst_argb_opt[(i * dst_stride_argb) + j]);
92 if (abs_diff > max_diff) {
93 max_diff = abs_diff;
94 }
95 }
96 }
97
98 free_aligned_buffer_16(dst_argb_c)
99 free_aligned_buffer_16(dst_argb_opt)
100 free_aligned_buffer_16(src_argb)
101 return max_diff;
102 }
103
TEST_F(libyuvTest,ARGBScaleDownBy2)104 TEST_F(libyuvTest, ARGBScaleDownBy2) {
105 const int src_width = 1280;
106 const int src_height = 720;
107 const int dst_width = src_width / 2;
108 const int dst_height = src_height / 2;
109
110 for (int f = 0; f < 2; ++f) {
111 int max_diff = ARGBTestFilter(src_width, src_height,
112 dst_width, dst_height,
113 static_cast<FilterMode>(f),
114 benchmark_iterations_);
115 EXPECT_LE(max_diff, 1);
116 }
117 }
118
TEST_F(libyuvTest,ARGBScaleDownBy4)119 TEST_F(libyuvTest, ARGBScaleDownBy4) {
120 const int src_width = 1280;
121 const int src_height = 720;
122 const int dst_width = src_width / 4;
123 const int dst_height = src_height / 4;
124
125 for (int f = 0; f < 2; ++f) {
126 int max_diff = ARGBTestFilter(src_width, src_height,
127 dst_width, dst_height,
128 static_cast<FilterMode>(f),
129 benchmark_iterations_);
130 EXPECT_LE(max_diff, 1);
131 }
132 }
133
TEST_F(libyuvTest,ARGBScaleDownBy5)134 TEST_F(libyuvTest, ARGBScaleDownBy5) {
135 const int src_width = 1280;
136 const int src_height = 720;
137 const int dst_width = src_width / 5;
138 const int dst_height = src_height / 5;
139
140 for (int f = 0; f < 2; ++f) {
141 int max_diff = ARGBTestFilter(src_width, src_height,
142 dst_width, dst_height,
143 static_cast<FilterMode>(f),
144 benchmark_iterations_);
145 EXPECT_LE(max_diff, 1);
146 }
147 }
148
TEST_F(libyuvTest,ARGBScaleDownBy8)149 TEST_F(libyuvTest, ARGBScaleDownBy8) {
150 const int src_width = 1280;
151 const int src_height = 720;
152 const int dst_width = src_width / 8;
153 const int dst_height = src_height / 8;
154
155 for (int f = 0; f < 2; ++f) {
156 int max_diff = ARGBTestFilter(src_width, src_height,
157 dst_width, dst_height,
158 static_cast<FilterMode>(f),
159 benchmark_iterations_);
160 EXPECT_LE(max_diff, 1);
161 }
162 }
163
TEST_F(libyuvTest,ARGBScaleDownBy16)164 TEST_F(libyuvTest, ARGBScaleDownBy16) {
165 const int src_width = 1280;
166 const int src_height = 720;
167 const int dst_width = src_width / 16;
168 const int dst_height = src_height / 16;
169
170 for (int f = 0; f < 2; ++f) {
171 int max_diff = ARGBTestFilter(src_width, src_height,
172 dst_width, dst_height,
173 static_cast<FilterMode>(f),
174 benchmark_iterations_);
175 EXPECT_LE(max_diff, 1);
176 }
177 }
178
TEST_F(libyuvTest,ARGBScaleDownBy34)179 TEST_F(libyuvTest, ARGBScaleDownBy34) {
180 const int src_width = 1280;
181 const int src_height = 720;
182 const int dst_width = src_width * 3 / 4;
183 const int dst_height = src_height * 3 / 4;
184
185 for (int f = 0; f < 2; ++f) {
186 int max_diff = ARGBTestFilter(src_width, src_height,
187 dst_width, dst_height,
188 static_cast<FilterMode>(f),
189 benchmark_iterations_);
190 EXPECT_LE(max_diff, 1);
191 }
192 }
193
TEST_F(libyuvTest,ARGBScaleDownBy38)194 TEST_F(libyuvTest, ARGBScaleDownBy38) {
195 int src_width = 1280;
196 int src_height = 720;
197 int dst_width = src_width * 3 / 8;
198 int dst_height = src_height * 3 / 8;
199
200 for (int f = 0; f < 2; ++f) {
201 int max_diff = ARGBTestFilter(src_width, src_height,
202 dst_width, dst_height,
203 static_cast<FilterMode>(f),
204 benchmark_iterations_);
205 EXPECT_LE(max_diff, 1);
206 }
207 }
208
TEST_F(libyuvTest,ARGBScaleTo1366)209 TEST_F(libyuvTest, ARGBScaleTo1366) {
210 int src_width = 1280;
211 int src_height = 720;
212 int dst_width = 1366;
213 int dst_height = 768;
214
215 for (int f = 0; f < 2; ++f) {
216 int max_diff = ARGBTestFilter(src_width, src_height,
217 dst_width, dst_height,
218 static_cast<FilterMode>(f),
219 benchmark_iterations_);
220 EXPECT_LE(max_diff, 1);
221 }
222 }
223
TEST_F(libyuvTest,ARGBScaleTo4074)224 TEST_F(libyuvTest, ARGBScaleTo4074) {
225 int src_width = 2880 * 2;
226 int src_height = 1800;
227 int dst_width = 4074;
228 int dst_height = 1272;
229
230 for (int f = 0; f < 2; ++f) {
231 int max_diff = ARGBTestFilter(src_width, src_height,
232 dst_width, dst_height,
233 static_cast<FilterMode>(f),
234 benchmark_iterations_);
235 EXPECT_LE(max_diff, 1);
236 }
237 }
238
239
TEST_F(libyuvTest,ARGBScaleTo853)240 TEST_F(libyuvTest, ARGBScaleTo853) {
241 int src_width = 1280;
242 int src_height = 720;
243 int dst_width = 853;
244 int dst_height = 480;
245
246 for (int f = 0; f < 2; ++f) {
247 int max_diff = ARGBTestFilter(src_width, src_height,
248 dst_width, dst_height,
249 static_cast<FilterMode>(f),
250 benchmark_iterations_);
251 EXPECT_LE(max_diff, 1);
252 }
253 }
254
255 } // namespace libyuv
256