//
// Copyright (c) 2014 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.
//

// SwapChainPanelNativeWindow.cpp: NativeWindow for managing ISwapChainPanel native window types.

#include "libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h"

#include <algorithm>
#include <math.h>

using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::UI::Core;
using namespace ABI::Windows::UI::Xaml;
using namespace Microsoft::WRL;

namespace rx
{
SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
{
    unregisterForSizeChangeEvents();
}

template <typename T>
struct AddFtmBase
{
    typedef Implements<RuntimeClassFlags<ClassicCom>, T, FtmBase> Type;
};

template <typename CODE>
HRESULT RunOnUIThread(CODE &&code, const ComPtr<ICoreDispatcher> &dispatcher)
{
    ComPtr<IAsyncAction> asyncAction;
    HRESULT result = S_OK;

    boolean hasThreadAccess;
    result = dispatcher->get_HasThreadAccess(&hasThreadAccess);
    if (FAILED(result))
    {
        return result;
    }

    if (hasThreadAccess)
    {
        return code();
    }
    else
    {
        Event waitEvent(
            CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
        if (!waitEvent.IsValid())
        {
            return E_FAIL;
        }

        HRESULT codeResult = E_FAIL;
        auto handler =
            Callback<AddFtmBase<IDispatchedHandler>::Type>([&codeResult, &code, &waitEvent]
                                                           {
                                                               codeResult = code();
                                                               SetEvent(waitEvent.Get());
                                                               return S_OK;
                                                           });

        result = dispatcher->RunAsync(CoreDispatcherPriority_Normal, handler.Get(),
                                      asyncAction.GetAddressOf());
        if (FAILED(result))
        {
            return result;
        }

        auto waitResult = WaitForSingleObjectEx(waitEvent.Get(), 10 * 1000, true);
        if (waitResult != WAIT_OBJECT_0)
        {
            // Wait 10 seconds before giving up. At this point, the application is in an
            // unrecoverable state (probably deadlocked). We therefore terminate the application
            // entirely. This also prevents stack corruption if the async operation is eventually
            // run.
            ERR()
                << "Timeout waiting for async action on UI thread. The UI thread might be blocked.";
            std::terminate();
            return E_FAIL;
        }

        return codeResult;
    }
}

bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
{
    ComPtr<IPropertySet> props = propertySet;
    ComPtr<IInspectable> win = window;
    SIZE swapChainSize = {};
    HRESULT result = S_OK;

    // IPropertySet is an optional parameter and can be null.
    // If one is specified, cache as an IMap and read the properties
    // used for initial host initialization.
    if (propertySet)
    {
        result = props.As(&mPropertyMap);
        if (FAILED(result))
        {
            return false;
        }

        // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
        // was prevalidated to contain the EGLNativeWindowType before being passed to
        // this host.
        result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &mSwapChainSizeSpecified);
        if (FAILED(result))
        {
            return false;
        }

        // The EGLRenderResolutionScaleProperty is optional and may be missing. The IPropertySet
        // was prevalidated to contain the EGLNativeWindowType before being passed to
        // this host.
        result = GetOptionalSinglePropertyValue(mPropertyMap, EGLRenderResolutionScaleProperty, &mSwapChainScale, &mSwapChainScaleSpecified);
        if (FAILED(result))
        {
            return false;
        }

        if (!mSwapChainScaleSpecified)
        {
            // Default value for the scale is 1.0f
            mSwapChainScale = 1.0f;
        }

        // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified
        if (mSwapChainScaleSpecified && mSwapChainSizeSpecified)
        {
            ERR() << "It is invalid to specify both an EGLRenderSurfaceSizeProperty and a "
                     "EGLRenderResolutionScaleProperty.";
            return false;
        }
    }

    if (SUCCEEDED(result))
    {
        result = win.As(&mSwapChainPanel);
    }

    ComPtr<IDependencyObject> swapChainPanelDependencyObject;
    if (SUCCEEDED(result))
    {
        result = mSwapChainPanel.As(&swapChainPanelDependencyObject);
    }

    if (SUCCEEDED(result))
    {
        result = swapChainPanelDependencyObject->get_Dispatcher(
            mSwapChainPanelDispatcher.GetAddressOf());
    }

    if (SUCCEEDED(result))
    {
        // If a swapchain size is specfied, then the automatic resize
        // behaviors implemented by the host should be disabled.  The swapchain
        // will be still be scaled when being rendered to fit the bounds
        // of the host.
        // Scaling of the swapchain output needs to be handled by the
        // host for swapchain panels even though the scaling mode setting
        // DXGI_SCALING_STRETCH is configured on the swapchain.
        if (mSwapChainSizeSpecified)
        {
            mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
        }
        else
        {
            Size swapChainPanelSize;
            result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher,
                                           &swapChainPanelSize);

            if (SUCCEEDED(result))
            {
                // Update the client rect to account for any swapchain scale factor
                mClientRect = clientRect(swapChainPanelSize);
            }
        }
    }

