// Copyright 2017 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 "gpu/ipc/service/direct_composition_surface_win.h"

#include "base/bind_helpers.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/win/scoped_gdi_object.h"
#include "base/win/scoped_hdc.h"
#include "base/win/scoped_select_object.h"
#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/win/hidden_window.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/gdi_util.h"
#include "ui/gfx/transform.h"
#include "ui/gl/dc_renderer_layer_params.h"
#include "ui/gl/gl_angle_util_win.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_image_dxgi.h"
#include "ui/gl/gl_image_ref_counted_memory.h"
#include "ui/gl/init/gl_factory.h"
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/platform_window/win/win_window.h"

namespace gpu {
namespace {

bool CheckIfDCSupported() {
  if (!gl::QueryDirectCompositionDevice(
          gl::QueryD3D11DeviceObjectFromANGLE())) {
    LOG(WARNING)
        << "GL implementation not using DirectComposition, skipping test.";
    return false;
  }
  return true;
}

class TestImageTransportSurfaceDelegate
    : public ImageTransportSurfaceDelegate,
      public base::SupportsWeakPtr<TestImageTransportSurfaceDelegate> {
 public:
  TestImageTransportSurfaceDelegate()
      : feature_info_(new gpu::gles2::FeatureInfo()) {}

  ~TestImageTransportSurfaceDelegate() override {}

  // ImageTransportSurfaceDelegate implementation.
  void DidCreateAcceleratedSurfaceChildWindow(
      SurfaceHandle parent_window,
      SurfaceHandle child_window) override {
    if (parent_window)
      ::SetParent(child_window, parent_window);
  }
  void DidSwapBuffersComplete(SwapBuffersCompleteParams params) override {}
  const gles2::FeatureInfo* GetFeatureInfo() const override {
    return feature_info_.get();
  }
  const GpuPreferences& GetGpuPreferences() const override {
    return gpu_preferences_;
  }
  void SetSnapshotRequestedCallback(const base::Closure& callback) override {}
  void UpdateVSyncParameters(base::TimeTicks timebase,
                             base::TimeDelta interval) override {}
  void BufferPresented(const gfx::PresentationFeedback& feedback) override {}
  void AddFilter(IPC::MessageFilter* message_filter) override {}
  int32_t GetRouteID() const override { return 0; }

 private:
  scoped_refptr<gpu::gles2::FeatureInfo> feature_info_;
  GpuPreferences gpu_preferences_;
};

class TestPlatformDelegate : public ui::PlatformWindowDelegate {
 public:
  // ui::PlatformWindowDelegate implementation.
  void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
  void OnDamageRect(const gfx::Rect& damaged_region) override {}
  void DispatchEvent(ui::Event* event) override {}
  void OnCloseRequest() override {}
  void OnClosed() override {}
  void OnWindowStateChanged(ui::PlatformWindowState new_state) override {}
  void OnLostCapture() override {}
  void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget,
                                    float device_pixel_ratio) override {}
  void OnAcceleratedWidgetDestroying() override {}
  void OnAcceleratedWidgetDestroyed() override {}
  void OnActivationChanged(bool active) override {}
};

void RunPendingTasks(scoped_refptr<base::TaskRunner> task_runner) {
  base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                           base::WaitableEvent::InitialState::NOT_SIGNALED);
  task_runner->PostTask(FROM_HERE,
                        Bind(&base::WaitableEvent::Signal, Unretained(&done)));
  done.Wait();
}

void DestroySurface(scoped_refptr<DirectCompositionSurfaceWin> surface) {
  scoped_refptr<base::TaskRunner> task_runner =
      surface->GetWindowTaskRunnerForTesting();
  DCHECK(surface->HasOneRef());

  surface = nullptr;

  // Ensure that the ChildWindowWin posts the task to delete the thread to the
  // main loop before doing RunUntilIdle. Otherwise the child threads could
  // outlive the main thread.
  RunPendingTasks(task_runner);

  base::RunLoop().RunUntilIdle();
}

