Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: third_party/WebKit/Source/platform/image-encoders/JPEGImageEncoderTest.cpp

Issue 2576223002: NEON-ize RGBA to RGB code (Closed)
Patch Set: Moved perf test to another issue Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/timer/elapsed_timer.h"
6 #include "platform/image-encoders/RGBAtoRGB.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "wtf/build_config.h"
9
10 namespace blink {
11
12 class RGBAtoRGBTest : public ::testing::Test {
13 public:
14 RGBAtoRGBTest() {}
15 };
16
17 static const size_t channelsRGBA = 4;
18 static const size_t channelsRGB = 3;
19
20 inline size_t calculateRGBAPixels(size_t inputBufferSize) {
21 size_t pixels = inputBufferSize / channelsRGBA;
22 return pixels;
23 }
24
25 inline size_t calculateRGBOutputSize(size_t inputBufferSize) {
26 size_t pixels = calculateRGBAPixels(inputBufferSize);
27 pixels *= channelsRGB;
28 return pixels;
29 }
30
31 TEST_F(RGBAtoRGBTest, testOpaqueCaseEven8pixels) {
32 unsigned char canvas[] = {255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
33 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 255,
34 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
35
36 unsigned char expected[] = {255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0,
37 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0};
38 #if OS(WIN)
39 // Windows release bot can't be reasoned with (compiler error C2131).
40 static const constexpr size_t pixels = sizeof(canvas) / channelsRGBA;
41 static const constexpr size_t rgbSize = pixels * channelsRGB;
42 #else
43 const size_t pixels = calculateRGBAPixels(sizeof(canvas));
44 const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
45 #endif
46
47 unsigned char output[rgbSize];
48 memset(output, 0, rgbSize);
49
50 blink::RGBAtoRGB(canvas, static_cast<unsigned>(pixels), output);
51
52 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
53 }
54
55 #ifdef __ARM_NEON__
56 TEST_F(RGBAtoRGBTest, testCaseEven16pixels) {
57 unsigned char canvas[] = {
58 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255,
59 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
60 0, 255, 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255,
61 128, 0, 0, 255, 128, 0, 0, 255, 128, 128, 128, 128, 128,
62 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
63
64 const size_t pixels = calculateRGBAPixels(sizeof(canvas));
65 const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
66 unsigned char output[rgbSize];
67 unsigned char expected[rgbSize];
68 memset(output, 0, rgbSize);
69 memset(expected, 0, rgbSize);
70
71 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
72 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
73
74 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
75 }
76
77 TEST_F(RGBAtoRGBTest, testCaseOdd17pixels) {
78 unsigned char canvas[] = {
79 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
80 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
81 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255, 128, 0, 0,
82 255, 128, 0, 0, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128,
83 128, 128, 128, 128, 128, 128, 128, 128, 10, 10, 10, 100};
84
85 const size_t pixels = calculateRGBAPixels(sizeof(canvas));
86 const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
87 unsigned char output[rgbSize];
88 unsigned char expected[rgbSize];
89 memset(output, 0, rgbSize);
90 memset(expected, 0, rgbSize);
91
92 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
93 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
94
95 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
96 }
97
98 TEST_F(RGBAtoRGBTest, testCaseEven32pixels) {
99 unsigned char canvas[] = {
100 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
101 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
102 0, 255, 0, 0, 255, 128, 0, 0, 255, 128, 0, 0, 255, 128, 0,
103 0, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
104 128, 128, 128, 128, 128, 128, 128, 255, 128, 128, 128, 255, 128, 128, 128,
105 255, 128, 128, 128, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
106 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
107 255, 0, 255, 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255, 128,
108 0, 0, 255, 128, 0, 0, 255, 128};
109
110 const size_t pixels = calculateRGBAPixels(sizeof(canvas));
111 const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
112 unsigned char output[rgbSize];
113 unsigned char expected[rgbSize];
114 memset(output, 0, rgbSize);
115 memset(expected, 0, rgbSize);
116
117 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
118 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
119
120 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
121 }
122
123 static base::TimeDelta testNpixels(bool fastPath = true,
124 const size_t width = 1024,
125 const size_t height = 1024,
126 bool setAlpha = true) {
127 const size_t pixels = width * height;
128 const size_t canvasLen = channelsRGBA * width * height;
129 const size_t outputLen = channelsRGB * width * height;
130 unsigned char* canvas = new unsigned char[canvasLen];
131 unsigned char* output = new unsigned char[outputLen];
132
133 auto cleanup = [&]() {
134 if (canvas)
135 delete[] canvas;
136 if (output)
137 delete[] output;
138 };
139
140 if (!canvas || !output) {
141 cleanup();
142 return base::TimeDelta();
143 }
144
145 if (setAlpha) {
146 memset(canvas, 128, canvasLen);
147 } else {
148 memset(canvas, 200, canvasLen);
149 }
150
151 base::ElapsedTimer runTime;
152 if (fastPath) {
153 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
154 } else {
155 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), output);
156 }
157
158 auto result = runTime.Elapsed();
159 cleanup();
160 return result;
161 }
162
163 TEST_F(RGBAtoRGBTest, testPerf1k) {
164 auto neonElapsed = testNpixels();
165 auto scalarElapsed = testNpixels(false);
166
167 EXPECT_TRUE(neonElapsed < scalarElapsed)
168 << "Neon: " << neonElapsed << "\tScalar: " << scalarElapsed << std::endl;
169 }
170
171 TEST_F(RGBAtoRGBTest, testPerf4k) {
172 auto neonElapsed = testNpixels(true, 4000, 4000);
173 auto scalarElapsed = testNpixels(false, 4000, 4000);
174
175 EXPECT_TRUE(neonElapsed < scalarElapsed)
176 << "Neon: " << neonElapsed << "\tScalar: " << scalarElapsed << std::endl;
177 }
178
179 // This width will force the tail case, cause width = (16 * 64) + 15.
180 static bool testRandNpixels(const size_t width = 1039,
181 const size_t height = 1024,
182 bool setAlpha = true) {
183 const size_t pixels = width * height;
184 const size_t canvasLen = channelsRGBA * pixels;
185 const size_t outputLen = channelsRGB * pixels;
186 unsigned char* canvas = new unsigned char[canvasLen];
187 unsigned char* expected = new unsigned char[outputLen];
188 unsigned char* output = new unsigned char[outputLen];
189
190 auto cleanup = [&]() {
191 if (canvas)
192 delete[] canvas;
193 if (expected)
194 delete[] expected;
195 if (output)
196 delete[] output;
197 };
198
199 if (!canvas || !output || !expected) {
200 cleanup();
201 return false;
202 }
203
204 if (setAlpha) {
205 memset(canvas, 128, canvasLen);
206 } else {
207 memset(canvas, 200, canvasLen);
208 }
209
210 srand(time(0));
211 unsigned char* ptr = canvas;
212 for (size_t i = 0; i < pixels; ++i) {
213 *ptr++ = static_cast<unsigned char>(rand() % 255);
214 *ptr++ = static_cast<unsigned char>(rand() % 255);
215 *ptr++ = static_cast<unsigned char>(rand() % 255);
216 *ptr++ = static_cast<unsigned char>(rand() % 255);
217 }
218
219 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
220 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
221
222 bool result = memcmp(expected, output, outputLen) == 0;
223
224 cleanup();
225 return result;
226 }
227
228 TEST_F(RGBAtoRGBTest, randomPixels) {
229 EXPECT_TRUE(testRandNpixels());
230 }
231
232 #endif
233 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698