//
// 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.
//

// EGLDirectCompositionTest.cpp:
//   Tests pertaining to DirectComposition and WindowsUIComposition.

#include "common/unsafe_buffers.h"
#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW

#    include <d3d11.h>
#    include "test_utils/ANGLETest.h"

#    include <DispatcherQueue.h>
#    include <VersionHelpers.h>
#    include <Windows.Foundation.h>
#    include <windows.ui.composition.desktop.h>
#    include <windows.ui.composition.h>
#    include <windows.ui.composition.interop.h>
#    include <wrl.h>
#    include <memory>

#    include "libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h"
#    include "util/OSWindow.h"
#    include "util/test_utils.h"

using namespace angle;
using namespace ABI::Windows::System;
using namespace ABI::Windows::UI::Composition;
using namespace ABI::Windows::UI::Composition::Desktop;
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

const int WINDOWWIDTH = 200, WINDOWHEIGHT = 200;

class EGLDirectCompositionTest : public ANGLETest<>
{
  protected:
    EGLDirectCompositionTest() : mOSWindow(nullptr) {}

    void testSetUp() override
    {
        if (!mRoHelper.SupportedWindowsRelease())
        {
            return;
        }

        // Create an OS Window
        mOSWindow = OSWindow::New();

        mOSWindow->initialize("EGLDirectCompositionTest", WINDOWWIDTH, WINDOWHEIGHT);
        auto nativeWindow = mOSWindow->getNativeWindow();
        setWindowVisible(mOSWindow, true);

        // Create DispatcherQueue for window to process compositor callbacks
        CreateDispatcherQueue(mDispatcherController);

        HSTRING act;
        HSTRING_HEADER header;

        auto hr = mRoHelper.GetStringReference(RuntimeClass_Windows_UI_Composition_Compositor, &act,
                                               &header);

        ASSERT_TRUE(SUCCEEDED(hr));

        ComPtr<IActivationFactory> compositorFactory;
        hr = mRoHelper.GetActivationFactory(act, IID_PPV_ARGS(&compositorFactory));
        ASSERT_TRUE(SUCCEEDED(hr));

        hr = compositorFactory->ActivateInstance(&mCompositor);
        ASSERT_TRUE(SUCCEEDED(hr));

        // Create a DesktopWindowTarget against native window (HWND)
        CreateDesktopWindowTarget(mCompositor, static_cast<HWND>(nativeWindow), mDesktopTarget);

        ASSERT_TRUE(SUCCEEDED(mCompositor->CreateSpriteVisual(&mAngleHost)));

        ComPtr<IVisual> angleVis;
        ASSERT_TRUE(SUCCEEDED(mAngleHost.As(&angleVis)));

        ASSERT_TRUE(SUCCEEDED(angleVis->put_Size(
            {static_cast<FLOAT>(WINDOWWIDTH), static_cast<FLOAT>(WINDOWHEIGHT)})));

        ASSERT_TRUE(SUCCEEDED(angleVis->put_Offset({0, 0, 0})));

        ComPtr<ICompositionTarget> compTarget;
        ASSERT_TRUE(SUCCEEDED(mDesktopTarget.As(&compTarget)));
        ASSERT_TRUE(SUCCEEDED(compTarget->put_Root(angleVis.Get())));

        Init();
    }

    void CreateDispatcherQueue(ComPtr<IDispatcherQueueController> &controller)
    {
        DispatcherQueueOptions options{sizeof(DispatcherQueueOptions), DQTYPE_THREAD_CURRENT,
                                       DQTAT_COM_STA};

        auto hr = mRoHelper.CreateDispatcherQueueController(options, &controller);

        ASSERT_TRUE(SUCCEEDED(hr));
    }

    void CreateDesktopWindowTarget(ComPtr<ICompositor> const &compositor,
                                   const HWND window,
                                   ComPtr<IDesktopWindowTarget> &target)
    {
        namespace abi = ABI::Windows::UI::Composition::Desktop;

        ComPtr<ICompositorDesktopInterop> interop;
        ASSERT_TRUE(SUCCEEDED(compositor.As(&interop)));

        ASSERT_TRUE(SUCCEEDED(interop->CreateDesktopWindowTarget(window, true, &target)));
    }