Microsoft::WRL::ComPtr<ID3D11Texture2D> CreateNV12Texture(
    const Microsoft::WRL::ComPtr<ID3D11Device>& d3d11_device,
    const gfx::Size& size,
    bool shared) {
  D3D11_TEXTURE2D_DESC desc = {};
  desc.Width = size.width();
  desc.Height = size.height();
  desc.MipLevels = 1;
  desc.ArraySize = 1;
  desc.Format = DXGI_FORMAT_NV12;
  desc.Usage = D3D11_USAGE_DEFAULT;
  desc.SampleDesc.Count = 1;
  desc.BindFlags = 0;
  if (shared) {
    desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX |
                     D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
  }

  std::vector<char> image_data(size.width() * size.height() * 3 / 2);
  // Y, U, and V should all be 160. Output color should be pink.
  memset(&image_data[0], 160, size.width() * size.height() * 3 / 2);

  D3D11_SUBRESOURCE_DATA data = {};
  data.pSysMem = (const void*)&image_data[0];
  data.SysMemPitch = size.width();

  Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
  HRESULT hr =
      d3d11_device->CreateTexture2D(&desc, &data, texture.GetAddressOf());
  CHECK(SUCCEEDED(hr));
  return texture;
}

TEST(DirectCompositionSurfaceTest, TestMakeCurrent) {
  if (!CheckIfDCSupported())
    return;

  TestImageTransportSurfaceDelegate delegate;

  scoped_refptr<DirectCompositionSurfaceWin> surface1(
      new DirectCompositionSurfaceWin(nullptr, delegate.AsWeakPtr(),
                                      ui::GetHiddenWindow()));
  EXPECT_TRUE(surface1->Initialize());

  scoped_refptr<gl::GLContext> context1 = gl::init::CreateGLContext(
      nullptr, surface1.get(), gl::GLContextAttribs());
  EXPECT_TRUE(context1->MakeCurrent(surface1.get()));

  surface1->SetEnableDCLayers(true);
  EXPECT_TRUE(surface1->Resize(gfx::Size(100, 100), 1.0,
                               gl::GLSurface::ColorSpace::UNSPECIFIED, true));

  // First SetDrawRectangle must be full size of surface.
  EXPECT_FALSE(surface1->SetDrawRectangle(gfx::Rect(0, 0, 50, 50)));
  EXPECT_TRUE(surface1->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));

  // SetDrawRectangle can't be called again until swap.
  EXPECT_FALSE(surface1->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface1->SwapBuffers(base::DoNothing()));

  EXPECT_TRUE(context1->IsCurrent(surface1.get()));

  // SetDrawRectangle must be contained within surface.
  EXPECT_FALSE(surface1->SetDrawRectangle(gfx::Rect(0, 0, 101, 101)));
  EXPECT_TRUE(surface1->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
  EXPECT_TRUE(context1->IsCurrent(surface1.get()));

  EXPECT_TRUE(surface1->Resize(gfx::Size(50, 50), 1.0,
                               gl::GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_TRUE(context1->IsCurrent(surface1.get()));
  EXPECT_TRUE(surface1->SetDrawRectangle(gfx::Rect(0, 0, 50, 50)));
  EXPECT_TRUE(context1->IsCurrent(surface1.get()));

  scoped_refptr<DirectCompositionSurfaceWin> surface2(
      new DirectCompositionSurfaceWin(nullptr, delegate.AsWeakPtr(),
                                      ui::GetHiddenWindow()));
  EXPECT_TRUE(surface2->Initialize());

  scoped_refptr<gl::GLContext> context2 = gl::init::CreateGLContext(
      nullptr, surface2.get(), gl::GLContextAttribs());
  EXPECT_TRUE(context2->MakeCurrent(surface2.get()));

  surface2->SetEnableDCLayers(true);
  EXPECT_TRUE(surface2->Resize(gfx::Size(100, 100), 1.0,
                               gl::GLSurface::ColorSpace::UNSPECIFIED, true));
  // The previous IDCompositionSurface should be suspended when another
  // surface is being drawn to.
  EXPECT_TRUE(surface2->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
  EXPECT_TRUE(context2->IsCurrent(surface2.get()));

  // It should be possible to switch back to the previous surface and
  // unsuspend it.
  EXPECT_TRUE(context1->MakeCurrent(surface1.get()));
  context2 = nullptr;
  context1 = nullptr;

  DestroySurface(std::move(surface1));
  DestroySurface(std::move(surface2));
}

// Tests that switching using EnableDCLayers works.
TEST(DirectCompositionSurfaceTest, DXGIDCLayerSwitch) {
  if (!CheckIfDCSupported())
    return;

  TestImageTransportSurfaceDelegate delegate;

  scoped_refptr<DirectCompositionSurfaceWin> surface(
      new DirectCompositionSurfaceWin(nullptr, delegate.AsWeakPtr(),
                                      ui::GetHiddenWindow()));
  EXPECT_TRUE(surface->Initialize());

  scoped_refptr<gl::GLContext> context =
      gl::init::CreateGLContext(nullptr, surface.get(), gl::GLContextAttribs());
  EXPECT_TRUE(context->MakeCurrent(surface.get()));

  EXPECT_TRUE(surface->Resize(gfx::Size(100, 100), 1.0,
                              gl::GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_FALSE(surface->swap_chain());

  // First SetDrawRectangle must be full size of surface for DXGI
  // swapchain.
  EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 50, 50)));
  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
  EXPECT_TRUE(surface->swap_chain());

  // SetDrawRectangle can't be called again until swap.
  EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));

  EXPECT_TRUE(context->MakeCurrent(surface.get()));
  EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing()));

  EXPECT_TRUE(context->IsCurrent(surface.get()));

  surface->SetEnableDCLayers(true);

  // Surface switched to use IDCompositionSurface, so must draw to
  // entire surface.
  EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 50, 50)));
  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
  EXPECT_TRUE(context->IsCurrent(surface.get()));
  EXPECT_FALSE(surface->swap_chain());

  surface->SetEnableDCLayers(false);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing()));

  // Surface switched to use IDXGISwapChain, so must draw to entire
  // surface.
  EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 50, 50)));
  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
  EXPECT_TRUE(surface->swap_chain());

  context = nullptr;
  DestroySurface(std::move(surface));
}

