// 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 "ui/gl/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 "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_d3d.h"
#include "ui/gl/gl_image_dxgi.h"
#include "ui/gl/gl_image_ref_counted_memory.h"
#include "ui/gl/gl_version_info.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 gl {
namespace {
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) override {}
  void OnAcceleratedWidgetDestroyed() override {}
  void OnActivationChanged(bool active) override {}
  void OnMouseEnter() 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);
  CHECK(SUCCEEDED(hr));
  return texture;
}

class DirectCompositionSurfaceTest : public testing::Test {
 public:
  DirectCompositionSurfaceTest() : parent_window_(ui::GetHiddenWindow()) {}

 protected:
  void SetUp() override {
    // Without this, the following check always fails.
    gl::init::InitializeGLNoExtensionsOneOff();
    if (!QueryDirectCompositionDevice(QueryD3D11DeviceObjectFromANGLE())) {
      LOG(WARNING)
          << "GL implementation not using DirectComposition, skipping test.";
      return;
    }
    surface_ = CreateDirectCompositionSurfaceWin();
    context_ = CreateGLContext(surface_);
    if (surface_)
      surface_->SetEnableDCLayers(true);
    DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(false);
    DirectCompositionSurfaceWin::SetOverlayFormatUsedForTesting(
        DXGI_FORMAT_NV12);
  }

  void TearDown() override {
    context_ = nullptr;
    if (surface_)
      DestroySurface(std::move(surface_));
    gl::init::ShutdownGL(false);
  }

  scoped_refptr<DirectCompositionSurfaceWin>
  CreateDirectCompositionSurfaceWin() {
    DirectCompositionSurfaceWin::Settings settings;
    scoped_refptr<DirectCompositionSurfaceWin> surface =
        base::MakeRefCounted<DirectCompositionSurfaceWin>(
            /*vsync_provider=*/nullptr,
            DirectCompositionSurfaceWin::VSyncCallback(), parent_window_,
            settings);
    EXPECT_TRUE(surface->Initialize(GLSurfaceFormat()));

    // ImageTransportSurfaceDelegate::DidCreateAcceleratedSurfaceChildWindow()
    // is called in production code here. However, to remove dependency from
    // gpu/ipc/service/image_transport_surface_delegate.h, here we directly
    // executes the required minimum code.
    if (parent_window_)
      ::SetParent(surface->window(), parent_window_);

    return surface;
  }

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

  HWND parent_window_;
  scoped_refptr<DirectCompositionSurfaceWin> surface_;
  scoped_refptr<GLContext> context_;
};

TEST_F(DirectCompositionSurfaceTest, TestMakeCurrent) {
  if (!surface_)
    return;
  EXPECT_TRUE(surface_->Resize(gfx::Size(100, 100), 1.0,
                               GLSurface::ColorSpace::UNSPECIFIED, true));

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

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

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

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

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

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

  scoped_refptr<DirectCompositionSurfaceWin> surface2 =
      CreateDirectCompositionSurfaceWin();
  scoped_refptr<GLContext> context2 = CreateGLContext(surface2.get());

  surface2->SetEnableDCLayers(true);
  EXPECT_TRUE(surface2->Resize(gfx::Size(100, 100), 1.0,
                               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(context_->MakeCurrent(surface_.get()));
  context2 = nullptr;
  DestroySurface(std::move(surface2));
}

// Tests that switching using EnableDCLayers works.
TEST_F(DirectCompositionSurfaceTest, DXGIDCLayerSwitch) {
  if (!surface_)
    return;
  surface_->SetEnableDCLayers(false);
  EXPECT_TRUE(surface_->Resize(gfx::Size(100, 100), 1.0,
                               GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_FALSE(surface_->GetBackbufferSwapChainForTesting());

  // 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_->GetBackbufferSwapChainForTesting());

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

  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_FALSE(surface_->GetBackbufferSwapChainForTesting());

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));
  EXPECT_TRUE(context_->IsCurrent(surface_.get()));

  surface_->SetEnableDCLayers(false);

  // 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_->GetBackbufferSwapChainForTesting());

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));
  EXPECT_TRUE(context_->IsCurrent(surface_.get()));
}

