133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp/* 233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * Copyright 2012 The LibYuv Project Authors. All rights reserved. 333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * 433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * Use of this source code is governed by a BSD-style license 533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * that can be found in the LICENSE file in the root of the source 633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * tree. An additional intellectual property rights grant can be found 733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * in the file PATENTS. All contributing project authors may 833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp * be found in the AUTHORS file in the root of the source tree. 933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp */ 1033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 1133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include <stdlib.h> 1233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include <time.h> 1333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 1433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/cpu_id.h" 1533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "libyuv/rotate_argb.h" 1633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp#include "../unit_test/unit_test.h" 1733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 1833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampnamespace libyuv { 1933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 2033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkampstatic int ARGBTestRotate(int src_width, int src_height, 2133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int dst_width, int dst_height, 2233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp libyuv::RotationMode mode, int runs) { 2333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int b = 128; 2433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int src_argb_plane_size = (src_width + b * 2) * (src_height + b * 2) * 4; 2533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int src_stride_argb = (b * 2 + src_width) * 4; 2633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 2733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp align_buffer_16(src_argb, src_argb_plane_size) 2833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp memset(src_argb, 1, src_argb_plane_size); 2933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 3033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int dst_argb_plane_size = (dst_width + b * 2) * (dst_height + b * 2) * 4; 3133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int dst_stride_argb = (b * 2 + dst_width) * 4; 3233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 3333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp srandom(time(NULL)); 3433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 3533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int i, j; 3633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (i = b; i < (src_height + b); ++i) { 3733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (j = b; j < (src_width + b) * 4; ++j) { 3833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp src_argb[(i * src_stride_argb) + j] = (random() & 0xff); 3933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 4033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 4133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 4233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp align_buffer_16(dst_argb_c, dst_argb_plane_size) 4333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp align_buffer_16(dst_argb_opt, dst_argb_plane_size) 4433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp memset(dst_argb_c, 2, dst_argb_plane_size); 4533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp memset(dst_argb_opt, 3, dst_argb_plane_size); 4633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 4733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // Warm up both versions for consistent benchmarks. 4833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp MaskCpuFlags(0); // Disable all CPU optimization. 4933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 5033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb, 5133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp src_width, src_height, mode); 5233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp MaskCpuFlags(-1); // Enable all CPU optimization. 5333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 5433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb, 5533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp src_width, src_height, mode); 5633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 5733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp MaskCpuFlags(0); // Disable all CPU optimization. 5833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp double c_time = get_time(); 5933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (i = 0; i < runs; ++i) { 6033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 6133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_argb_c + (dst_stride_argb * b) + b * 4, dst_stride_argb, 6233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp src_width, src_height, mode); 6333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 6433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp c_time = (get_time() - c_time) / runs; 6533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 6633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp MaskCpuFlags(-1); // Enable all CPU optimization. 6733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp double opt_time = get_time(); 6833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (i = 0; i < runs; ++i) { 6933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp ARGBRotate(src_argb + (src_stride_argb * b) + b * 4, src_stride_argb, 7033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_argb_opt + (dst_stride_argb * b) + b * 4, dst_stride_argb, 7133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp src_width, src_height, mode); 7233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 7333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp opt_time = (get_time() - opt_time) / runs; 7433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 7533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // Report performance of C vs OPT 7633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp printf("filter %d - %8d us C - %8d us OPT\n", 7733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp mode, static_cast<int>(c_time*1e6), static_cast<int>(opt_time*1e6)); 7833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 7933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // C version may be a little off from the optimized. Order of 8033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // operations may introduce rounding somewhere. So do a difference 8133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // of the buffers and look to see that the max difference isn't 8233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp // over 2. 8333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int max_diff = 0; 8433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (i = b; i < (dst_height + b); ++i) { 8533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp for (j = b * 4; j < (dst_width + b) * 4; ++j) { 8633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int abs_diff = abs(dst_argb_c[(i * dst_stride_argb) + j] - 8733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_argb_opt[(i * dst_stride_argb) + j]); 8833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp if (abs_diff > max_diff) 8933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp max_diff = abs_diff; 9033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 9133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp } 9233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 9333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp free_aligned_buffer_16(dst_argb_c) 9433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp free_aligned_buffer_16(dst_argb_opt) 9533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp free_aligned_buffer_16(src_argb) 9633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp return max_diff; 9733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 9833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 9933cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate0) { 10033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1280; 10133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 720; 10233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 1280; 10333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 720; 10433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 10533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 10633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate0, 10733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 10833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 10933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 11033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 11133cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate90) { 11233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1280; 11333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 720; 11433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 720; 11533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 1280; 11633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 11733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 11833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate90, 11933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 12033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 12133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 12233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 12333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate180) { 12433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1280; 12533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 720; 12633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 1280; 12733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 720; 12833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 12933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 13033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate180, 13133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 13233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 13333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 13433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 13533cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate270) { 13633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1280; 13733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 720; 13833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 720; 13933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 1280; 14033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 14133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 14233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate270, 14333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 14433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 14533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 14633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 14733cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate0_Odd) { 14833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1277; 14933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 719; 15033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 1277; 15133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 719; 15233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 15333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 15433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate0, 15533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 15633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 15733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 15833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 15933cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate90_Odd) { 16033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1277; 16133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 719; 16233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 719; 16333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 1277; 16433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 16533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 16633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate90, 16733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 16833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 16933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 17033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 17133cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate180_Odd) { 17233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1277; 17333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 719; 17433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 1277; 17533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 719; 17633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 17733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 17833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate180, 17933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 18033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 18133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 18233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 18333cfdeb7b267ab635413797fffb046b73272f7ecHendrik DahlkampTEST_F(libyuvTest, ARGBRotate270_Odd) { 18433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_width = 1277; 18533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int src_height = 719; 18633cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_width = 719; 18733cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp const int dst_height = 1277; 18833cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 18933cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp int err = ARGBTestRotate(src_width, src_height, 19033cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp dst_width, dst_height, kRotate270, 19133cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp benchmark_iterations_); 19233cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp EXPECT_GE(1, err); 19333cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} 19433cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp 19533cfdeb7b267ab635413797fffb046b73272f7ecHendrik Dahlkamp} // namespace libyuv 196