// Ensure that the swapchain's alpha is correct.
TEST(DirectCompositionSurfaceTest, SwitchAlpha) {
  if (!CheckIfDCSupported())
    return;

  TestImageTransportSurfaceDelegate delegate;

  scoped_refptr<DirectCompositionSurfaceWin> surface(
      new DirectCompositionSurfaceWin(nullptr, delegate.AsWeakPtr(),
                                      ui::GetHiddenWindow()));
  EXPECT_TRUE(surface->Initialize());

  scoped_refptr<gl::GLContext> context =
      gl::init::CreateGLContext(nullptr, surface.get(), gl::GLContextAttribs());
  EXPECT_TRUE(context->MakeCurrent(surface.get()));

  EXPECT_TRUE(surface->Resize(gfx::Size(100, 100), 1.0,
                              gl::GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_FALSE(surface->swap_chain());

  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain = surface->swap_chain();
  ASSERT_TRUE(swap_chain);
  DXGI_SWAP_CHAIN_DESC1 desc;
  swap_chain->GetDesc1(&desc);
  EXPECT_EQ(DXGI_ALPHA_MODE_PREMULTIPLIED, desc.AlphaMode);

  // Resize to the same parameters should have no effect.
  EXPECT_TRUE(surface->Resize(gfx::Size(100, 100), 1.0,
                              gl::GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_TRUE(surface->swap_chain());

  EXPECT_TRUE(surface->Resize(gfx::Size(100, 100), 1.0,
                              gl::GLSurface::ColorSpace::UNSPECIFIED, false));
  EXPECT_FALSE(surface->swap_chain());

  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));

  swap_chain = surface->swap_chain();
  ASSERT_TRUE(swap_chain);
  swap_chain->GetDesc1(&desc);
  EXPECT_EQ(DXGI_ALPHA_MODE_IGNORE, desc.AlphaMode);

  context = nullptr;
  DestroySurface(std::move(surface));
}

// Ensure that the GLImage isn't presented again unless it changes.
TEST(DirectCompositionSurfaceTest, NoPresentTwice) {
  if (!CheckIfDCSupported())
    return;

  TestImageTransportSurfaceDelegate delegate;
  scoped_refptr<DirectCompositionSurfaceWin> surface(
      new DirectCompositionSurfaceWin(nullptr, delegate.AsWeakPtr(),
                                      ui::GetHiddenWindow()));
  EXPECT_TRUE(surface->Initialize());

  scoped_refptr<gl::GLContext> context =
      gl::init::CreateGLContext(nullptr, surface.get(), gl::GLContextAttribs());
  EXPECT_TRUE(context->MakeCurrent(surface.get()));

  surface->SetEnableDCLayers(true);

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      gl::QueryD3D11DeviceObjectFromANGLE();

  gfx::Size texture_size(50, 50);
  Microsoft::WRL::ComPtr<ID3D11Texture2D> texture =
      CreateNV12Texture(d3d11_device, texture_size, false);

  scoped_refptr<gl::GLImageDXGI> image_dxgi(
      new gl::GLImageDXGI(texture_size, nullptr));
  image_dxgi->SetTexture(texture, 0);
  image_dxgi->SetColorSpace(gfx::ColorSpace::CreateREC709());

  gfx::Size window_size(100, 100);
  ui::DCRendererLayerParams params(
      false, gfx::Rect(), 1, gfx::Transform(),
      std::vector<scoped_refptr<gl::GLImage>>{image_dxgi},
      gfx::RectF(gfx::Rect(texture_size)), gfx::Rect(window_size), 0, 0, 1.0, 0,
      false);
  surface->ScheduleDCLayer(params);

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface->GetLayerSwapChainForTesting(1);
  ASSERT_FALSE(swap_chain);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing()));

  swap_chain = surface->GetLayerSwapChainForTesting(1);
  ASSERT_TRUE(swap_chain);

  UINT last_present_count = 0;
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetLastPresentCount(&last_present_count)));

  // One present is normal, and a second present because it's the first frame
  // and the other buffer needs to be drawn to.
  EXPECT_EQ(2u, last_present_count);

  surface->ScheduleDCLayer(params);
  EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing()));

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain2 =
      surface->GetLayerSwapChainForTesting(1);
  EXPECT_EQ(swap_chain2.Get(), swap_chain.Get());

  // It's the same image, so it should have the same swapchain.
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetLastPresentCount(&last_present_count)));
  EXPECT_EQ(2u, last_present_count);

  // The size of the swapchain changed, so it should be recreated.
  ui::DCRendererLayerParams params2(
      false, gfx::Rect(), 1, gfx::Transform(),
      std::vector<scoped_refptr<gl::GLImage>>{image_dxgi},
      gfx::RectF(gfx::Rect(texture_size)), gfx::Rect(0, 0, 25, 25), 0, 0, 1.0,
      0, false);
  surface->ScheduleDCLayer(params2);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers(base::DoNothing()));

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain3 =
      surface->GetLayerSwapChainForTesting(1);
  EXPECT_NE(swap_chain2.Get(), swap_chain3.Get());

  context = nullptr;
  DestroySurface(std::move(surface));
}

