//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// CompositorNativeWindow11.cpp: Implementation of NativeWindow11 using Windows.UI.Composition APIs
// which work in both Win32 and WinRT contexts.

#include "libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"

#include "common/debug.h"

using namespace Microsoft::WRL;

namespace rx
{

CompositorNativeWindow11::CompositorNativeWindow11(EGLNativeWindowType window, bool hasAlpha)
    : NativeWindow11(window), mHasAlpha(hasAlpha)
{
    ABI::Windows::UI::Composition::ISpriteVisual *inspPtr =
        reinterpret_cast<ABI::Windows::UI::Composition::ISpriteVisual *>(window);
    mHostVisual = Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ISpriteVisual>{inspPtr};
}

CompositorNativeWindow11::~CompositorNativeWindow11() = default;

bool CompositorNativeWindow11::initialize()
{
    return true;
}

bool CompositorNativeWindow11::getClientRect(LPRECT rect) const
{
    ComPtr<ABI::Windows::UI::Composition::IVisual> visual;
    mHostVisual.As(&visual);

    ABI::Windows::Foundation::Numerics::Vector2 size;
    HRESULT hr = visual->get_Size(&size);
    if (FAILED(hr))
    {
        return false;
    }

    ABI::Windows::Foundation::Numerics::Vector3 offset;
    hr = visual->get_Offset(&offset);
    if (FAILED(hr))
    {
        return false;
    }

    rect->top    = static_cast<LONG>(offset.Y);
    rect->left   = static_cast<LONG>(offset.X);
    rect->right  = static_cast<LONG>(offset.X) + static_cast<LONG>(size.X);
    rect->bottom = static_cast<LONG>(offset.Y) + static_cast<LONG>(size.Y);

    return true;
}

bool CompositorNativeWindow11::isIconic() const
{
    return false;
}

HRESULT CompositorNativeWindow11::createSwapChain(ID3D11Device *device,
                                                  IDXGIFactory *factory,
                                                  DXGI_FORMAT format,
                                                  UINT width,
                                                  UINT height,
                                                  UINT samples,
                                                  IDXGISwapChain **swapChain)
{
    if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 ||
        height == 0)
    {
        return E_INVALIDARG;
    }

    HRESULT hr{E_FAIL};

    ComPtr<ABI::Windows::UI::Composition::ICompositionObject> hostVisual;
    hr = mHostVisual.As(&hostVisual);
    if (FAILED(hr))
    {
        return hr;
    }

    Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ICompositor> compositor;
    hr = hostVisual->get_Compositor(&compositor);
    if (FAILED(hr))
    {
        return hr;
    }

    ComPtr<ABI::Windows::UI::Composition::ICompositorInterop> interop;

    hr = compositor.As(&interop);
    if (FAILED(hr))
    {
        return hr;
    }

    ComPtr<IDXGIFactory2> factory2;
    factory2.Attach(d3d11::DynamicCastComObject<IDXGIFactory2>(factory));

    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
    swapChainDesc.Width                 = width;
    swapChainDesc.Height                = height;
    swapChainDesc.Format                = format;
    swapChainDesc.Stereo                = FALSE;
    swapChainDesc.SampleDesc.Count      = 1;
    swapChainDesc.SampleDesc.Quality    = 0;
    swapChainDesc.BufferUsage =
        DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT;
    swapChainDesc.BufferCount = 2;
    swapChainDesc.Scaling     = DXGI_SCALING_STRETCH;
    swapChainDesc.SwapEffect  = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
    swapChainDesc.AlphaMode   = mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;
    swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG::DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
    Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain1;
    hr = factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1);
    if (SUCCEEDED(hr))
    {
        swapChain1.CopyTo(swapChain);
    }

    hr = interop->CreateCompositionSurfaceForSwapChain(swapChain1.Get(), &mSurface);
    if (FAILED(hr))
    {
        return hr;
    }

    hr = compositor->CreateSurfaceBrushWithSurface(mSurface.Get(), &mSurfaceBrush);
    if (FAILED(hr))
    {
        return hr;
    }

    hr = mSurfaceBrush.As(&mCompositionBrush);
    if (FAILED(hr))
    {
        return hr;
    }

    hr = mHostVisual->put_Brush(mCompositionBrush.Get());
    if (FAILED(hr))
    {
        return hr;
    }

    return hr;
}