    void Init()
    {
        if (!mRoHelper.SupportedWindowsRelease())
        {
            return;
        }

        DPI_AWARENESS_CONTEXT
        WINAPI
        SetThreadDpiAwarenessContext(_In_ DPI_AWARENESS_CONTEXT dpiContext);

        auto userModule = LoadLibraryA("user32.dll");

        if (userModule == nullptr)
        {
            return;
        }

        auto temp = GetProcAddress(userModule, "SetThreadDpiAwarenessContext");

        mFpSetThreadDpiAwarenessContext = reinterpret_cast<_SetThreadDpiAwarenessContext *>(temp);

        const EGLint configAttributes[] = {
            EGL_RED_SIZE,   8, EGL_GREEN_SIZE,   8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
            EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, EGL_NONE};

        const EGLAttrib defaultDisplayAttributes[] = {
            EGL_PLATFORM_ANGLE_TYPE_ANGLE,
            EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
            EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
            static_cast<EGLAttrib>(mOSWindow->getNativeDisplayPlatformType()),
            EGL_NONE,
        };

        PFNEGLGETPLATFORMDISPLAYPROC eglGetPlatformDisplay =
            reinterpret_cast<PFNEGLGETPLATFORMDISPLAYPROC>(
                eglGetProcAddress("eglGetPlatformDisplay"));
        ASSERT_TRUE(eglGetPlatformDisplay != nullptr);

        mEglDisplay =
            eglGetPlatformDisplay(GetEglPlatform(), reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY),
                                  defaultDisplayAttributes);
        ASSERT_TRUE(mEglDisplay != EGL_NO_DISPLAY);

        ASSERT_EGL_TRUE(eglInitialize(mEglDisplay, nullptr, nullptr));

        EGLint nConfigs = 0;

        ASSERT_EGL_TRUE(eglGetConfigs(mEglDisplay, nullptr, 0, &nConfigs));
        ASSERT_TRUE(nConfigs != 0);

        ASSERT_EGL_TRUE(eglChooseConfig(mEglDisplay, configAttributes, &mEglConfig, 1, &nConfigs));
    }

    void CreateSurface(ComPtr<ABI::Windows::UI::Composition::ISpriteVisual> visual,
                       EGLSurface &surface)
    {
        auto displayExtensions = eglQueryString(mEglDisplay, EGL_EXTENSIONS);

        // Check that the EGL_ANGLE_windows_ui_composition display extension is available
        ASSERT_TRUE(ANGLE_UNSAFE_TODO(
                        strstr(displayExtensions, "EGL_ANGLE_windows_ui_composition")) != nullptr);

        const EGLint contextAttributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};

        // Use a spritevisual as the nativewindowtype
        surface =
            eglCreateWindowSurface(mEglDisplay, mEglConfig,
                                   static_cast<EGLNativeWindowType>((void *)visual.Get()), nullptr);
        ASSERT_TRUE(surface != EGL_NO_SURFACE);

        mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, contextAttributes);
        ASSERT_TRUE(mEglContext != EGL_NO_CONTEXT);

        ASSERT_TRUE(eglMakeCurrent(mEglDisplay, surface, surface, mEglContext) != EGL_FALSE);
    }

    void testTearDown() override
    {
        if (!mRoHelper.SupportedWindowsRelease())
        {
            return;
        }
        if (mEglDisplay != EGL_NO_DISPLAY)
        {
            ASSERT_EGL_TRUE(eglTerminate(mEglDisplay));
            mEglDisplay = EGL_NO_DISPLAY;
        }

        OSWindow::Delete(&mOSWindow);
    }

    OSWindow *mOSWindow;
    ComPtr<ICompositor> mCompositor;
    ComPtr<IDispatcherQueueController> mDispatcherController;
    ComPtr<ICompositionColorBrush> mColorBrush;
    ComPtr<IDesktopWindowTarget> mDesktopTarget;
    ComPtr<ISpriteVisual> mAngleHost;

    EGLDisplay mEglDisplay;
    EGLContext mEglContext;
    EGLConfig mEglConfig;
    rx::RoHelper mRoHelper;

    using _SetThreadDpiAwarenessContext =
        DPI_AWARENESS_CONTEXT WINAPI(DPI_AWARENESS_CONTEXT dpiContext);

    _SetThreadDpiAwarenessContext *mFpSetThreadDpiAwarenessContext;
};