SkColor ReadBackWindowPixel(HWND window, const gfx::Point& point) {
  base::win::ScopedCreateDC mem_hdc(::CreateCompatibleDC(nullptr));
  void* bits = nullptr;
  BITMAPV4HEADER hdr;
  gfx::CreateBitmapV4Header(point.x() + 1, point.y() + 1, &hdr);
  DCHECK(mem_hdc.IsValid());
  base::win::ScopedBitmap bitmap(
      ::CreateDIBSection(mem_hdc.Get(), reinterpret_cast<BITMAPINFO*>(&hdr),
                         DIB_RGB_COLORS, &bits, nullptr, 0));
  DCHECK(bitmap.is_valid());

  base::win::ScopedSelectObject select_object(mem_hdc.Get(), bitmap.get());

  // Grab a copy of the window. Use PrintWindow because it works even when the
  // window's partially occluded. The PW_RENDERFULLCONTENT flag is undocumented,
  // but works starting in Windows 8.1. It allows for capturing the contents of
  // the window that are drawn using DirectComposition.
  UINT flags = PW_CLIENTONLY | PW_RENDERFULLCONTENT;

  BOOL result = PrintWindow(window, mem_hdc.Get(), flags);
  if (!result)
    PLOG(ERROR) << "Failed to print window";

  GdiFlush();

  uint32_t pixel_value =
      static_cast<uint32_t*>(bits)[hdr.bV4Width * point.y() + point.x()];

  return static_cast<SkColor>(pixel_value);
}

