| Index: ui/surface/accelerated_surface_transformer_win_unittest.cc
|
| diff --git a/ui/surface/accelerated_surface_transformer_win_unittest.cc b/ui/surface/accelerated_surface_transformer_win_unittest.cc
|
| index 5d432efc6090a56a77bc95c2bd2967062ccd3251..ed5b606990e292d1f2e9467ecd1721212917e9bd 100644
|
| --- a/ui/surface/accelerated_surface_transformer_win_unittest.cc
|
| +++ b/ui/surface/accelerated_surface_transformer_win_unittest.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2013 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.
|
|
|
| @@ -6,13 +6,21 @@
|
| #include <random>
|
|
|
| #include "base/basictypes.h"
|
| +#include "base/file_util.h"
|
| #include "base/hash.h"
|
| #include "base/scoped_native_library.h"
|
| #include "base/stringprintf.h"
|
| +#include "base/time.h"
|
| #include "base/win/scoped_comptr.h"
|
| #include "base/win/windows_version.h"
|
| +#include "media/base/simd/convert_rgb_to_yuv.h"
|
| +#include "media/base/yuv_convert.h"
|
| +#include "skia/ext/image_operations.h"
|
| #include "testing/gtest/include/gtest/gtest-param-test.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| +#include "third_party/skia/include/core/SkBitmap.h"
|
| +#include "third_party/skia/include/core/SkColor.h"
|
| +#include "ui/gfx/codec/png_codec.h"
|
| #include "ui/gfx/rect.h"
|
| #include "ui/surface/accelerated_surface_transformer_win.h"
|
| #include "ui/surface/accelerated_surface_win.h"
|
| @@ -23,14 +31,67 @@ namespace d3d_utils = ui_surface_d3d9_utils;
|
| using base::win::ScopedComPtr;
|
| using std::uniform_int_distribution;
|
|
|
| -// Provides a reference rasterizer (all rendering done by software emulation)
|
| -// Direct3D device, for use by unit tests.
|
| +namespace {
|
| +
|
| +// Debug flag, useful when hacking on tests.
|
| +const bool kDumpImagesOnFailure = false;
|
| +
|
| +SkBitmap ToSkBitmap(IDirect3DSurface9* surface, bool is_single_channel) {
|
| + D3DLOCKED_RECT locked_rect;
|
| + EXPECT_HRESULT_SUCCEEDED(
|
| + surface->LockRect(&locked_rect, NULL, D3DLOCK_READONLY));
|
| +
|
| + SkBitmap result;
|
| + gfx::Size size = d3d_utils::GetSize(surface);
|
| + if (is_single_channel)
|
| + size = gfx::Size(size.width() * 4, size.height());
|
| + result.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
|
| + result.setIsOpaque(true);
|
| + result.allocPixels();
|
| + result.lockPixels();
|
| + for (int y = 0; y < size.height(); ++y) {
|
| + uint8* row8 = reinterpret_cast<uint8*>(locked_rect.pBits) +
|
| + (y * locked_rect.Pitch);
|
| + if (is_single_channel) {
|
| + for (int x = 0; x < size.width(); ++x) {
|
| + *result.getAddr32(x, y) = SkColorSetRGB(row8[x], row8[x], row8[x]);
|
| + }
|
| + } else {
|
| + uint32* row32 = reinterpret_cast<uint32*>(row8);
|
| + for (int x = 0; x < size.width(); ++x) {
|
| + *result.getAddr32(x, y) = row32[x] | 0xFF000000;
|
| + }
|
| + }
|
| + }
|
| + result.unlockPixels();
|
| + result.setImmutable();
|
| + surface->UnlockRect();
|
| + return result;
|
| +}
|
| +
|
| +bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) {
|
| + std::vector<unsigned char> png_data;
|
| + const bool discard_transparency = true;
|
| + if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap,
|
| + discard_transparency,
|
| + &png_data) &&
|
| + file_util::CreateDirectory(file_path.DirName())) {
|
| + char* data = reinterpret_cast<char*>(&png_data[0]);
|
| + int size = static_cast<int>(png_data.size());
|
| + return file_util::WriteFile(file_path, data, size) == size;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Test fixture for AcceleratedSurfaceTransformer.
|
| //
|
| // This class is parameterized so that it runs only on Vista+. See
|
| // WindowsVersionIfVistaOrBetter() for details on this works.
|
| class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| public:
|
| - AcceleratedSurfaceTransformerTest() {};
|
| + AcceleratedSurfaceTransformerTest() : color_error_tolerance_(0) {};
|
|
|
| IDirect3DDevice9Ex* device() { return device_.get(); }
|
|
|
| @@ -79,6 +140,15 @@ class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| device()->Present(0, 0, 0, 0));
|
| }
|
|
|
| + void WarnOnMissingFeatures(AcceleratedSurfaceTransformer* gpu_ops) {
|
| + // Prints a single warning line if some tests are feature-dependent
|
| + // and the feature is not supported by the current GPU.
|
| + if (!gpu_ops->device_supports_multiple_render_targets()) {
|
| + LOG(WARNING) << "MRT not supported, some tests will be skipped. "
|
| + << GetAdapterInfo();
|
| + }
|
| + }
|
| +
|
| // Locks and fills a surface with a checkerboard pattern where the colors
|
| // are random but the total image pattern is horizontally and vertically
|
| // symmetric.
|
| @@ -94,8 +164,8 @@ class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| ASSERT_EQ(0, locked_rect.Pitch % sizeof(DWORD));
|
| int pitch = locked_rect.Pitch / sizeof(DWORD);
|
|
|
| - for (int y = 0; y <= size.height() / 2; y += checker_square_size) {
|
| - for (int x = 0; x <= size.width() / 2; x += checker_square_size) {
|
| + for (int y = 0; y < (size.height() + 1) / 2; y += checker_square_size) {
|
| + for (int x = 0; x < (size.width() + 1) / 2; x += checker_square_size) {
|
| DWORD color = RandomColor();
|
| int y_limit = std::min(size.height() / 2, y + checker_square_size - 1);
|
| int x_limit = std::min(size.width() / 2, x + checker_square_size - 1);
|
| @@ -154,7 +224,7 @@ class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| max_error = std::max(max_error,
|
| std::abs(static_cast<int>(a[i]) - b[i]));
|
|
|
| - if (max_error <= kAbsoluteColorErrorTolerance)
|
| + if (max_error <= color_error_tolerance())
|
| return true;
|
|
|
| std::string expected_color =
|
| @@ -163,8 +233,19 @@ class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| StringPrintf("%3d, %3d, %3d, %3d", b[0], b[1], b[2], b[3]);
|
| EXPECT_EQ(expected_color, actual_color)
|
| << "Componentwise color difference was "
|
| - << max_error << "; max allowed is " << kAbsoluteColorErrorTolerance;
|
| + << max_error << "; max allowed is " << color_error_tolerance();
|
| +
|
| + return false;
|
| + }
|
|
|
| +bool AssertSameColor(uint8 color_a, uint8 color_b) {
|
| + if (color_a == color_b)
|
| + return true;
|
| + int max_error = std::abs((int) color_a - (int) color_b);
|
| + if (max_error <= color_error_tolerance())
|
| + return true;
|
| + ADD_FAILURE() << "Colors not equal: " << StringPrintf("0x%x", color_a)
|
| + << " vs. " << StringPrintf("0x%x", color_b);
|
| return false;
|
| }
|
|
|
| @@ -239,12 +320,18 @@ class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| }
|
|
|
| protected:
|
| - static const int kAbsoluteColorErrorTolerance = 5;
|
| -
|
| DWORD RandomColor() {
|
| return random_dword_(rng_);
|
| }
|
|
|
| + void set_color_error_tolerance(int value) {
|
| + color_error_tolerance_ = value;
|
| + }
|
| +
|
| + int color_error_tolerance() {
|
| + return color_error_tolerance_;
|
| + }
|
| +
|
| void DoResizeBilinearTest(AcceleratedSurfaceTransformer* gpu_ops,
|
| const gfx::Size& src_size,
|
| const gfx::Size& dst_size,
|
| @@ -256,6 +343,8 @@ class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| dst_size.width(), dst_size.height(),
|
| checkerboard_size));
|
|
|
| + set_color_error_tolerance(4);
|
| +
|
| base::win::ScopedComPtr<IDirect3DSurface9> src, dst;
|
| ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface(
|
| device(), src_size, src.Receive()))
|
| @@ -271,29 +360,211 @@ class AcceleratedSurfaceTransformerTest : public testing::TestWithParam<int> {
|
| AssertSymmetry(dst, dst_size);
|
| }
|
|
|
| + void CreateRandomCheckerboardTexture(
|
| + const gfx::Size& size,
|
| + int checkerboard_size,
|
| + IDirect3DSurface9** reference_surface,
|
| + IDirect3DTexture9** result) {
|
| + base::win::ScopedComPtr<IDirect3DSurface9> dst;
|
| + ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface(device(), size,
|
| + reference_surface));
|
| + ASSERT_TRUE(d3d_utils::CreateTemporaryRenderTargetTexture(device(), size,
|
| + result, dst.Receive()));
|
| + FillRandomCheckerboard(*reference_surface, size, checkerboard_size);
|
| + ASSERT_HRESULT_SUCCEEDED(
|
| + device()->StretchRect(
|
| + *reference_surface, NULL, dst, NULL, D3DTEXF_NONE));
|
| + }
|
| +
|
| + void AssertSame(int width_in_bytes, int height, uint8* reference,
|
| + IDirect3DSurface9* lockable) {
|
| + BeforeLockWorkaround();
|
| +
|
| + D3DLOCKED_RECT locked_rect;
|
| + ASSERT_HRESULT_SUCCEEDED(
|
| + lockable->LockRect(&locked_rect, NULL, D3DLOCK_READONLY));
|
| + uint8* actual = reinterpret_cast<uint8*>(locked_rect.pBits);
|
| + for (int y = 0; y < height; ++y) {
|
| + for (int x = 0; x < width_in_bytes; ++x) {
|
| + if (!AssertSameColor(reference[y * width_in_bytes + x],
|
| + actual[y * locked_rect.Pitch + x])) {
|
| + lockable->UnlockRect();
|
| + GTEST_FAIL() << "At pixel (" << x << ", " << y << ")";
|
| + }
|
| + }
|
| + }
|
| + lockable->UnlockRect();
|
| + }
|
| +
|
| void DoCopyInvertedTest(AcceleratedSurfaceTransformer* gpu_ops,
|
| const gfx::Size& size) {
|
|
|
| SCOPED_TRACE(
|
| StringPrintf("CopyInverted @ %dx%d", size.width(), size.height()));
|
|
|
| - base::win::ScopedComPtr<IDirect3DSurface9> checkerboard, src, dst;
|
| - base::win::ScopedComPtr<IDirect3DTexture9> src_texture;
|
| - ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface(device(), size,
|
| - checkerboard.Receive())) << "Could not create src render target";;
|
| - ASSERT_TRUE(d3d_utils::CreateTemporaryRenderTargetTexture(device(), size,
|
| - src_texture.Receive(), src.Receive()))
|
| - << "Could not create src texture.";
|
| - ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface(device(), size,
|
| + set_color_error_tolerance(0);
|
| +
|
| + base::win::ScopedComPtr<IDirect3DSurface9> dst, reference_pattern;
|
| + base::win::ScopedComPtr<IDirect3DTexture9> src;
|
| +
|
| + CreateRandomCheckerboardTexture(size, 1, reference_pattern.Receive(),
|
| + src.Receive());
|
| +
|
| + // Alloc a slightly larger image 75% of the time, to test that the
|
| + // viewport is set properly.
|
| + const int kAlign = 4;
|
| + gfx::Size alloc_size((size.width() + kAlign - 1) / kAlign * kAlign,
|
| + (size.height() + kAlign - 1) / kAlign * kAlign);
|
| +
|
| + ASSERT_TRUE(d3d_utils::CreateTemporaryLockableSurface(device(), alloc_size,
|
| dst.Receive())) << "Could not create dst render target.";
|
|
|
| - FillRandomCheckerboard(checkerboard, size, 1);
|
| - ASSERT_HRESULT_SUCCEEDED(
|
| - device()->StretchRect(checkerboard, NULL, src, NULL, D3DTEXF_NONE));
|
| - ASSERT_TRUE(gpu_ops->CopyInverted(src_texture, dst, size));
|
| - AssertIsInvertedCopy(size, checkerboard, dst);
|
| + ASSERT_TRUE(gpu_ops->CopyInverted(src, dst, size));
|
| + AssertIsInvertedCopy(size, reference_pattern, dst);
|
| + }
|
| +
|
| +
|
| + void DoYUVConversionTest(AcceleratedSurfaceTransformer* gpu_ops,
|
| + const gfx::Size& src_size,
|
| + int checkerboard_size) {
|
| + // Test the non-MRT implementation, and the MRT implementation as well
|
| + // (if supported by the device).
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(gpu_ops, src_size, src_size,
|
| + checkerboard_size, false));
|
| + if (gpu_ops->device_supports_multiple_render_targets()) {
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(gpu_ops, src_size, src_size,
|
| + checkerboard_size, true));
|
| + }
|
| + }
|
| +
|
| + void DoYUVConversionScaleTest(AcceleratedSurfaceTransformer* gpu_ops,
|
| + const gfx::Size& src_size,
|
| + const gfx::Size& dst_size) {
|
| + // Test the non-MRT implementation, and the MRT implementation as well
|
| + // (if supported by the device).
|
| + if (gpu_ops->device_supports_multiple_render_targets()) {
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(gpu_ops, src_size, dst_size, 4, true));
|
| + }
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(gpu_ops, src_size, dst_size, 4, false));
|
| }
|
|
|
| + void DoYUVConversionTest(AcceleratedSurfaceTransformer* gpu_ops,
|
| + const gfx::Size& src_size,
|
| + const gfx::Size& dst_size,
|
| + int checkerboard_size,
|
| + boolean use_multi_render_targets) {
|
| + SCOPED_TRACE(
|
| + StringPrintf("YUV Converting %dx%d at checkerboard size of %d; MRT %s",
|
| + src_size.width(), src_size.height(),
|
| + checkerboard_size,
|
| + use_multi_render_targets ? "enabled" : "disabled"));
|
| +
|
| +
|
| + base::win::ScopedComPtr<IDirect3DTexture9> src;
|
| + base::win::ScopedComPtr<IDirect3DSurface9> reference;
|
| + base::win::ScopedComPtr<IDirect3DSurface9> dst_y, dst_u, dst_v;
|
| +
|
| + // TODO(ncarter): Use a better error metric that measures aggregate error
|
| + // rather than simply max error. There seems to be slightly more error at
|
| + // higher resolutions, maybe due to precision issues during rasterization
|
| + // (or maybe more pixels = more test trials). Results are usually to an
|
| + // error of 1, but we must use a tolerance of 3.
|
| + set_color_error_tolerance(3);
|
| + CreateRandomCheckerboardTexture(
|
| + src_size, checkerboard_size, reference.Receive(), src.Receive());
|
| +
|
| + gfx::Size packed_y_size, packed_uv_size;
|
| +
|
| + ASSERT_TRUE(gpu_ops->AllocYUVBuffers(dst_size,
|
| + &packed_y_size,
|
| + &packed_uv_size,
|
| + dst_y.Receive(),
|
| + dst_u.Receive(),
|
| + dst_v.Receive()));
|
| +
|
| + // Actually do the conversion.
|
| + if (use_multi_render_targets) {
|
| + ASSERT_TRUE(gpu_ops->TransformRGBToYV12_MRT(src,
|
| + dst_size,
|
| + packed_y_size,
|
| + packed_uv_size,
|
| + dst_y,
|
| + dst_u,
|
| + dst_v));
|
| + } else {
|
| + ASSERT_TRUE(gpu_ops->TransformRGBToYV12_WithoutMRT(src,
|
| + dst_size,
|
| + packed_y_size,
|
| + packed_uv_size,
|
| + dst_y,
|
| + dst_u,
|
| + dst_v));
|
| + }
|
| +
|
| + // UV size (in bytes/samples) is half, rounded up.
|
| + gfx::Size uv_size((dst_size.width() + 1) / 2,
|
| + (dst_size.height() + 1) / 2);
|
| +
|
| + // Generate a reference bitmap by calling a software implementation.
|
| + SkBitmap reference_rgb = ToSkBitmap(reference, false);
|
| + SkBitmap reference_rgb_scaled;
|
| + if (dst_size == src_size) {
|
| + reference_rgb_scaled = reference_rgb;
|
| + } else {
|
| + // We'll call Copy to do the bilinear scaling if needed.
|
| + base::win::ScopedComPtr<IDirect3DSurface9> reference_scaled;
|
| + ASSERT_TRUE(
|
| + d3d_utils::CreateTemporaryLockableSurface(
|
| + device(), dst_size, reference_scaled.Receive()));
|
| + ASSERT_TRUE(
|
| + gpu_ops->Copy(src, reference_scaled, dst_size));
|
| + BeforeLockWorkaround();
|
| + reference_rgb_scaled = ToSkBitmap(reference_scaled, false);
|
| + }
|
| +
|
| + scoped_ptr<uint8[]> reference_y(new uint8[dst_size.GetArea()]);
|
| + scoped_ptr<uint8[]> reference_u(new uint8[uv_size.GetArea()]);
|
| + scoped_ptr<uint8[]> reference_v(new uint8[uv_size.GetArea()]);
|
| + reference_rgb_scaled.lockPixels();
|
| + media::ConvertRGB32ToYUV_SSE2_Reference(
|
| + reinterpret_cast<uint8*>(reference_rgb_scaled.getAddr32(0, 0)),
|
| + &reference_y[0],
|
| + &reference_u[0],
|
| + &reference_v[0],
|
| + dst_size.width(),
|
| + dst_size.height(),
|
| + reference_rgb_scaled.rowBytes(),
|
| + dst_size.width(),
|
| + uv_size.width());
|
| + reference_rgb_scaled.unlockPixels();
|
| +
|
| + // Check for equality of the reference and the actual.
|
| + AssertSame(dst_size.width(), dst_size.height(), &reference_y[0], dst_y);
|
| + AssertSame(uv_size.width(), uv_size.height(), &reference_u[0], dst_u);
|
| + AssertSame(uv_size.width(), uv_size.height(), &reference_v[0], dst_v);
|
| +
|
| + if (kDumpImagesOnFailure && HasFatalFailure()) {
|
| + // Note that this will dump the full u and v buffers, including
|
| + // extra columns added due to packing. That means up to 7 extra
|
| + // columns for uv, and up to 3 extra columns for y.
|
| + WritePNGFile(reference_rgb,
|
| + FilePath(FILE_PATH_LITERAL("test_fail_src.png")));
|
| + WritePNGFile(reference_rgb_scaled,
|
| + FilePath(FILE_PATH_LITERAL("test_fail_src_scaled.png")));
|
| + WritePNGFile(ToSkBitmap(dst_y, true),
|
| + FilePath(FILE_PATH_LITERAL("test_fail_y.png")));
|
| + WritePNGFile(ToSkBitmap(dst_u, true),
|
| + FilePath(FILE_PATH_LITERAL("test_fail_u.png")));
|
| + WritePNGFile(ToSkBitmap(dst_v, true),
|
| + FilePath(FILE_PATH_LITERAL("test_fail_v.png")));
|
| + }
|
| + }
|
| +
|
| + int color_error_tolerance_;
|
| uniform_int_distribution<DWORD> random_dword_;
|
| std::mt19937 rng_;
|
| base::ScopedNativeLibrary d3d_module_;
|
| @@ -305,6 +576,8 @@ TEST_P(AcceleratedSurfaceTransformerTest, Init) {
|
| SCOPED_TRACE(GetAdapterInfo());
|
| AcceleratedSurfaceTransformer gpu_ops;
|
| ASSERT_TRUE(gpu_ops.Init(device()));
|
| +
|
| + WarnOnMissingFeatures(&gpu_ops);
|
| };
|
|
|
| // Fails on some bots because Direct3D isn't allowed.
|
| @@ -341,7 +614,6 @@ TEST_P(AcceleratedSurfaceTransformerTest, CopyInverted) {
|
| }
|
| }
|
|
|
| -
|
| // Fails on some bots because Direct3D isn't allowed.
|
| // Fails on other bots because of ResizeBilinear symmetry failures.
|
| // Should pass, at least, on NVIDIA Quadro 600.
|
| @@ -363,10 +635,14 @@ TEST_P(AcceleratedSurfaceTransformerTest, MixedOperations) {
|
| ASSERT_NO_FATAL_FAILURE(
|
| DoResizeBilinearTest(&t, gfx::Size(256, 256), gfx::Size(64, 64), 5));
|
| ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&t, gfx::Size(128, 128), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| DoResizeBilinearTest(&t, gfx::Size(255, 255), gfx::Size(3, 3), 1));
|
| ASSERT_NO_FATAL_FAILURE(
|
| DoCopyInvertedTest(&t, gfx::Size(1412, 124)));
|
| ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&t, gfx::Size(100, 200), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| DoResizeBilinearTest(&t, gfx::Size(255, 255), gfx::Size(257, 257), 1));
|
| ASSERT_NO_FATAL_FAILURE(
|
| DoResizeBilinearTest(&t, gfx::Size(255, 255), gfx::Size(257, 257), 2));
|
| @@ -380,6 +656,8 @@ TEST_P(AcceleratedSurfaceTransformerTest, MixedOperations) {
|
| ASSERT_NO_FATAL_FAILURE(
|
| DoCopyInvertedTest(&t, gfx::Size(1521, 3)));
|
| ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&t, gfx::Size(140, 181), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| DoResizeBilinearTest(&t, gfx::Size(150, 256), gfx::Size(126, 256), 1));
|
| ASSERT_NO_FATAL_FAILURE(
|
| DoCopyInvertedTest(&t, gfx::Size(33, 712)));
|
| @@ -425,6 +703,12 @@ TEST_P(AcceleratedSurfaceTransformerTest, LargeSurfaces) {
|
| DoCopyInvertedTest(&gpu_ops, gfx::Size(w, lo)));
|
| ASSERT_NO_FATAL_FAILURE(
|
| DoCopyInvertedTest(&gpu_ops, gfx::Size(lo, h)));
|
| +
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(w, lo), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(lo, h), 1));
|
| +
|
| }
|
|
|
| // Exercises ResizeBilinear with random minification cases where the
|
| @@ -440,8 +724,8 @@ TEST_P(AcceleratedSurfaceTransformerTest, MinifyUniform) {
|
| AcceleratedSurfaceTransformer gpu_ops;
|
| ASSERT_TRUE(gpu_ops.Init(device()));
|
|
|
| - int dims[] = { 21, 63, 64, 65, 99, 127, 128, 129, 192, 255, 256, 257};
|
| - int checkerboards[] = {1, 2, 3, 9};
|
| + const int dims[] = {21, 63, 64, 65, 99, 127, 128, 129, 192, 255, 256, 257};
|
| + const int checkerboards[] = {1, 2, 3, 9};
|
| uniform_int_distribution<int> dim(0, arraysize(dims) - 1);
|
| uniform_int_distribution<int> checkerboard(0, arraysize(checkerboards) - 1);
|
|
|
| @@ -481,8 +765,8 @@ TEST_P(AcceleratedSurfaceTransformerTest, DISABLED_MagnifyUniform) {
|
| AcceleratedSurfaceTransformer gpu_ops;
|
| ASSERT_TRUE(gpu_ops.Init(device()));
|
|
|
| - int dims[] = {63, 64, 65, 99, 127, 128, 129, 192, 255, 256, 257};
|
| - int checkerboards[] = {1, 2, 3, 9};
|
| + const int dims[] = {63, 64, 65, 99, 127, 128, 129, 192, 255, 256, 257};
|
| + const int checkerboards[] = {1, 2, 3, 9};
|
| uniform_int_distribution<int> dim(0, arraysize(dims) - 1);
|
| uniform_int_distribution<int> checkerboard(0, arraysize(checkerboards) - 1);
|
|
|
| @@ -507,6 +791,87 @@ TEST_P(AcceleratedSurfaceTransformerTest, DISABLED_MagnifyUniform) {
|
| }
|
| };
|
|
|
| +TEST_P(AcceleratedSurfaceTransformerTest, RGBtoYUV) {
|
| + SeedRandom("RGBtoYUV");
|
| +
|
| + AcceleratedSurfaceTransformer gpu_ops;
|
| + ASSERT_TRUE(gpu_ops.Init(device()));
|
| +
|
| + // Start with some easy-to-debug cases. A checkerboard size of 1 is the
|
| + // best test, but larger checkerboard sizes give more insight into where
|
| + // a bug might be.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(32, 32), 4));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(32, 32), 2));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(32, 32), 3));
|
| +
|
| + // All cases of width (mod 8) and height (mod 8), using 1x1 checkerboard.
|
| + for (int w = 32; w < 40; ++w) {
|
| + for (int h = 32; h < 40; ++h) {
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(w, h), 1));
|
| + }
|
| + }
|
| +
|
| + // All the very small sizes which require the most shifting in the
|
| + // texture coordinates when doing alignment.
|
| + for (int w = 1; w <= 9; ++w) {
|
| + for (int h = 1; h <= 9; ++h) {
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(w, h), 1));
|
| + }
|
| + }
|
| +
|
| + // Random medium dimensions.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(10, 142), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(124, 333), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(853, 225), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(231, 412), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(512, 128), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(1024, 768), 1));
|
| +
|
| + // Common video/monitor resolutions
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(800, 768), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(1024, 768), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(1280, 720), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(1280, 720), 2));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(1920, 1080), 1));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(1920, 1080), 2));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionTest(&gpu_ops, gfx::Size(2048, 1536), 1));
|
| +}
|
| +
|
| +TEST_P(AcceleratedSurfaceTransformerTest, RGBtoYUVScaled) {
|
| + SeedRandom("RGBtoYUVScaled");
|
| +
|
| + AcceleratedSurfaceTransformer gpu_ops;
|
| + ASSERT_TRUE(gpu_ops.Init(device()));
|
| +
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionScaleTest(&gpu_ops, gfx::Size(32, 32), gfx::Size(64, 64)));
|
| +
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionScaleTest(&gpu_ops, gfx::Size(32, 32), gfx::Size(16, 16)));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionScaleTest(&gpu_ops, gfx::Size(32, 32), gfx::Size(24, 24)));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + DoYUVConversionScaleTest(&gpu_ops, gfx::Size(32, 32), gfx::Size(48, 48)));
|
| +}
|
| +
|
| namespace {
|
|
|
| // Used to suppress test on Windows versions prior to Vista.
|
|
|