// Ensure that the swapchain's alpha is correct.
TEST_F(DirectCompositionSurfaceTest, SwitchAlpha) {
  if (!surface_)
    return;
  surface_->SetEnableDCLayers(false);
  EXPECT_TRUE(surface_->Resize(gfx::Size(100, 100), 1.0,
                               GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_FALSE(surface_->GetBackbufferSwapChainForTesting());

  EXPECT_TRUE(surface_->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface_->GetBackbufferSwapChainForTesting();
  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,
                               GLSurface::ColorSpace::UNSPECIFIED, true));
  EXPECT_TRUE(surface_->GetBackbufferSwapChainForTesting());

  EXPECT_TRUE(surface_->Resize(gfx::Size(100, 100), 1.0,
                               GLSurface::ColorSpace::UNSPECIFIED, false));
  EXPECT_FALSE(surface_->GetBackbufferSwapChainForTesting());

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

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

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

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

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

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

  ui::DCRendererLayerParams params;
  params.images[0] = image_dxgi;
  params.content_rect = gfx::Rect(texture_size);
  params.quad_rect = gfx::Rect(100, 100);
  surface_->ScheduleDCLayer(params);

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_FALSE(swap_chain);

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

  swap_chain = surface_->GetLayerSwapChainForTesting(0);
  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(0);
  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 image changed, we should get a new present
  scoped_refptr<GLImageDXGI> image_dxgi2(
      new GLImageDXGI(texture_size, nullptr));
  image_dxgi2->SetTexture(texture, 0);
  image_dxgi2->SetColorSpace(gfx::ColorSpace::CreateREC709());

  params.images[0] = image_dxgi2;
  params.images[1] = image_dxgi2;
  surface_->ScheduleDCLayer(params);

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

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain3 =
      surface_->GetLayerSwapChainForTesting(0);
  EXPECT_TRUE(SUCCEEDED(swap_chain3->GetLastPresentCount(&last_present_count)));
  // the present count should increase with the new present
  EXPECT_EQ(3u, last_present_count);
}

// Ensure the swapchain size is set to the correct size if HW overlay scaling
// is support - swapchain should be the minimum of the decoded
// video buffer size and the onscreen video size
TEST_F(DirectCompositionSurfaceTest, SwapchainSizeWithScaledOverlays) {
  if (!surface_)
    return;

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

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

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

  // HW supports scaled overlays
  // The input texture size is maller than the window size.
  DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(true);

  ui::DCRendererLayerParams params;
  params.images[0] = image_dxgi;
  params.content_rect = gfx::Rect(texture_size);
  params.quad_rect = gfx::Rect(100, 100);
  surface_->ScheduleDCLayer(params);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));
  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_TRUE(swap_chain);

  DXGI_SWAP_CHAIN_DESC Desc;
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc(&Desc)));
  EXPECT_EQ((int)Desc.BufferDesc.Width, texture_size.width());
  EXPECT_EQ((int)Desc.BufferDesc.Height, texture_size.height());

  // Clear SwapChainPresenters
  // Must do Clear first because the swap chain won't resize immediately if
  // a new size is given unless this is the very first time after Clear.
  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));

  // The input texture size is bigger than the window size.
  params.quad_rect = gfx::Rect(32, 48);

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

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain2 =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_TRUE(swap_chain2);

  EXPECT_TRUE(SUCCEEDED(swap_chain2->GetDesc(&Desc)));
  EXPECT_EQ((int)Desc.BufferDesc.Width, params.quad_rect.width());
  EXPECT_EQ((int)Desc.BufferDesc.Height, params.quad_rect.height());
}

// Ensure the swapchain size is set to the correct size if HW overlay scaling
// is not support - swapchain should be the onscreen video size
TEST_F(DirectCompositionSurfaceTest, SwapchainSizeWithoutScaledOverlays) {
  if (!surface_)
    return;

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

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

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

  ui::DCRendererLayerParams params;
  params.images[0] = image_dxgi;
  params.content_rect = gfx::Rect(texture_size);
  params.quad_rect = gfx::Rect(42, 42);
  surface_->ScheduleDCLayer(params);

  EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
            surface_->SwapBuffers(base::DoNothing()));
  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_TRUE(swap_chain);

  DXGI_SWAP_CHAIN_DESC desc;
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc(&desc)));
  EXPECT_EQ((int)desc.BufferDesc.Width, params.quad_rect.width());
  EXPECT_EQ((int)desc.BufferDesc.Height, params.quad_rect.height());

  // The input texture size is smaller than the window size.
  params.quad_rect = gfx::Rect(124, 136);

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

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain2 =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_TRUE(swap_chain2);

  EXPECT_TRUE(SUCCEEDED(swap_chain2->GetDesc(&desc)));
  EXPECT_EQ((int)desc.BufferDesc.Width, params.quad_rect.width());
  EXPECT_EQ((int)desc.BufferDesc.Height, params.quad_rect.height());
}

