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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/image-encoders/JPEGImageEncoderTest.cpp
diff --git a/third_party/WebKit/Source/platform/image-encoders/JPEGImageEncoderTest.cpp b/third_party/WebKit/Source/platform/image-encoders/JPEGImageEncoderTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..29219a6313d27c19bae3263b74b462f8c48295bd
--- /dev/null
+++ b/third_party/WebKit/Source/platform/image-encoders/JPEGImageEncoderTest.cpp
@@ -0,0 +1,233 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/timer/elapsed_timer.h"
+#include "platform/image-encoders/RGBAtoRGB.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "wtf/build_config.h"
+
+namespace blink {
+
+class RGBAtoRGBTest : public ::testing::Test {
+ public:
+ RGBAtoRGBTest() {}
+};
+
+static const size_t channelsRGBA = 4;
+static const size_t channelsRGB = 3;
+
+inline size_t calculateRGBAPixels(size_t inputBufferSize) {
+ size_t pixels = inputBufferSize / channelsRGBA;
+ return pixels;
+}
+
+inline size_t calculateRGBOutputSize(size_t inputBufferSize) {
+ size_t pixels = calculateRGBAPixels(inputBufferSize);
+ pixels *= channelsRGB;
+ return pixels;
+}
+
+TEST_F(RGBAtoRGBTest, testOpaqueCaseEven8pixels) {
+ unsigned char canvas[] = {255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
+ 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
+
+ unsigned char expected[] = {255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0,
+ 255, 0, 0, 255, 0, 0, 255, 0, 0, 255, 0};
+#if OS(WIN)
+ // Windows release bot can't be reasoned with (compiler error C2131).
+ static const constexpr size_t pixels = sizeof(canvas) / channelsRGBA;
+ static const constexpr size_t rgbSize = pixels * channelsRGB;
+#else
+ const size_t pixels = calculateRGBAPixels(sizeof(canvas));
+ const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
+#endif
+
+ unsigned char output[rgbSize];
+ memset(output, 0, rgbSize);
+
+ blink::RGBAtoRGB(canvas, static_cast<unsigned>(pixels), output);
+
+ EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
+}
+
+#ifdef __ARM_NEON__
+TEST_F(RGBAtoRGBTest, testCaseEven16pixels) {
+ unsigned char canvas[] = {
+ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255,
+ 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255,
+ 128, 0, 0, 255, 128, 0, 0, 255, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
+
+ const size_t pixels = calculateRGBAPixels(sizeof(canvas));
+ const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
+ unsigned char output[rgbSize];
+ unsigned char expected[rgbSize];
+ memset(output, 0, rgbSize);
+ memset(expected, 0, rgbSize);
+
+ blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
+ blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
+
+ EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
+}
+
+TEST_F(RGBAtoRGBTest, testCaseOdd17pixels) {
+ unsigned char canvas[] = {
+ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
+ 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255, 128, 0, 0,
+ 255, 128, 0, 0, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 10, 10, 10, 100};
+
+ const size_t pixels = calculateRGBAPixels(sizeof(canvas));
+ const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
+ unsigned char output[rgbSize];
+ unsigned char expected[rgbSize];
+ memset(output, 0, rgbSize);
+ memset(expected, 0, rgbSize);
+
+ blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
+ blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
+
+ EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
+}
+
+TEST_F(RGBAtoRGBTest, testCaseEven32pixels) {
+ unsigned char canvas[] = {
+ 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0,
+ 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+ 0, 255, 0, 0, 255, 128, 0, 0, 255, 128, 0, 0, 255, 128, 0,
+ 0, 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 255, 128, 128, 128, 255, 128, 128, 128,
+ 255, 128, 128, 128, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0,
+ 0, 255, 255, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+ 255, 0, 255, 0, 255, 0, 255, 0, 0, 255, 128, 0, 0, 255, 128,
+ 0, 0, 255, 128, 0, 0, 255, 128};
+
+ const size_t pixels = calculateRGBAPixels(sizeof(canvas));
+ const size_t rgbSize = calculateRGBOutputSize(sizeof(canvas));
+ unsigned char output[rgbSize];
+ unsigned char expected[rgbSize];
+ memset(output, 0, rgbSize);
+ memset(expected, 0, rgbSize);
+
+ blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
+ blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
+
+ EXPECT_EQ(memcmp(expected, output, rgbSize), 0);
+}
+
+static base::TimeDelta testNpixels(bool fastPath = true,
+ const size_t width = 1024,
+ const size_t height = 1024,
+ bool setAlpha = true) {
+ const size_t pixels = width * height;
+ const size_t canvasLen = channelsRGBA * width * height;
+ const size_t outputLen = channelsRGB * width * height;
+ unsigned char* canvas = new unsigned char[canvasLen];
+ unsigned char* output = new unsigned char[outputLen];
+
+ auto cleanup = [&]() {
+ if (canvas)
+ delete[] canvas;
+ if (output)
+ delete[] output;
+ };
+
+ if (!canvas || !output) {
+ cleanup();
+ return base::TimeDelta();
+ }
+
+ if (setAlpha) {
+ memset(canvas, 128, canvasLen);
+ } else {
+ memset(canvas, 200, canvasLen);
+ }
+
+ base::ElapsedTimer runTime;
+ if (fastPath) {
+ blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
+ } else {
+ blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), output);
+ }
+
+ auto result = runTime.Elapsed();
+ cleanup();
+ return result;
+}
+
+TEST_F(RGBAtoRGBTest, testPerf1k) {
+ auto neonElapsed = testNpixels();
+ auto scalarElapsed = testNpixels(false);
+
+ EXPECT_TRUE(neonElapsed < scalarElapsed)
+ << "Neon: " << neonElapsed << "\tScalar: " << scalarElapsed << std::endl;
+}
+
+TEST_F(RGBAtoRGBTest, testPerf4k) {
+ auto neonElapsed = testNpixels(true, 4000, 4000);
+ auto scalarElapsed = testNpixels(false, 4000, 4000);
+
+ EXPECT_TRUE(neonElapsed < scalarElapsed)
+ << "Neon: " << neonElapsed << "\tScalar: " << scalarElapsed << std::endl;
+}
+
+// This width will force the tail case, cause width = (16 * 64) + 15.
+static bool testRandNpixels(const size_t width = 1039,
+ const size_t height = 1024,
+ bool setAlpha = true) {
+ const size_t pixels = width * height;
+ const size_t canvasLen = channelsRGBA * pixels;
+ const size_t outputLen = channelsRGB * pixels;
+ unsigned char* canvas = new unsigned char[canvasLen];
+ unsigned char* expected = new unsigned char[outputLen];
+ unsigned char* output = new unsigned char[outputLen];
+
+ auto cleanup = [&]() {
+ if (canvas)
+ delete[] canvas;
+ if (expected)
+ delete[] expected;
+ if (output)
+ delete[] output;
+ };
+
+ if (!canvas || !output || !expected) {
+ cleanup();
+ return false;
+ }
+
+ if (setAlpha) {
+ memset(canvas, 128, canvasLen);
+ } else {
+ memset(canvas, 200, canvasLen);
+ }
+
+ srand(time(0));
+ unsigned char* ptr = canvas;
+ for (size_t i = 0; i < pixels; ++i) {
+ *ptr++ = static_cast<unsigned char>(rand() % 255);
+ *ptr++ = static_cast<unsigned char>(rand() % 255);
+ *ptr++ = static_cast<unsigned char>(rand() % 255);
+ *ptr++ = static_cast<unsigned char>(rand() % 255);
+ }
+
+ blink::RGBAtoRGBScalar(canvas, static_cast<unsigned>(pixels), expected);
+ blink::RGBAtoRGBNeon(canvas, static_cast<unsigned>(pixels), output);
+
+ bool result = memcmp(expected, output, outputLen) == 0;
+
+ cleanup();
+ return result;
+}
+
+TEST_F(RGBAtoRGBTest, randomPixels) {
+ EXPECT_TRUE(testRandNpixels());
+}
+
+#endif
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698