    if (SUCCEEDED(result))
    {
        mNewClientRect = mClientRect;
        mClientRectChanged = false;
        return registerForSizeChangeEvents();
    }

    return false;
}

bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
{
    ComPtr<ISizeChangedEventHandler> sizeChangedHandler;
    ComPtr<IFrameworkElement> frameworkElement;
    HRESULT result = Microsoft::WRL::MakeAndInitialize<SwapChainPanelSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());

    if (SUCCEEDED(result))
    {
        result = mSwapChainPanel.As(&frameworkElement);
    }

    if (SUCCEEDED(result))
    {
        result = RunOnUIThread(
            [this, frameworkElement, sizeChangedHandler]
            {
                return frameworkElement->add_SizeChanged(sizeChangedHandler.Get(),
                                                         &mSizeChangedEventToken);
            },
            mSwapChainPanelDispatcher);
    }

    if (SUCCEEDED(result))
    {
        return true;
    }

    return false;
}

void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents()
{
    ComPtr<IFrameworkElement> frameworkElement;
    if (mSwapChainPanel && SUCCEEDED(mSwapChainPanel.As(&frameworkElement)))
    {
        RunOnUIThread(
            [this, frameworkElement]
            {
                return frameworkElement->remove_SizeChanged(mSizeChangedEventToken);
            },
            mSwapChainPanelDispatcher);
    }

    mSizeChangedEventToken.value = 0;
}

HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device,
                                                    IDXGIFactory2 *factory,
                                                    DXGI_FORMAT format,
                                                    unsigned int width,
                                                    unsigned int height,
                                                    bool containsAlpha,
                                                    IDXGISwapChain1 **swapChain)
{
    if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 ||
        height == 0)
    {
        return E_INVALIDARG;
    }

    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
    swapChainDesc.Width = width;
    swapChainDesc.Height = height;
    swapChainDesc.Format = format;
    swapChainDesc.Stereo = FALSE;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.BufferUsage =
        DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
    swapChainDesc.BufferCount = 2;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
    swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
    swapChainDesc.AlphaMode =
        containsAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;

    *swapChain = nullptr;

    ComPtr<IDXGISwapChain1> newSwapChain;
    ComPtr<ISwapChainPanelNative> swapChainPanelNative;
    Size currentPanelSize = {};

    HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());

    if (SUCCEEDED(result))
    {
        result = mSwapChainPanel.As(&swapChainPanelNative);
    }

    if (SUCCEEDED(result))
    {
        result = RunOnUIThread(
            [swapChainPanelNative, newSwapChain]
            {
                return swapChainPanelNative->SetSwapChain(newSwapChain.Get());
            },
            mSwapChainPanelDispatcher);
    }

    if (SUCCEEDED(result))
    {
        // The swapchain panel host requires an instance of the swapchain set on the SwapChainPanel
        // to perform the runtime-scale behavior.  This swapchain is cached here because there are
        // no methods for retreiving the currently configured on from ISwapChainPanelNative.
        mSwapChain = newSwapChain;
        result = newSwapChain.CopyTo(swapChain);
    }

    // If the host is responsible for scaling the output of the swapchain, then
    // scale it now before returning an instance to the caller.  This is done by
    // first reading the current size of the swapchain panel, then scaling
    if (SUCCEEDED(result))
    {
        if (mSwapChainSizeSpecified || mSwapChainScaleSpecified)
        {
            result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher,
                                           &currentPanelSize);

            // Scale the swapchain to fit inside the contents of the panel.
            if (SUCCEEDED(result))
            {
                result = scaleSwapChain(currentPanelSize, mClientRect);
            }
        }
    }

    return result;
}

HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &windowSize, const RECT &clientRect)
{
    Size renderScale = {windowSize.Width / (float)clientRect.right,
                        windowSize.Height / (float)clientRect.bottom};
    // Setup a scale matrix for the swap chain
    DXGI_MATRIX_3X2_F scaleMatrix = {};
    scaleMatrix._11 = renderScale.Width;
    scaleMatrix._22 = renderScale.Height;

    ComPtr<IDXGISwapChain2> swapChain2;
    HRESULT result = mSwapChain.As(&swapChain2);
    if (SUCCEEDED(result))
    {
        result = swapChain2->SetMatrixTransform(&scaleMatrix);
    }

    return result;
}

HRESULT GetSwapChainPanelSize(
    const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel,
    const ComPtr<ICoreDispatcher> &dispatcher,
    Size *windowSize)
{
    ComPtr<IUIElement> uiElement;
    HRESULT result = swapChainPanel.As(&uiElement);
    if (SUCCEEDED(result))
    {
        result = RunOnUIThread(
            [uiElement, windowSize] { return uiElement->get_RenderSize(windowSize); }, dispatcher);
    }

    return result;
}
}