// Test protected video flags
TEST_F(DirectCompositionSurfaceTest, ProtectedVideos) {
  if (!surface_)
    return;

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

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

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

  // Clear video
  {
    ui::DCRendererLayerParams params;
    params.images[0] = image_dxgi;

    params.quad_rect = gfx::Rect(window_size);
    params.content_rect = gfx::Rect(texture_size);
    params.protected_video_type = gfx::ProtectedVideoType::kClear;

    surface_->ScheduleDCLayer(params);
    EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
              surface_->SwapBuffers(base::DoNothing()));
    Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
        surface_->GetLayerSwapChainForTesting(0);
    ASSERT_TRUE(swap_chain);

    DXGI_SWAP_CHAIN_DESC Desc;
    EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc(&Desc)));
    unsigned display_only_flag = Desc.Flags & DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY;
    unsigned hw_protected_flag = Desc.Flags & DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED;
    EXPECT_EQ(display_only_flag, (unsigned)0);
    EXPECT_EQ(hw_protected_flag, (unsigned)0);
  }

  // Software protected video
  {
    ui::DCRendererLayerParams params;
    params.images[0] = image_dxgi;

    params.quad_rect = gfx::Rect(window_size);
    params.content_rect = gfx::Rect(texture_size);
    params.protected_video_type = gfx::ProtectedVideoType::kSoftwareProtected;

    surface_->ScheduleDCLayer(params);
    EXPECT_EQ(gfx::SwapResult::SWAP_ACK,
              surface_->SwapBuffers(base::DoNothing()));
    Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
        surface_->GetLayerSwapChainForTesting(0);
    ASSERT_TRUE(swap_chain);

    DXGI_SWAP_CHAIN_DESC Desc;
    EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc(&Desc)));
    unsigned display_only_flag = Desc.Flags & DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY;
    unsigned hw_protected_flag = Desc.Flags & DXGI_SWAP_CHAIN_FLAG_HW_PROTECTED;
    EXPECT_EQ(display_only_flag, (unsigned)DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY);
    EXPECT_EQ(hw_protected_flag, (unsigned)0);
  }

  // TODO(magchen): Add a hardware protected video test when hardware procted
  // video support is enabled by defaut in the Intel driver and Chrome
}

std::vector<SkColor> ReadBackWindow(HWND window, const gfx::Size& size) {
  base::win::ScopedCreateDC mem_hdc(::CreateCompatibleDC(nullptr));
  DCHECK(mem_hdc.IsValid());

  BITMAPV4HEADER hdr;
  gfx::CreateBitmapV4Header(size.width(), size.height(), &hdr);

  void* bits = nullptr;
  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();

  std::vector<SkColor> pixels(size.width() * size.height());
  memcpy(pixels.data(), bits, pixels.size() * sizeof(SkColor));
  return pixels;
}

SkColor ReadBackWindowPixel(HWND window, const gfx::Point& point) {
  gfx::Size size(point.x() + 1, point.y() + 1);
  auto pixels = ReadBackWindow(window, size);
  return pixels[size.width() * point.y() + point.x()];
}

class DirectCompositionPixelTest : public DirectCompositionSurfaceTest {
 public:
  DirectCompositionPixelTest()
      : window_(&platform_delegate_, gfx::Rect(100, 100)) {
    parent_window_ = window_.hwnd();
  }

 protected:
  void SetUp() override {
    static_cast<ui::PlatformWindow*>(&window_)->Show();
    DirectCompositionSurfaceTest::SetUp();
  }

  void TearDown() override {
    // Test harness times out without DestroyWindow() here.
    if (IsWindow(parent_window_))
      DestroyWindow(parent_window_);
    DirectCompositionSurfaceTest::TearDown();
  }

