• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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