/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkSurface.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/d3d/GrD3DBackendContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "tools/gpu/d3d/D3DTestUtils.h"
#include "tools/window/DisplayParams.h"
#include "tools/window/WindowContext.h"
#include "tools/window/win/WindowContextFactory_win.h"

#include <d3d12.h>
#include <dxgi1_4.h>
#include <wrl/client.h>

#define GR_D3D_CALL_ERRCHECK(X)                                         \
    do {                                                                \
        HRESULT result = X;                                             \
        SkASSERT(SUCCEEDED(result));                                    \
        if (!SUCCEEDED(result)) {                                       \
            SkDebugf("Failed Direct3D call. Error: 0x%08lx\n", result); \
        }                                                               \
    } while (false)

using namespace Microsoft::WRL;

using skwindow::DisplayParams;
using skwindow::WindowContext;

namespace {

class D3D12WindowContext : public WindowContext {
public:
    D3D12WindowContext(HWND hwnd, const DisplayParams& params);
    ~D3D12WindowContext() override;
    void initializeContext();
    void destroyContext();
    void setupSurfaces(int width, int height);

    bool isValid() override {
        return fDevice.get() != nullptr;
    }

    sk_sp<SkSurface> getBackbufferSurface() override;

    void resize(int width, int height) override;
    void setDisplayParams(const DisplayParams& params) override;
private:
    inline static constexpr int kNumFrames = 2;

    void onSwapBuffers() override;

    HWND fWindow;
    gr_cp<ID3D12Device> fDevice;
    gr_cp<ID3D12CommandQueue> fQueue;
    gr_cp<IDXGISwapChain3> fSwapChain;
    gr_cp<ID3D12Resource> fBuffers[kNumFrames];
    sk_sp<SkSurface> fSurfaces[kNumFrames];

    // Synchronization objects.
    unsigned int fBufferIndex;
    HANDLE fFenceEvent;
    gr_cp<ID3D12Fence> fFence;
    uint64_t fFenceValues[kNumFrames];
};

D3D12WindowContext::D3D12WindowContext(HWND hwnd, const DisplayParams& params)
    : WindowContext(params)
    , fWindow(hwnd) {

    this->initializeContext();
}

D3D12WindowContext::~D3D12WindowContext() {
    this->destroyContext();
}

void D3D12WindowContext::initializeContext() {
    GrD3DBackendContext backendContext;
    sk_gpu_test::CreateD3DBackendContext(&backendContext);
    fDevice = backendContext.fDevice;
    fQueue = backendContext.fQueue;

    fContext = GrDirectContext::MakeDirect3D(backendContext, fDisplayParams.fGrContextOptions);
    SkASSERT(fContext);

    // Make the swapchain
    RECT windowRect;
    GetWindowRect(fWindow, &windowRect);
    unsigned int width = windowRect.right - windowRect.left;
    unsigned int height = windowRect.bottom - windowRect.top;

    UINT dxgiFactoryFlags = 0;
    SkDEBUGCODE(dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;)

    gr_cp<IDXGIFactory4> factory;
    GR_D3D_CALL_ERRCHECK(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory)));

    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
    swapChainDesc.BufferCount = kNumFrames;
    swapChainDesc.Width = width;
    swapChainDesc.Height = height;
    swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    swapChainDesc.SampleDesc.Count = 1;

    gr_cp<IDXGISwapChain1> swapChain;
    GR_D3D_CALL_ERRCHECK(factory->CreateSwapChainForHwnd(
            fQueue.get(), fWindow, &swapChainDesc, nullptr, nullptr, &swapChain));

    // We don't support fullscreen transitions.
    GR_D3D_CALL_ERRCHECK(factory->MakeWindowAssociation(fWindow, DXGI_MWA_NO_ALT_ENTER));

    GR_D3D_CALL_ERRCHECK(swapChain->QueryInterface(IID_PPV_ARGS(&fSwapChain)));

    fBufferIndex = fSwapChain->GetCurrentBackBufferIndex();

    fSampleCount = fDisplayParams.fMSAASampleCount;

    this->setupSurfaces(width, height);

    for (int i = 0; i < kNumFrames; ++i) {
        fFenceValues[i] = 10000;   // use a high value to make it easier to track these in PIX
    }
    GR_D3D_CALL_ERRCHECK(fDevice->CreateFence(fFenceValues[fBufferIndex], D3D12_FENCE_FLAG_NONE,
                                              IID_PPV_ARGS(&fFence)));

    fFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
    SkASSERT(fFenceEvent);

    fWidth = width;
    fHeight = height;
}