  void InitializeForPixelTest(const gfx::Size& window_size,
                              const gfx::Size& texture_size,
                              const gfx::Rect& content_rect,
                              const gfx::Rect& quad_rect) {
    EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                                 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 =
        QueryD3D11DeviceObjectFromANGLE();

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

    // Pass content rect with odd with and height.  Surface should round up
    // width and height when creating swap chain.
    ui::DCRendererLayerParams params;
    params.images[0] = image_dxgi;

    params.content_rect = content_rect;
    params.quad_rect = quad_rect;
    surface_->ScheduleDCLayer(params);

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

    Sleep(1000);
  }

  void PixelTestSwapChain(bool layers_enabled) {
    if (!surface_)
      return;
    if (!layers_enabled)
      surface_->SetEnableDCLayers(false);

    gfx::Size window_size(100, 100);
    EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                                 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_;
  ui::WinWindow window_;
};

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 (!surface_)
      return;

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

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

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

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

    ui::DCRendererLayerParams params;
    params.images[0] = image_dxgi;

    params.content_rect = gfx::Rect(texture_size);
    params.quad_rect = gfx::Rect(texture_size);
    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.
    params.quad_rect = gfx::Rect(window_size);

    surface_->ScheduleDCLayer(params);
    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 (!surface_)
    return;

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

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      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);
  auto y_image = base::MakeRefCounted<GLImageRefCountedMemory>(y_size);
  y_image->Initialize(new base::RefCountedBytes(y_data),
                      gfx::BufferFormat::R_8);
  auto uv_image = base::MakeRefCounted<GLImageRefCountedMemory>(uv_size);
  uv_image->Initialize(new base::RefCountedBytes(uv_data),
                       gfx::BufferFormat::RG_88);
  y_image->SetColorSpace(gfx::ColorSpace::CreateREC709());

  ui::DCRendererLayerParams params;
  params.images[0] = y_image;
  params.images[1] = uv_image;
  params.content_rect = gfx::Rect(y_size);
  params.quad_rect = gfx::Rect(window_size);
  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 (!surface_)
    return;

  gfx::Size window_size(100, 100);
  gfx::Size texture_size(50, 50);
  gfx::Rect content_rect(texture_size);
  gfx::Rect quad_rect(window_size);
  InitializeForPixelTest(window_size, texture_size, content_rect, quad_rect);

  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 (!surface_)
    return;

  gfx::Size window_size(100, 100);
  gfx::Size texture_size(50, 50);
  gfx::Rect content_rect(texture_size);
  gfx::Rect quad_rect;  // Layer with empty bounds rect.
  InitializeForPixelTest(window_size, texture_size, content_rect, quad_rect);

  // 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 (!surface_)
    return;
  // Swap chain size is overridden to content rect size only if scaled overlays
  // are supported.
  DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(true);

  gfx::Size window_size(100, 100);
  EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                               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 =
      QueryD3D11DeviceObjectFromANGLE();

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

  // Layer with empty content rect.
  ui::DCRendererLayerParams params;
  params.images[0] = image_dxgi;
  params.quad_rect = gfx::Rect(window_size);
  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, NV12SwapChain) {
  if (!surface_)
    return;
  // Swap chain size is overridden to content rect size only if scaled overlays
  // are supported.
  DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(true);

  gfx::Size window_size(100, 100);
  gfx::Size texture_size(50, 50);
  // Pass content rect with odd with and height.  Surface should round up
  // width and height when creating swap chain.
  gfx::Rect content_rect(0, 0, 49, 49);
  gfx::Rect quad_rect(window_size);
  InitializeForPixelTest(window_size, texture_size, content_rect, quad_rect);

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_TRUE(swap_chain);

  DXGI_SWAP_CHAIN_DESC1 desc;
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc1(&desc)));
  EXPECT_EQ(desc.Format, DXGI_FORMAT_NV12);
  EXPECT_EQ(desc.Width, 50u);
  EXPECT_EQ(desc.Height, 50u);

  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, YUY2SwapChain) {
  if (!surface_)
    return;
  // CreateSwapChainForCompositionSurfaceHandle fails with YUY2 format on
  // Win10/AMD bot (Radeon RX550). See https://crbug.com/967860.
  if (context_ && context_->GetVersionInfo() &&
      context_->GetVersionInfo()->driver_vendor == "ANGLE (AMD)")
    return;

  // Swap chain size is overridden to content rect size only if scaled overlays
  // are supported.
  DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(true);
  // By default NV12 is used, so set it to YUY2 explicitly.
  DirectCompositionSurfaceWin::SetOverlayFormatUsedForTesting(DXGI_FORMAT_YUY2);

  gfx::Size window_size(100, 100);
  gfx::Size texture_size(50, 50);
  // Pass content rect with odd with and height.  Surface should round up
  // width and height when creating swap chain.
  gfx::Rect content_rect(0, 0, 49, 49);
  gfx::Rect quad_rect(window_size);
  InitializeForPixelTest(window_size, texture_size, content_rect, quad_rect);

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_TRUE(swap_chain);

  DXGI_SWAP_CHAIN_DESC1 desc;
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc1(&desc)));
  EXPECT_EQ(desc.Format, DXGI_FORMAT_YUY2);
  EXPECT_EQ(desc.Width, 50u);
  EXPECT_EQ(desc.Height, 50u);

  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, NonZeroBoundsOffset) {
  if (!surface_)
    return;
  // Swap chain size is overridden to content rect size only if scaled overlays
  // are supported.
  DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(true);

  gfx::Size window_size(100, 100);
  gfx::Size texture_size(50, 50);
  gfx::Rect content_rect(texture_size);
  gfx::Rect quad_rect(gfx::Point(25, 25), texture_size);
  InitializeForPixelTest(window_size, texture_size, content_rect, quad_rect);

  SkColor video_color = SkColorSetRGB(0xe1, 0x90, 0xeb);
  struct {
    gfx::Point point;
    SkColor expected_color;
  } test_cases[] = {
      // Outside bounds
      {{24, 24}, SK_ColorBLACK},
      {{75, 75}, SK_ColorBLACK},
      // Inside bounds
      {{25, 25}, video_color},
      {{74, 74}, video_color},
  };

  auto pixels = ReadBackWindow(window_.hwnd(), window_size);

  for (const auto& test_case : test_cases) {
    const auto& point = test_case.point;
    const auto& expected_color = test_case.expected_color;
    SkColor actual_color = pixels[window_size.width() * point.y() + point.x()];
    EXPECT_TRUE(AreColorsSimilar(expected_color, actual_color))
        << std::hex << "Expected " << expected_color << " Actual "
        << actual_color << " at " << point.ToString();
  }
}