void CompositorNativeWindow11::commitChange()
{
    // Windows::UI::Composition uses an implicit commit model hence no action needed here
}

// static
bool CompositorNativeWindow11::IsValidNativeWindow(EGLNativeWindowType window)
{
    return IsSupportedWinRelease() && IsSpriteVisual(window);
}

// static
bool CompositorNativeWindow11::IsSupportedWinRelease()
{
    RoHelper helper;
    if (!helper.WinRtAvailable())
    {
        return false;
    }

    return helper.SupportedWindowsRelease();
}

bool CompositorNativeWindow11::IsSpriteVisual(EGLNativeWindowType window)
{
    RoHelper helper;

    ABI::Windows::UI::Composition::ISpriteVisual *inspp =
        reinterpret_cast<ABI::Windows::UI::Composition::ISpriteVisual *>(window);
    HSTRING className, spriteClassName;
    HSTRING_HEADER spriteClassNameHeader;

    auto hr = helper.GetStringReference(RuntimeClass_Windows_UI_Composition_SpriteVisual,
                                        &spriteClassName, &spriteClassNameHeader);
    if (FAILED(hr))
    {
        return false;
    }

    hr = inspp->GetRuntimeClassName(&className);
    if (FAILED(hr))
    {
        return false;
    }

    INT32 result = -1;
    hr           = helper.WindowsCompareStringOrdinal(className, spriteClassName, &result);

    helper.WindowsDeleteString(className);

    if (FAILED(hr))
    {
        return false;
    }

    if (result == 0)
    {
        return true;
    }

    return false;
}

// RoHelperImpl

template <typename T>
bool AssignProcAddress(HMODULE comBaseModule, const char *name, T *&outProc)
{
    outProc = reinterpret_cast<T *>(GetProcAddress(comBaseModule, name));
    return *outProc != nullptr;
}

RoHelper::RoHelper()
    : mFpWindowsCreateStringReference(nullptr),
      mFpGetActivationFactory(nullptr),
      mFpWindowsCompareStringOrdinal(nullptr),
      mFpCreateDispatcherQueueController(nullptr),
      mFpWindowsDeleteString(nullptr),
      mFpRoInitialize(nullptr),
      mFpRoUninitialize(nullptr),
      mWinRtAvailable(false),
      mComBaseModule(nullptr),
      mCoreMessagingModule(nullptr)
{
    if (!IsWindows10OrGreater())
    {
        return;
    }

    mComBaseModule = LoadLibraryA("ComBase.dll");

    if (mComBaseModule == nullptr)
    {
        return;
    }

    if (!AssignProcAddress(mComBaseModule, "WindowsCreateStringReference",
                           mFpWindowsCreateStringReference))
    {
        return;
    }

    if (!AssignProcAddress(mComBaseModule, "RoGetActivationFactory", mFpGetActivationFactory))
    {
        return;
    }

    if (!AssignProcAddress(mComBaseModule, "WindowsCompareStringOrdinal",
                           mFpWindowsCompareStringOrdinal))
    {
        return;
    }

    if (!AssignProcAddress(mComBaseModule, "WindowsDeleteString", mFpWindowsDeleteString))
    {
        return;
    }

    if (!AssignProcAddress(mComBaseModule, "RoInitialize", mFpRoInitialize))
    {
        return;
    }

    if (!AssignProcAddress(mComBaseModule, "RoUninitialize", mFpRoUninitialize))
    {
        return;
    }

    mCoreMessagingModule = LoadLibraryA("coremessaging.dll");

    if (mCoreMessagingModule == nullptr)
    {
        return;
    }

    if (!AssignProcAddress(mCoreMessagingModule, "CreateDispatcherQueueController",
                           mFpCreateDispatcherQueueController))
    {
        return;
    }

    if (SUCCEEDED(RoInitialize(RO_INIT_MULTITHREADED)))
    {
        mWinRtAvailable = true;
    }
}