void D3D12WindowContext::setupSurfaces(int width, int height) {
    // set up base resource info
    GrD3DTextureResourceInfo info(nullptr,
                                  nullptr,
                                  D3D12_RESOURCE_STATE_PRESENT,
                                  DXGI_FORMAT_R8G8B8A8_UNORM,
                                  1,
                                  1,
                                  0);
    for (int i = 0; i < kNumFrames; ++i) {
        GR_D3D_CALL_ERRCHECK(fSwapChain->GetBuffer(i, IID_PPV_ARGS(&fBuffers[i])));

        SkASSERT(fBuffers[i]->GetDesc().Width == (UINT64)width &&
                 fBuffers[i]->GetDesc().Height == (UINT64)height);

        info.fResource = fBuffers[i];
        if (fSampleCount > 1) {
            GrBackendTexture backendTexture(width, height, info);
            fSurfaces[i] = SkSurfaces::WrapBackendTexture(fContext.get(),
                                                          backendTexture,
                                                          kTopLeft_GrSurfaceOrigin,
                                                          fSampleCount,
                                                          kRGBA_8888_SkColorType,
                                                          fDisplayParams.fColorSpace,
                                                          &fDisplayParams.fSurfaceProps);
        } else {
            GrBackendRenderTarget backendRT(width, height, info);
            fSurfaces[i] = SkSurfaces::WrapBackendRenderTarget(fContext.get(),
                                                               backendRT,
                                                               kTopLeft_GrSurfaceOrigin,
                                                               kRGBA_8888_SkColorType,
                                                               fDisplayParams.fColorSpace,
                                                               &fDisplayParams.fSurfaceProps);
        }
    }
}

void D3D12WindowContext::destroyContext() {
    CloseHandle(fFenceEvent);
    fFence.reset(nullptr);

    for (int i = 0; i < kNumFrames; ++i) {
        fSurfaces[i].reset(nullptr);
        fBuffers[i].reset(nullptr);
    }

    fSwapChain.reset(nullptr);
    fQueue.reset(nullptr);
    fDevice.reset(nullptr);
}

sk_sp<SkSurface> D3D12WindowContext::getBackbufferSurface() {
    // Update the frame index.
    const UINT64 currentFenceValue = fFenceValues[fBufferIndex];
    fBufferIndex = fSwapChain->GetCurrentBackBufferIndex();

    // If the last frame for this buffer index is not done, wait until it is ready.
    if (fFence->GetCompletedValue() < fFenceValues[fBufferIndex]) {
        GR_D3D_CALL_ERRCHECK(fFence->SetEventOnCompletion(fFenceValues[fBufferIndex], fFenceEvent));
        WaitForSingleObjectEx(fFenceEvent, INFINITE, FALSE);
    }

    // Set the fence value for the next frame.
    fFenceValues[fBufferIndex] = currentFenceValue + 1;

    return fSurfaces[fBufferIndex];
}

void D3D12WindowContext::onSwapBuffers() {
    SkSurface* surface = fSurfaces[fBufferIndex].get();

    GrFlushInfo info;
    fContext->flush(surface, SkSurfaces::BackendSurfaceAccess::kPresent, info);
    fContext->submit();

    GR_D3D_CALL_ERRCHECK(fSwapChain->Present(1, 0));

    // Schedule a Signal command in the queue.
    GR_D3D_CALL_ERRCHECK(fQueue->Signal(fFence.get(), fFenceValues[fBufferIndex]));
}

void D3D12WindowContext::resize(int width, int height) {
    // Clean up any outstanding resources in command lists
    fContext->flush();
    fContext->submit(GrSyncCpu::kYes);

    // release the previous surface and backbuffer resources
    for (int i = 0; i < kNumFrames; ++i) {
        // Let present complete
        if (fFence->GetCompletedValue() < fFenceValues[i]) {
            GR_D3D_CALL_ERRCHECK(fFence->SetEventOnCompletion(fFenceValues[i], fFenceEvent));
            WaitForSingleObjectEx(fFenceEvent, INFINITE, FALSE);
        }
        fSurfaces[i].reset(nullptr);
        fBuffers[i].reset(nullptr);
    }

    GR_D3D_CALL_ERRCHECK(fSwapChain->ResizeBuffers(0, width, height,
                                                   DXGI_FORMAT_R8G8B8A8_UNORM, 0));

    this->setupSurfaces(width, height);

    fWidth = width;
    fHeight = height;
}

void D3D12WindowContext::setDisplayParams(const DisplayParams& params) {
    this->destroyContext();
    fDisplayParams = params;
    this->initializeContext();
}

} // anonymous namespace

namespace skwindow {

std::unique_ptr<WindowContext> MakeD3D12ForWin(HWND hwnd, const DisplayParams& params) {
    std::unique_ptr<WindowContext> ctx(new D3D12WindowContext(hwnd, params));
    if (!ctx->isValid()) {
        return nullptr;
    }
    return ctx;
}

} // namespace skwindow