TEST_F(DirectCompositionPixelTest, ResizeVideoLayer) {
  if (!surface_)
    return;
  // Swap chain size is overridden to content rect size only if scaled overlays
  // are supported.
  DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(true);

  gfx::Size window_size(100, 100);
  EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                               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 =
      QueryD3D11DeviceObjectFromANGLE();

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

  {
    ui::DCRendererLayerParams params;
    params.images[0] = image_dxgi;

    params.content_rect = gfx::Rect(texture_size);
    params.quad_rect = gfx::Rect(window_size);
    surface_->ScheduleDCLayer(params);

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

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain =
      surface_->GetLayerSwapChainForTesting(0);
  ASSERT_TRUE(swap_chain);

  DXGI_SWAP_CHAIN_DESC1 desc;
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc1(&desc)));
  EXPECT_EQ(desc.Width, 50u);
  EXPECT_EQ(desc.Height, 50u);

  {
    ui::DCRendererLayerParams params;
    params.images[0] = image_dxgi;

    params.content_rect = gfx::Rect(30, 30);
    params.quad_rect = gfx::Rect(window_size);
    surface_->ScheduleDCLayer(params);

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

  // Swap chain isn't recreated on resize.
  ASSERT_TRUE(surface_->GetLayerSwapChainForTesting(0));
  EXPECT_EQ(swap_chain.Get(), surface_->GetLayerSwapChainForTesting(0).Get());
  EXPECT_TRUE(SUCCEEDED(swap_chain->GetDesc1(&desc)));
  EXPECT_EQ(desc.Width, 30u);
  EXPECT_EQ(desc.Height, 30u);
}