class DirectCompositionPixelTest : public testing::Test {
 public:
  DirectCompositionPixelTest()
      : window_(&platform_delegate_, gfx::Rect(0, 0, 100, 100)) {}

  ~DirectCompositionPixelTest() override {
    context_ = nullptr;
    if (surface_)
      DestroySurface(std::move(surface_));
  }

 protected:
  void InitializeSurface() {
    static_cast<ui::PlatformWindow*>(&window_)->Show();

    surface_ = new DirectCompositionSurfaceWin(nullptr, delegate_.AsWeakPtr(),
                                               window_.hwnd());
    EXPECT_TRUE(surface_->Initialize());
    context_ = gl::init::CreateGLContext(nullptr, surface_.get(),
                                         gl::GLContextAttribs());
    EXPECT_TRUE(context_->MakeCurrent(surface_.get()));
  }

  void PixelTestSwapChain(bool layers_enabled) {
    if (!CheckIfDCSupported())
      return;

    InitializeSurface();

    surface_->SetEnableDCLayers(layers_enabled);
    gfx::Size window_size(100, 100);
    EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                                 gl::GLSurface::ColorSpace::UNSPECIFIED, true));
    EXPECT_TRUE(surface_->SetDrawRectangle(gfx::Rect(window_size)));

    glClearColor(1.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
              surface_->SwapBuffers(base::DoNothing()));

    // Ensure DWM swap completed.
    Sleep(1000);

    SkColor expected_color = SK_ColorRED;
    SkColor actual_color =
        ReadBackWindowPixel(window_.hwnd(), gfx::Point(75, 75));
    EXPECT_EQ(expected_color, actual_color)
        << std::hex << "Expected " << expected_color << " Actual "
        << actual_color;

    EXPECT_TRUE(context_->IsCurrent(surface_.get()));
  }

  TestPlatformDelegate platform_delegate_;
  TestImageTransportSurfaceDelegate delegate_;
  ui::WinWindow window_;
  scoped_refptr<DirectCompositionSurfaceWin> surface_;
  scoped_refptr<gl::GLContext> context_;
};

TEST_F(DirectCompositionPixelTest, DCLayersEnabled) {
  PixelTestSwapChain(true);
}

TEST_F(DirectCompositionPixelTest, DCLayersDisabled) {
  PixelTestSwapChain(false);
}

bool AreColorsSimilar(int a, int b) {
  // The precise colors may differ depending on the video processor, so allow
  // a margin for error.
  const int kMargin = 10;
  return abs(SkColorGetA(a) - SkColorGetA(b)) < kMargin &&
         abs(SkColorGetR(a) - SkColorGetR(b)) < kMargin &&
         abs(SkColorGetG(a) - SkColorGetG(b)) < kMargin &&
         abs(SkColorGetB(a) - SkColorGetB(b)) < kMargin;
}

