// Copyright 2019 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 <utility>

#include "media/base/media_util.h"
#include "media/base/win/d3d11_mocks.h"
#include "media/gpu/windows/d3d11_texture_selector.h"
#include "media/gpu/windows/d3d11_video_device_format_support.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::Combine;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::Values;

namespace media {

class D3D11TextureSelectorUnittest : public ::testing::Test {
 public:
  class MockFormatSupportChecker : public FormatSupportChecker {
   public:
    MockFormatSupportChecker() : FormatSupportChecker(nullptr) {}
    ~MockFormatSupportChecker() = default;
    bool Initialize() override { return true; }

    MOCK_CONST_METHOD1(CheckOutputFormatSupport, bool(DXGI_FORMAT));
  };

  VideoDecoderConfig CreateDecoderConfig(VideoCodecProfile profile,
                                         gfx::Size size,
                                         bool encrypted) {
    VideoDecoderConfig result;
    result.Initialize(
        VideoCodec::kUnknown,  // It doesn't matter because it won't
                               // be used.
        profile, VideoDecoderConfig::AlphaMode::kIsOpaque, VideoColorSpace(),
        kNoTransformation, size, {}, {}, {},
        encrypted ? EncryptionScheme::kCenc : EncryptionScheme::kUnencrypted);
    return result;
  }

  enum class ZeroCopyEnabled { kFalse = 0, kTrue = 1 };
  enum class ZeroCopyDisabledByWorkaround { kFalse = 0, kTrue = 1 };

  std::unique_ptr<TextureSelector> CreateWithDefaultGPUInfo(
      DXGI_FORMAT decoder_output_format,
      ZeroCopyEnabled zero_copy_enabled = ZeroCopyEnabled::kTrue,
      TextureSelector::HDRMode hdr_mode = TextureSelector::HDRMode::kSDROnly,
      ZeroCopyDisabledByWorkaround zero_copy_disabled_by_workaround =
          ZeroCopyDisabledByWorkaround::kFalse) {
    gpu::GpuPreferences prefs;
    prefs.enable_zero_copy_dxgi_video =
        zero_copy_enabled == ZeroCopyEnabled::kTrue;
    gpu::GpuDriverBugWorkarounds workarounds;
    workarounds.disable_dxgi_zero_copy_video =
        zero_copy_disabled_by_workaround == ZeroCopyDisabledByWorkaround::kTrue;
    auto media_log = std::make_unique<NullMediaLog>();
    return TextureSelector::Create(prefs, workarounds, decoder_output_format,
                                   hdr_mode, &format_checker_, nullptr, nullptr,
                                   media_log.get());
  }

  // Set the format checker to succeed any check, except for |disallowed|.
  void AllowFormatCheckerSupportExcept(std::vector<DXGI_FORMAT> disallowed) {
    ON_CALL(format_checker_, CheckOutputFormatSupport(_))
        .WillByDefault(Return(true));
    for (auto format : disallowed) {
      ON_CALL(format_checker_, CheckOutputFormatSupport(format))
          .WillByDefault(Return(false));
    }
  }

  MockFormatSupportChecker format_checker_;
};

TEST_F(D3D11TextureSelectorUnittest, NV12BindsToNV12) {
  // Nothing should ask about VideoProcessor support, since we're binding.
  EXPECT_CALL(format_checker_, CheckOutputFormatSupport(_)).Times(0);
  auto tex_sel = CreateWithDefaultGPUInfo(DXGI_FORMAT_NV12);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_NV12);
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_NV12);
  EXPECT_FALSE(tex_sel->WillCopyForTesting());
}

TEST_F(D3D11TextureSelectorUnittest, NV12CopiesToNV12WithoutSharingSupport) {
  AllowFormatCheckerSupportExcept({});
  auto tex_sel =
      CreateWithDefaultGPUInfo(DXGI_FORMAT_NV12, ZeroCopyEnabled::kFalse);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_NV12);
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_NV12);
  EXPECT_TRUE(tex_sel->WillCopyForTesting());
}