TEST_F(DirectCompositionPixelTest, SwapChainImage) {
  if (!surface_)
    return;

  Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
      QueryD3D11DeviceObjectFromANGLE();
  ASSERT_TRUE(d3d11_device);
  Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device;
  d3d11_device.As(&dxgi_device);
  ASSERT_TRUE(dxgi_device);
  Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter;
  dxgi_device->GetAdapter(&dxgi_adapter);
  ASSERT_TRUE(dxgi_adapter);
  Microsoft::WRL::ComPtr<IDXGIFactory2> dxgi_factory;
  dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
  ASSERT_TRUE(dxgi_factory);

  gfx::Size swap_chain_size(50, 50);
  DXGI_SWAP_CHAIN_DESC1 desc = {};
  desc.Width = swap_chain_size.width();
  desc.Height = swap_chain_size.height();
  desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
  desc.Stereo = FALSE;
  desc.SampleDesc.Count = 1;
  desc.BufferCount = 2;
  desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;
  desc.Scaling = DXGI_SCALING_STRETCH;
  desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
  desc.Flags = 0;

  Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain;

  ASSERT_TRUE(SUCCEEDED(dxgi_factory->CreateSwapChainForComposition(
      d3d11_device.Get(), &desc, nullptr, &swap_chain)));
  ASSERT_TRUE(swap_chain);

  Microsoft::WRL::ComPtr<ID3D11Texture2D> front_buffer_texture;
  ASSERT_TRUE(SUCCEEDED(
      swap_chain->GetBuffer(1u, IID_PPV_ARGS(&front_buffer_texture))));
  ASSERT_TRUE(front_buffer_texture);

  auto front_buffer_image = base::MakeRefCounted<GLImageD3D>(
      swap_chain_size, gfx::BufferFormat::BGRA_8888, front_buffer_texture,
      swap_chain);
  ASSERT_TRUE(front_buffer_image->Initialize());

  Microsoft::WRL::ComPtr<ID3D11Texture2D> back_buffer_texture;
  ASSERT_TRUE(
      SUCCEEDED(swap_chain->GetBuffer(0u, IID_PPV_ARGS(&back_buffer_texture))));
  ASSERT_TRUE(back_buffer_texture);

  Microsoft::WRL::ComPtr<ID3D11RenderTargetView> rtv;
  ASSERT_TRUE(SUCCEEDED(d3d11_device->CreateRenderTargetView(
      back_buffer_texture.Get(), nullptr, &rtv)));
  ASSERT_TRUE(rtv);

  Microsoft::WRL::ComPtr<ID3D11DeviceContext> context;
  d3d11_device->GetImmediateContext(&context);
  ASSERT_TRUE(context);

  gfx::Size window_size(100, 100);
  EXPECT_TRUE(surface_->Resize(window_size, 1.0,
                               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);

  ui::DCRendererLayerParams dc_layer_params;
  dc_layer_params.images[0] = front_buffer_image;
  dc_layer_params.content_rect = gfx::Rect(swap_chain_size);
  dc_layer_params.quad_rect = gfx::Rect(window_size);

  DXGI_PRESENT_PARAMETERS present_params = {};
  present_params.DirtyRectsCount = 0;
  present_params.pDirtyRects = nullptr;

  // Clear to red and present.
  {
    float clear_color[] = {1.0, 0.0, 0.0, 1.0};
    context->ClearRenderTargetView(rtv.Get(), clear_color);

    ASSERT_TRUE(SUCCEEDED(swap_chain->Present1(0, 0, &present_params)));

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

    SkColor expected_color = SK_ColorRED;
    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;
  }

  // Clear to green and present.
  {
    float clear_color[] = {0.0, 1.0, 0.0, 1.0};
    context->ClearRenderTargetView(rtv.Get(), clear_color);

    ASSERT_TRUE(SUCCEEDED(swap_chain->Present1(0, 0, &present_params)));

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

    SkColor expected_color = SK_ColorGREEN;
    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;
  }

  // Present without clearing.  This will flip front and back buffers so the
  // previous rendered contents (red) will become visible again.
  {
    ASSERT_TRUE(SUCCEEDED(swap_chain->Present1(0, 0, &present_params)));

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

    SkColor expected_color = SK_ColorRED;
    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;
  }

  // Clear to blue without present.
  {
    float clear_color[] = {0.0, 0.0, 1.0, 1.0};
    context->ClearRenderTargetView(rtv.Get(), clear_color);

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

    SkColor expected_color = SK_ColorRED;
    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 gl