class DirectCompositionVideoPixelTest : public DirectCompositionPixelTest {
 protected:
  void TestVideo(const gfx::ColorSpace& color_space,
                 SkColor expected_color,
                 bool check_color) {
    if (!CheckIfDCSupported())
      return;
    InitializeSurface();
    surface_->SetEnableDCLayers(true);

    gfx::Size window_size(100, 100);
    EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                                 gl::GLSurface::ColorSpace::UNSPECIFIED, true));

    Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
        gl::QueryD3D11DeviceObjectFromANGLE();

    gfx::Size texture_size(50, 50);
    Microsoft::WRL::ComPtr<ID3D11Texture2D> texture =
        CreateNV12Texture(d3d11_device, texture_size, false);

    scoped_refptr<gl::GLImageDXGI> image_dxgi(
        new gl::GLImageDXGI(texture_size, nullptr));
    image_dxgi->SetTexture(texture, 0);
    image_dxgi->SetColorSpace(color_space);

    ui::DCRendererLayerParams params(
        false, gfx::Rect(), 1, gfx::Transform(),
        std::vector<scoped_refptr<gl::GLImage>>{image_dxgi},
        gfx::RectF(gfx::Rect(texture_size)), gfx::Rect(texture_size), 0, 0, 1.0,
        0, false);
    surface_->ScheduleDCLayer(params);

    EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
              surface_->SwapBuffers(base::DoNothing()));

    // Scaling up the swapchain with the same image should cause it to be
    // transformed again, but not presented again.
    ui::DCRendererLayerParams params2(
        false, gfx::Rect(), 1, gfx::Transform(),
        std::vector<scoped_refptr<gl::GLImage>>{image_dxgi},
        gfx::RectF(gfx::Rect(texture_size)), gfx::Rect(window_size), 0, 0, 1.0,
        0, false);
    surface_->ScheduleDCLayer(params2);

    EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
              surface_->SwapBuffers(base::DoNothing()));
    Sleep(1000);

    if (check_color) {
      SkColor actual_color =
          ReadBackWindowPixel(window_.hwnd(), gfx::Point(75, 75));
      EXPECT_TRUE(AreColorsSimilar(expected_color, actual_color))
          << std::hex << "Expected " << expected_color << " Actual "
          << actual_color;
    }
  }
};

TEST_F(DirectCompositionVideoPixelTest, BT601) {
  TestVideo(gfx::ColorSpace::CreateREC601(), SkColorSetRGB(0xdb, 0x81, 0xe8),
            true);
}

TEST_F(DirectCompositionVideoPixelTest, BT709) {
  TestVideo(gfx::ColorSpace::CreateREC709(), SkColorSetRGB(0xe1, 0x90, 0xeb),
            true);
}

TEST_F(DirectCompositionVideoPixelTest, SRGB) {
  // SRGB doesn't make sense on an NV12 input, but don't crash.
  TestVideo(gfx::ColorSpace::CreateSRGB(), SK_ColorTRANSPARENT, false);
}

TEST_F(DirectCompositionVideoPixelTest, SCRGBLinear) {
  // SCRGB doesn't make sense on an NV12 input, but don't crash.
  TestVideo(gfx::ColorSpace::CreateSCRGBLinear(), SK_ColorTRANSPARENT, false);
}

TEST_F(DirectCompositionVideoPixelTest, InvalidColorSpace) {
  // Invalid color space should be treated as BT.709
  TestVideo(gfx::ColorSpace(), SkColorSetRGB(0xe1, 0x90, 0xeb), true);
}