TEST_F(D3D11TextureSelectorUnittest, NV12CopiesToNV12WithWorkaround) {
  AllowFormatCheckerSupportExcept({});
  auto tex_sel = CreateWithDefaultGPUInfo(
      DXGI_FORMAT_NV12, ZeroCopyEnabled::kTrue,
      TextureSelector::HDRMode::kSDROnly, ZeroCopyDisabledByWorkaround::kTrue);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_NV12);
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_NV12);
  EXPECT_TRUE(tex_sel->WillCopyForTesting());
}

TEST_F(D3D11TextureSelectorUnittest, P010BindsP010InHDR) {
  // Allow all output formats, p010 should be the default.
  AllowFormatCheckerSupportExcept({});
  auto tex_sel =
      CreateWithDefaultGPUInfo(DXGI_FORMAT_P010, ZeroCopyEnabled::kTrue,
                               TextureSelector::HDRMode::kSDROrHDR);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_P016LE);
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_P010);
  EXPECT_FALSE(tex_sel->WillCopyForTesting());
  // TODO(liberato): Check output color space.
}

TEST_F(D3D11TextureSelectorUnittest, P010CopiesTo16bitRGBInHDR) {
  // 16 bit float should be the second choice after p010 zero copy.
  AllowFormatCheckerSupportExcept({DXGI_FORMAT_P010});
  auto tex_sel =
      CreateWithDefaultGPUInfo(DXGI_FORMAT_P010, ZeroCopyEnabled::kFalse,
                               TextureSelector::HDRMode::kSDROrHDR);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_RGBAF16);
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_R16G16B16A16_FLOAT);
  EXPECT_TRUE(tex_sel->WillCopyForTesting());
}

TEST_F(D3D11TextureSelectorUnittest, P010CopiesTo10BitRGBInHDR) {
  // 10 bit unorm should be the third and final choice.
  AllowFormatCheckerSupportExcept(
      {DXGI_FORMAT_P010, DXGI_FORMAT_R16G16B16A16_FLOAT});
  auto tex_sel =
      CreateWithDefaultGPUInfo(DXGI_FORMAT_P010, ZeroCopyEnabled::kFalse,
                               TextureSelector::HDRMode::kSDROrHDR);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_XB30);
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_R10G10B10A2_UNORM);
  EXPECT_TRUE(tex_sel->WillCopyForTesting());
}

TEST_F(D3D11TextureSelectorUnittest, P010CopiesTo8BitInSDR) {
  // Should copy to 8 bit RGB if the video processor can do it, if we're not in
  // HDR mode.
  AllowFormatCheckerSupportExcept({});
  auto tex_sel =
      CreateWithDefaultGPUInfo(DXGI_FORMAT_P010, ZeroCopyEnabled::kTrue,
                               TextureSelector::HDRMode::kSDROnly);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_ARGB);
  // Note that this might also produce 8 bit rgb, but for now always
  // tries for fp16.
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_B8G8R8A8_UNORM);
  EXPECT_TRUE(tex_sel->WillCopyForTesting());
  // TODO(liberato): Check output color space, somehow.
}

TEST_F(D3D11TextureSelectorUnittest, P010BindsToP010InSDR) {
  // Should bind P010 if the video processor can't convert to RGB8, if we're not
  // int HDR mode.
  AllowFormatCheckerSupportExcept({DXGI_FORMAT_B8G8R8A8_UNORM});
  auto tex_sel =
      CreateWithDefaultGPUInfo(DXGI_FORMAT_P010, ZeroCopyEnabled::kTrue,
                               TextureSelector::HDRMode::kSDROnly);

  EXPECT_EQ(tex_sel->PixelFormat(), PIXEL_FORMAT_P016LE);
  EXPECT_EQ(tex_sel->OutputDXGIFormat(), DXGI_FORMAT_P010);
  EXPECT_FALSE(tex_sel->WillCopyForTesting());
}

}  // namespace media
