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

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

Issue 2576223002: NEON-ize RGBA to RGB code (Closed)
Patch Set: Created 4 years 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 /*
2 * Copyright 2016 The Chromium Authors. All rights reserved.
esprehn 2016/12/15 05:01:25 Use the new short copyright on new files.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Chromium nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "base/timer/elapsed_timer.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 // TODO(cavalcantii): use regular macro, see https://crbug.com/673067.
35 #ifdef __ARM_NEON__
36 #include "platform/image-encoders/RGBAtoRGB.h"
37 #endif
38
39 namespace blink {
40
41 static const size_t channelsRGBA = 4;
42 static const size_t channelsRGB = 3;
43
44 class RGBAtoRGBTest : public ::testing::Test {
45 public:
46 RGBAtoRGBTest() {}
47 };
48
49 TEST_F(RGBAtoRGBTest, testEmpty) {
50 EXPECT_TRUE(true);
51 }
52
53 inline size_t calculateRGBAPixels(size_t inputBufferSize) {
54 size_t pixels = inputBufferSize / channelsRGBA;
55 return pixels;
56 }
57
58 inline size_t calculateRGBOutputSize(size_t inputBufferSize) {
59 size_t pixels = calculateRGBAPixels(inputBufferSize);
60 pixels *= channelsRGB;
61 return pixels;
62 }
63
64 #ifdef __ARM_NEON__
65 TEST_F(RGBAtoRGBTest, testOpaqueCaseEven8pixels) {
66 unsigned char canvas[] = {255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
67 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 255,
68 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
69
70 unsigned char expected[] = {255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0,
71 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0};
72
73 size_t pixels = calculateRGBAPixels(sizeof(canvas));
74 size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
75 unsigned char output[rgbSize];
76 memset(output, 0, rgbSize);
77
78 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
79
80 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
81 }
82
83 TEST_F(RGBAtoRGBTest, testCaseEven16pixels) {
84 unsigned char canvas[] = {
85 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255,
86 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
87 0, 255, 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255,
88 128, 0, 0, 255, 128, 0, 0, 255, 128, 128, 128, 128, 128,
89 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
90
91 size_t pixels = calculateRGBAPixels(sizeof(canvas));
92 size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
93 unsigned char output[rgbSize];
94 unsigned char expected[rgbSize];
95 memset(output, 0, rgbSize);
96 memset(expected, 0, rgbSize);
97
98 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
99 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
100
101 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
102 }
103
104 TEST_F(RGBAtoRGBTest, testCaseOdd17pixels) {
105 unsigned char canvas[] = {
106 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
107 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
108 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255, 128, 0, 0,
109 255, 128, 0, 0, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128,
110 128, 128, 128, 128, 128, 128, 128, 128, 10, 10, 10, 100};
111
112 size_t pixels = calculateRGBAPixels(sizeof(canvas));
113 size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
114 unsigned char output[rgbSize];
115 unsigned char expected[rgbSize];
116 memset(output, 0, rgbSize);
117 memset(expected, 0, rgbSize);
118
119 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
120 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
121
122 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
123 }
124
125 TEST_F(RGBAtoRGBTest, testCaseEven32pixels) {
126 unsigned char canvas[] = {
127 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
128 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
129 0, 255, 0, 0, 255, 128, 0, 0, 255, 128, 0, 0, 255, 128, 0,
130 0, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
131 128, 128, 128, 128, 128, 128, 128, 255, 128, 128, 128, 255, 128, 128, 128,
132 255, 128, 128, 128, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
133 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
134 255, 0, 255, 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255, 128,
135 0, 0, 255, 128, 0, 0, 255, 128};
136
137 size_t pixels = calculateRGBAPixels(sizeof(canvas));
138 size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
139 unsigned char output[rgbSize];
140 unsigned char expected[rgbSize];
141 memset(output, 0, rgbSize);
142 memset(expected, 0, rgbSize);
143
144 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
145 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
146
147 EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
148 }
149
150 static base::TimeDelta testNpixels(bool fastPath = true,
151 const size_t width = 1024,
152 const size_t height = 1024,
153 bool setAlpha = true) {
154 size_t pixels = width * height;
155 size_t canvasLen = channelsRGBA * width * height;
156 size_t outputLen = channelsRGB * width * height;
157 unsigned char* canvas = new unsigned char[canvasLen];
158 unsigned char* output = new unsigned char[outputLen];
159
160 auto cleanup = [&]() {
161 if (canvas)
162 delete[] canvas;
163 if (output)
164 delete[] output;
165 };
166
167 if (!canvas || !output) {
168 cleanup();
169 return base::TimeDelta();
170 }
171
172 if (setAlpha) {
173 memset(canvas, 128, canvasLen);
174 } else {
175 memset(canvas, 200, canvasLen);
176 }
177
178 base::ElapsedTimer runTime;
179 if (fastPath) {
180 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
181 } else {
182 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), output);
183 }
184
185 auto result = runTime.Elapsed();
186 cleanup();
187 return result;
188 }
189
190 TEST_F(RGBAtoRGBTest, testPerf1k) {
191 auto neonElapsed = testNpixels();
192 auto scalarElapsed = testNpixels(false);
193
194 EXPECT_TRUE(neonElapsed < scalarElapsed)
195 << "Neon: " << neonElapsed << "\tScalar: " << scalarElapsed << std::endl;
196 }
197
198 TEST_F(RGBAtoRGBTest, testPerf4k) {
199 auto neonElapsed = testNpixels(true, 4000, 4000);
200 auto scalarElapsed = testNpixels(false, 4000, 4000);
201
202 EXPECT_TRUE(neonElapsed < scalarElapsed)
203 << "Neon: " << neonElapsed << "\tScalar: " << scalarElapsed << std::endl;
204 }
205
206 // This width will force the tail case, cause width = (16 * 64) + 15.
207 static bool testRandNpixels(const size_t width = 1039,
208 const size_t height = 1024,
209 bool setAlpha = true) {
210 size_t pixels = width * height;
211 size_t canvasLen = channelsRGBA * pixels;
212 size_t outputLen = channelsRGB * pixels;
213 unsigned char* canvas = new unsigned char[canvasLen];
214 unsigned char* expected = new unsigned char[outputLen];
215 unsigned char* output = new unsigned char[outputLen];
216
217 auto cleanup = [&]() {
218 if (canvas)
219 delete[] canvas;
220 if (expected)
221 delete[] expected;
222 if (output)
223 delete[] output;
224 };
225
226 if (!canvas || !output || !expected) {
227 cleanup();
228 return false;
229 }
230
231 if (setAlpha) {
232 memset(canvas, 128, canvasLen);
233 } else {
234 memset(canvas, 200, canvasLen);
235 }
236
237 srand(time(0));
238 unsigned char* ptr = canvas;
239 for (size_t i = 0; i < pixels; ++i) {
240 *ptr++ = static_cast<unsigned char>(rand() % 255);
241 *ptr++ = static_cast<unsigned char>(rand() % 255);
242 *ptr++ = static_cast<unsigned char>(rand() % 255);
243 *ptr++ = static_cast<unsigned char>(rand() % 255);
244 }
245
246 blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
247 blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
248
249 bool result = memcmp(expected, output, outputLen) == 0;
250
251 cleanup();
252 return result;
253 }
254
255 TEST_F(RGBAtoRGBTest, randomPixels) {
256 EXPECT_TRUE(testRandNpixels());
257 }
258
259 #endif
260 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698