TEST_F(DirectCompositionPixelTest, SoftwareVideoSwapchain) {
  if (!CheckIfDCSupported())
    return;
  InitializeSurface();
  surface_->SetEnableDCLayers(true);

  gfx::Size window_size(100, 100);
  EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                               gl::GLSurface::ColorSpace::UNSPECIFIED, true));

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      gl::QueryD3D11DeviceObjectFromANGLE();

  gfx::Size y_size(50, 50);
  gfx::Size uv_size(25, 25);
  size_t y_stride =
      gfx::RowSizeForBufferFormat(y_size.width(), gfx::BufferFormat::R_8, 0);
  size_t uv_stride =
      gfx::RowSizeForBufferFormat(uv_size.width(), gfx::BufferFormat::RG_88, 0);
  std::vector<uint8_t> y_data(y_stride * y_size.height(), 0xff);
  std::vector<uint8_t> uv_data(uv_stride * uv_size.height(), 0xff);
  scoped_refptr<gl::GLImageRefCountedMemory> y_image(
      new gl::GLImageRefCountedMemory(y_size, GL_BGRA_EXT));

  y_image->Initialize(new base::RefCountedBytes(y_data),
                      gfx::BufferFormat::R_8);
  scoped_refptr<gl::GLImageRefCountedMemory> uv_image(
      new gl::GLImageRefCountedMemory(uv_size, GL_BGRA_EXT));
  uv_image->Initialize(new base::RefCountedBytes(uv_data),
                       gfx::BufferFormat::RG_88);
  y_image->SetColorSpace(gfx::ColorSpace::CreateREC709());

  ui::DCRendererLayerParams params(
      false, gfx::Rect(), 1, gfx::Transform(),
      std::vector<scoped_refptr<gl::GLImage>>{y_image, uv_image},
      gfx::RectF(gfx::Rect(y_size)), gfx::Rect(window_size), 0, 0, 1.0, 0,
      false);
  surface_->ScheduleDCLayer(params);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));
  Sleep(1000);

  SkColor expected_color = SkColorSetRGB(0xff, 0xb7, 0xff);
  SkColor actual_color =
      ReadBackWindowPixel(window_.hwnd(), gfx::Point(75, 75));
  EXPECT_TRUE(AreColorsSimilar(expected_color, actual_color))
      << std::hex << "Expected " << expected_color << " Actual "
      << actual_color;
}

TEST_F(DirectCompositionPixelTest, VideoHandleSwapchain) {
  if (!CheckIfDCSupported())
    return;
  InitializeSurface();
  surface_->SetEnableDCLayers(true);

  gfx::Size window_size(100, 100);
  EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                               gl::GLSurface::ColorSpace::UNSPECIFIED, true));

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      gl::QueryD3D11DeviceObjectFromANGLE();

  gfx::Size texture_size(50, 50);
  Microsoft::WRL::ComPtr<ID3D11Texture2D> texture =
      CreateNV12Texture(d3d11_device, texture_size, true);
  Microsoft::WRL::ComPtr<IDXGIResource1> resource;
  texture.CopyTo(resource.GetAddressOf());
  HANDLE handle = 0;
  resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr,
                               &handle);
  // The format doesn't matter, since we aren't binding.
  scoped_refptr<gl::GLImageDXGIHandle> image_dxgi(
      new gl::GLImageDXGIHandle(texture_size, 0, gfx::BufferFormat::RGBA_8888));
  ASSERT_TRUE(image_dxgi->Initialize(base::win::ScopedHandle(handle)));

  ui::DCRendererLayerParams params(
      false, gfx::Rect(), 1, gfx::Transform(),
      std::vector<scoped_refptr<gl::GLImage>>{image_dxgi},
      gfx::RectF(gfx::Rect(texture_size)), gfx::Rect(window_size), 0, 0, 1.0, 0,
      false);
  surface_->ScheduleDCLayer(params);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));

  Sleep(1000);

  SkColor expected_color = SkColorSetRGB(0xe1, 0x90, 0xeb);
  SkColor actual_color =
      ReadBackWindowPixel(window_.hwnd(), gfx::Point(75, 75));
  EXPECT_TRUE(AreColorsSimilar(expected_color, actual_color))
      << std::hex << "Expected " << expected_color << " Actual "
      << actual_color;
}

TEST_F(DirectCompositionPixelTest, SkipVideoLayerEmptyBoundsRect) {
  if (!CheckIfDCSupported())
    return;
  InitializeSurface();
  surface_->SetEnableDCLayers(true);

  gfx::Size window_size(100, 100);
  EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                               gl::GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_TRUE(surface_->SetDrawRectangle(gfx::Rect(window_size)));

  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT);

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      gl::QueryD3D11DeviceObjectFromANGLE();

  gfx::Size texture_size(50, 50);
  Microsoft::WRL::ComPtr<ID3D11Texture2D> texture =
      CreateNV12Texture(d3d11_device, texture_size, true);
  Microsoft::WRL::ComPtr<IDXGIResource1> resource;
  texture.CopyTo(resource.GetAddressOf());
  HANDLE handle = 0;
  resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr,
                               &handle);
  // The format doesn't matter, since we aren't binding.
  scoped_refptr<gl::GLImageDXGIHandle> image_dxgi(
      new gl::GLImageDXGIHandle(texture_size, 0, gfx::BufferFormat::RGBA_8888));
  ASSERT_TRUE(image_dxgi->Initialize(base::win::ScopedHandle(handle)));

  // Layer with empty bounds rect.
  gfx::Rect bounds_rect;
  ui::DCRendererLayerParams params(
      false, gfx::Rect(), 1, gfx::Transform(),
      std::vector<scoped_refptr<gl::GLImage>>{image_dxgi},
      gfx::RectF(gfx::Rect(texture_size)), bounds_rect, 0, 0, 1.0, 0, false);
  surface_->ScheduleDCLayer(params);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));

  Sleep(1000);

  // No color is written since the visual committed to DirectComposition has no
  // content.
  SkColor expected_color = SK_ColorBLACK;
  SkColor actual_color =
      ReadBackWindowPixel(window_.hwnd(), gfx::Point(75, 75));
  EXPECT_TRUE(AreColorsSimilar(expected_color, actual_color))
      << std::hex << "Expected " << expected_color << " Actual "
      << actual_color;
}

TEST_F(DirectCompositionPixelTest, SkipVideoLayerEmptyContentsRect) {
  if (!CheckIfDCSupported())
    return;
  InitializeSurface();
  // Swap chain size is overridden to content rect size only if scaled overlays
  // are supported.
  DirectCompositionSurfaceWin::EnableScaledOverlaysForTesting();
  surface_->SetEnableDCLayers(true);

  gfx::Size window_size(100, 100);
  EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                               gl::GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_TRUE(surface_->SetDrawRectangle(gfx::Rect(window_size)));

  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT);

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      gl::QueryD3D11DeviceObjectFromANGLE();

  gfx::Size texture_size(50, 50);
  Microsoft::WRL::ComPtr<ID3D11Texture2D> texture =
      CreateNV12Texture(d3d11_device, texture_size, true);
  Microsoft::WRL::ComPtr<IDXGIResource1> resource;
  texture.CopyTo(resource.GetAddressOf());
  HANDLE handle = 0;
  resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr,
                               &handle);
  // The format doesn't matter, since we aren't binding.
  scoped_refptr<gl::GLImageDXGIHandle> image_dxgi(
      new gl::GLImageDXGIHandle(texture_size, 0, gfx::BufferFormat::RGBA_8888));
  ASSERT_TRUE(image_dxgi->Initialize(base::win::ScopedHandle(handle)));

  // Layer with empty content rect.
  gfx::RectF contents_rect;
  ui::DCRendererLayerParams params(
      false, gfx::Rect(), 1, gfx::Transform(),
      std::vector<scoped_refptr<gl::GLImage>>{image_dxgi}, contents_rect,
      gfx::Rect(window_size), 0, 0, 1.0, 0, false);
  surface_->ScheduleDCLayer(params);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));

  Sleep(1000);

  // No color is written since the visual committed to DirectComposition has no
  // content.
  SkColor expected_color = SK_ColorBLACK;
  SkColor actual_color =
      ReadBackWindowPixel(window_.hwnd(), gfx::Point(75, 75));
  EXPECT_TRUE(AreColorsSimilar(expected_color, actual_color))
      << std::hex << "Expected " << expected_color << " Actual "
      << actual_color;
}

}  // namespace
}  // namespace gpu