RoHelper::~RoHelper()
{
    if (mWinRtAvailable)
    {
        RoUninitialize();
    }

    if (mCoreMessagingModule != nullptr)
    {
        FreeLibrary(mCoreMessagingModule);
        mCoreMessagingModule = nullptr;
    }

    if (mComBaseModule != nullptr)
    {
        FreeLibrary(mComBaseModule);
        mComBaseModule = nullptr;
    }
}

bool RoHelper::WinRtAvailable() const
{
    return mWinRtAvailable;
}

bool RoHelper::SupportedWindowsRelease()
{
    if (!IsWindows10OrGreater() || !mWinRtAvailable)
    {
        return false;
    }

    HSTRING className, contractName;
    HSTRING_HEADER classNameHeader, contractNameHeader;
    boolean isSupported = false;

    HRESULT hr = GetStringReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation,
                                    &className, &classNameHeader);

    if (FAILED(hr))
    {
        return !!isSupported;
    }

    Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Metadata::IApiInformationStatics> api;

    hr = GetActivationFactory(
        className, __uuidof(ABI::Windows::Foundation::Metadata::IApiInformationStatics), &api);

    if (FAILED(hr))
    {
        return !!isSupported;
    }

    hr = GetStringReference(L"Windows.Foundation.UniversalApiContract", &contractName,
                            &contractNameHeader);
    if (FAILED(hr))
    {
        return !!isSupported;
    }

    api->IsApiContractPresentByMajor(contractName, 6, &isSupported);

    return !!isSupported;
}

HRESULT RoHelper::GetStringReference(PCWSTR source, HSTRING *act, HSTRING_HEADER *header)
{
    if (!mWinRtAvailable)
    {
        return E_FAIL;
    }

    const wchar_t *str = static_cast<const wchar_t *>(source);

    unsigned int length;
    HRESULT hr = SizeTToUInt32(::wcslen(str), &length);
    if (FAILED(hr))
    {
        return hr;
    }

    return mFpWindowsCreateStringReference(source, length, header, act);
}

HRESULT RoHelper::GetActivationFactory(const HSTRING act, const IID &interfaceId, void **fac)
{
    if (!mWinRtAvailable)
    {
        return E_FAIL;
    }
    auto hr = mFpGetActivationFactory(act, interfaceId, fac);
    return hr;
}

HRESULT RoHelper::WindowsCompareStringOrdinal(HSTRING one, HSTRING two, int *result)
{
    if (!mWinRtAvailable)
    {
        return E_FAIL;
    }
    return mFpWindowsCompareStringOrdinal(one, two, result);
}

HRESULT RoHelper::CreateDispatcherQueueController(
    DispatcherQueueOptions options,
    ABI::Windows::System::IDispatcherQueueController **dispatcherQueueController)
{
    if (!mWinRtAvailable)
    {
        return E_FAIL;
    }
    return mFpCreateDispatcherQueueController(options, dispatcherQueueController);
}

HRESULT RoHelper::WindowsDeleteString(HSTRING one)
{
    if (!mWinRtAvailable)
    {
        return E_FAIL;
    }
    return mFpWindowsDeleteString(one);
}

HRESULT RoHelper::RoInitialize(RO_INIT_TYPE type)
{
    return mFpRoInitialize(type);
}

void RoHelper::RoUninitialize()
{
    mFpRoUninitialize();
}

}  // namespace rx