// This tests that a surface created using a SpriteVisual as container has the expected dimensions
// which should match the dimensions of the SpriteVisual passed in
TEST_P(EGLDirectCompositionTest, SurfaceSizeFromSpriteSize)
{
    // Only attempt this test when on Windows 10 1803+
    ANGLE_SKIP_TEST_IF(!mRoHelper.SupportedWindowsRelease());

    EGLSurface s{nullptr};
    CreateSurface(mAngleHost, s);

    EGLint surfacewidth = 0, surfaceheight = 0;
    eglQuerySurface(mEglDisplay, s, EGL_WIDTH, &surfacewidth);
    eglQuerySurface(mEglDisplay, s, EGL_HEIGHT, &surfaceheight);

    ComPtr<IVisual> angleVis;
    ASSERT_TRUE(SUCCEEDED(mAngleHost.As(&angleVis)));

    ABI::Windows::Foundation::Numerics::Vector2 visualsize{0, 0};

    ASSERT_TRUE(SUCCEEDED(angleVis->get_Size(&visualsize)));

    ASSERT_TRUE(surfacewidth == static_cast<int>(visualsize.X));
    ASSERT_TRUE(surfaceheight == static_cast<int>(visualsize.Y));

    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) !=
                EGL_FALSE);
    ASSERT_EGL_TRUE(eglDestroySurface(mEglDisplay, s));
    ASSERT_EGL_TRUE(eglDestroyContext(mEglDisplay, mEglContext));
    mEglContext = EGL_NO_CONTEXT;
}

// This tests that a WindowSurface can be created using a SpriteVisual as the containing window
// and that pixels can be successfully rendered into the resulting WindowSurface
TEST_P(EGLDirectCompositionTest, RenderSolidColor)
{
    // Only attempt this test when on Windows 10 1803+
    ANGLE_SKIP_TEST_IF(!mRoHelper.SupportedWindowsRelease());

    EGLSurface s{nullptr};
    CreateSurface(mAngleHost, s);

    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);

    glViewport(0, 0, WINDOWWIDTH, WINDOWHEIGHT);
    glClear(GL_COLOR_BUFFER_BIT);

    ASSERT_EGL_TRUE(eglSwapBuffers(mEglDisplay, s));

    // ensure user/DWM have a chance to paint the window and kick it to the top of the desktop
    // zorder before we attempt to sample
    angle::Sleep(200);
    mOSWindow->messageLoop();

    uint8_t *pixelBuffer = static_cast<uint8_t *>(malloc(WINDOWWIDTH * WINDOWHEIGHT * 4));
    ANGLE_UNSAFE_TODO(ZeroMemory(pixelBuffer, WINDOWWIDTH * WINDOWHEIGHT * 4));

    // In order to accurately capture a bitmap, we need to temporarily shift into per-monitor DPI
    // mode in order to get the window offset from desktop correct
    auto previous = mFpSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
    bool success  = mOSWindow->takeScreenshot(pixelBuffer);
    mFpSetThreadDpiAwarenessContext(previous);
    ASSERT_EGL_TRUE(success);

    ASSERT_EGL_TRUE(ANGLE_UNSAFE_TODO(pixelBuffer[(50 * 50 * 4)]) == 255);
    ASSERT_EGL_TRUE(ANGLE_UNSAFE_TODO(pixelBuffer[(50 * 50 * 4) + 1]) == 0);
    ASSERT_EGL_TRUE(ANGLE_UNSAFE_TODO(pixelBuffer[(50 * 50 * 4) + 2]) == 0);
    ASSERT_EGL_TRUE(ANGLE_UNSAFE_TODO(pixelBuffer[(50 * 50 * 4) + 3]) == 255);

    ASSERT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) !=
                EGL_FALSE);
    ASSERT_EGL_TRUE(eglDestroySurface(mEglDisplay, s));
    ASSERT_EGL_TRUE(eglDestroyContext(mEglDisplay, mEglContext));
    mEglContext = EGL_NO_CONTEXT;
}

ANGLE_INSTANTIATE_TEST(EGLDirectCompositionTest, WithNoFixture(ES2_D3D11()));

#endif  // ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW
