//
// Copyright 2024 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.
//
// DisplayWgpu.cpp:
//    Implements the class methods for DisplayWgpu.
//

#include "libANGLE/renderer/wgpu/DisplayWgpu.h"

#include <dawn/dawn_proc.h>

#include "common/debug.h"
#include "common/platform.h"

#include "libANGLE/Display.h"
#include "libANGLE/renderer/wgpu/ContextWgpu.h"
#include "libANGLE/renderer/wgpu/DeviceWgpu.h"
#include "libANGLE/renderer/wgpu/DisplayWgpu_api.h"
#include "libANGLE/renderer/wgpu/ImageWgpu.h"
#include "libANGLE/renderer/wgpu/SurfaceWgpu.h"
#include "libANGLE/renderer/wgpu/wgpu_proc_utils.h"

#include "EGL/eglext.h"

// The wgpu backend only provides a window surface when a window system is available. On Linux
// that requires X11 or Wayland; every other supported platform always has one. When it is
// unavailable (e.g. the ChromeOS wgpu build) CreateWgpuWindowSurface is stubbed out below and no
// EGL_WINDOW_BIT config is advertised. Unlike the rest of the backend, X11 vs Wayland is chosen at
// runtime (see DisplayWgpu::initialize) because a single Linux build commonly enables both.
#if defined(ANGLE_PLATFORM_LINUX) && !defined(ANGLE_USE_X11) && !defined(ANGLE_USE_WAYLAND)
#    define ANGLE_WEBGPU_HAS_WINDOW_SURFACE_TYPE 0
#else
#    define ANGLE_WEBGPU_HAS_WINDOW_SURFACE_TYPE 1
#endif

namespace rx
{

#if !ANGLE_WEBGPU_HAS_WINDOW_SURFACE_TYPE
WindowSurfaceWgpu *CreateWgpuWindowSurface(const egl::SurfaceState &surfaceState,
                                           EGLNativeWindowType window)
{
    UNIMPLEMENTED();
    return nullptr;
}
#endif

DisplayWgpu::DisplayWgpu(const egl::DisplayState &state) : DisplayImpl(state) {}

DisplayWgpu::~DisplayWgpu() {}

egl::Error DisplayWgpu::initialize(egl::Display *display)
{
    const egl::AttributeMap &attribs = display->getAttributeMap();
    mProcTable                       = *reinterpret_cast<DawnProcTable *>(
        attribs.get(EGL_PLATFORM_ANGLE_DAWN_PROC_TABLE_ANGLE,
                                          reinterpret_cast<EGLAttrib>(&webgpu::GetDefaultProcTable())));

    WGPUInstance providedInstance =
        reinterpret_cast<WGPUInstance>(attribs.get(EGL_PLATFORM_ANGLE_WEBGPU_INSTANCE_ANGLE, 0));
    if (providedInstance)
    {
        mProcTable.instanceAddRef(providedInstance);
        mInstance = webgpu::InstanceHandle::Acquire(&mProcTable, providedInstance);
    }

    WGPUDevice providedDevice =
        reinterpret_cast<WGPUDevice>(attribs.get(EGL_PLATFORM_ANGLE_WEBGPU_DEVICE_ANGLE, 0));
    if (providedDevice)
    {
        mProcTable.deviceAddRef(providedDevice);
        mDevice = webgpu::DeviceHandle::Acquire(&mProcTable, providedDevice);

        mAdapter =
            webgpu::AdapterHandle::Acquire(&mProcTable, mProcTable.deviceGetAdapter(mDevice.get()));

        if (!mInstance)
        {
            mInstance = webgpu::InstanceHandle::Acquire(
                &mProcTable, mProcTable.adapterGetInstance(mAdapter.get()));
        }
    }
    else
    {
        ANGLE_TRY(createWgpuDevice());
    }

    mQueue = webgpu::QueueHandle::Acquire(&mProcTable, mProcTable.deviceGetQueue(mDevice.get()));

    mFormatTable.initialize();

    mLimitsWgpu = WGPU_LIMITS_INIT;
    mProcTable.deviceGetLimits(mDevice.get(), &mLimitsWgpu);

    mWindowSystem = angle::NativeWindowSystem::Other;
#if defined(ANGLE_USE_X11) || defined(ANGLE_USE_WAYLAND)
    {
        // The front-end fills in EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE from the
        // environment when the app leaves it unset (Display::UpdateAttribsFromEnvironment), so it
        // already reflects the same default the front-end picks. Anything other than X11/Wayland
        // (no window system) leaves mWindowSystem as Other.
        EGLAttrib platformType = attribs.get(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, 0);
#    if defined(ANGLE_USE_X11)
        if (platformType == EGL_PLATFORM_X11_EXT)
        {
            mWindowSystem = angle::NativeWindowSystem::X11;
        }
#    endif
#    if defined(ANGLE_USE_WAYLAND)
        if (platformType == EGL_PLATFORM_WAYLAND_EXT)
        {
            mWindowSystem = angle::NativeWindowSystem::Wayland;
        }
#    endif
    }
#endif

    initializeFeatures();

    webgpu::GenerateCaps(mLimitsWgpu, &mGLCaps, &mGLTextureCaps, &mGLExtensions, &mGLLimitations,
                         &mEGLCaps, &mEGLExtensions, &mMaxSupportedClientVersion);

    return egl::NoError();
}

void DisplayWgpu::terminate()
{
    mAdapter  = nullptr;
    mInstance = nullptr;
    mDevice   = nullptr;
    mQueue    = nullptr;
}

egl::Error DisplayWgpu::makeCurrent(egl::Display *display,
                                    egl::Surface *drawSurface,
                                    egl::Surface *readSurface,
                                    gl::Context *context)
{
    // Ensure that the correct global DebugAnnotator is installed when the end2end tests change
    // the ANGLE back-end (done frequently).
    display->setGlobalDebugAnnotator();

    return egl::NoError();
}

egl::ConfigSet DisplayWgpu::generateConfigs()
{
    egl::Config config;
    config.renderTargetFormat    = GL_BGRA8_EXT;
    config.depthStencilFormat    = GL_DEPTH24_STENCIL8;
    config.bufferSize            = 32;
    config.redSize               = 8;
    config.greenSize             = 8;
    config.blueSize              = 8;
    config.alphaSize             = 8;
    config.alphaMaskSize         = 0;
    config.bindToTextureRGB      = EGL_FALSE;
    config.bindToTextureRGBA     = EGL_FALSE;
    config.colorBufferType       = EGL_RGB_BUFFER;
    config.configCaveat          = EGL_NONE;
    config.conformant            = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
    config.depthSize             = 24;
    config.level                 = 0;
    config.matchNativePixmap     = EGL_NONE;
    config.maxPBufferWidth       = 0;
    config.maxPBufferHeight      = 0;
    config.maxPBufferPixels      = 0;
    config.maxSwapInterval       = 1;
    config.minSwapInterval       = 1;
    config.nativeRenderable      = EGL_TRUE;
    config.nativeVisualID        = 0;
    config.nativeVisualType      = EGL_NONE;
    config.renderableType        = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
    config.sampleBuffers         = 0;
    config.samples               = 0;
    config.stencilSize           = 8;
    config.surfaceType           = EGL_PBUFFER_BIT;
#if ANGLE_WEBGPU_HAS_WINDOW_SURFACE_TYPE
    config.surfaceType |= EGL_WINDOW_BIT;
#endif
    config.optimalOrientation    = 0;
    config.transparentType       = EGL_NONE;
    config.transparentRedValue   = 0;
    config.transparentGreenValue = 0;
    config.transparentBlueValue  = 0;

    egl::ConfigSet configSet;
    configSet.add(config);
    return configSet;
}

bool ThreadSafeDisplayWgpu::testDeviceLost()
{
    return false;
}

egl::Error ThreadSafeDisplayWgpu::restoreLostDevice(const egl::ThreadSafeDisplay *display)
{
    return egl::NoError();
}

egl::Error DisplayWgpu::validateClientBuffer(const egl::Config *configuration,
                                             EGLenum buftype,
                                             EGLClientBuffer clientBuffer,
                                             const egl::AttributeMap &attribs) const
{
    switch (buftype)
    {
        case EGL_WEBGPU_TEXTURE_ANGLE:
            return validateExternalWebGPUTexture(clientBuffer, attribs);
        default:
            return DisplayImpl::validateClientBuffer(configuration, buftype, clientBuffer, attribs);
    }
}

egl::Error DisplayWgpu::validateImageClientBuffer(const gl::Context *context,
                                                  EGLenum target,
                                                  EGLClientBuffer clientBuffer,
                                                  const egl::AttributeMap &attribs) const
{
    switch (target)
    {
        case EGL_WEBGPU_TEXTURE_ANGLE:
            return validateExternalWebGPUTexture(clientBuffer, attribs);
        default:
            return DisplayImpl::validateImageClientBuffer(context, target, clientBuffer, attribs);
    }
}

egl::Error DisplayWgpu::validateExternalWebGPUTexture(EGLClientBuffer buffer,
                                                      const egl::AttributeMap &attribs) const
{
    WGPUTexture externalTexture = reinterpret_cast<WGPUTexture>(buffer);
    if (externalTexture == nullptr)
    {
        return egl::Error(EGL_BAD_PARAMETER, "NULL Buffer");
    }

    WGPUTextureFormat externalTextureFormat = mProcTable.textureGetFormat(externalTexture);
    const webgpu::Format *webgpuFormat =
        getFormatForImportedTexture(attribs, externalTextureFormat);
    if (webgpuFormat == nullptr)
    {
        return egl::Error(EGL_BAD_PARAMETER, "Invalid format.");
    }

    return egl::NoError();
}

bool DisplayWgpu::isValidNativeWindow(EGLNativeWindowType window) const
{
    return true;
}

std::string DisplayWgpu::getRendererDescription()
{
    return "WebGPU";
}

std::string DisplayWgpu::getVendorString()
{
    return "WebGPU";
}

std::string DisplayWgpu::getVersionString(bool includeFullVersion)
{
    return std::string();
}

DeviceImpl *DisplayWgpu::createDevice()
{
    return new DeviceWgpu();
}

egl::Error DisplayWgpu::waitClient(const gl::Context *context)
{
    return egl::NoError();
}

egl::Error DisplayWgpu::waitNative(const gl::Context *context, EGLint engine)
{
    return egl::NoError();
}

gl::Version DisplayWgpu::getMaxSupportedESVersion() const
{
    return mMaxSupportedClientVersion;
}

gl::Version DisplayWgpu::getMaxConformantESVersion() const
{
    return mMaxSupportedClientVersion;
}

SurfaceImpl *DisplayWgpu::createWindowSurface(const egl::SurfaceState &state,
                                              EGLNativeWindowType window,
                                              const egl::AttributeMap &attribs)
{
#if defined(ANGLE_USE_X11)
    if (mWindowSystem == angle::NativeWindowSystem::X11)
    {
        return CreateWgpuX11WindowSurface(state, window);
    }
#endif
#if defined(ANGLE_USE_WAYLAND)
    if (mWindowSystem == angle::NativeWindowSystem::Wayland)
    {
        return CreateWgpuWaylandWindowSurface(state, window);
    }
#endif
#if !defined(ANGLE_USE_X11) && !defined(ANGLE_USE_WAYLAND)
    return CreateWgpuWindowSurface(state, window);
#else
    UNIMPLEMENTED();
    return nullptr;
#endif
}

SurfaceImpl *DisplayWgpu::createPbufferSurface(const egl::SurfaceState &state,
                                               const egl::AttributeMap &attribs)
{
    return new OffscreenSurfaceWgpu(state, EGL_NONE, nullptr);
}

SurfaceImpl *DisplayWgpu::createPbufferFromClientBuffer(const egl::SurfaceState &state,
                                                        EGLenum buftype,
                                                        EGLClientBuffer buffer,
                                                        const egl::AttributeMap &attribs)
{
    return new OffscreenSurfaceWgpu(state, buftype, buffer);
}

SurfaceImpl *DisplayWgpu::createPixmapSurface(const egl::SurfaceState &state,
                                              NativePixmapType nativePixmap,
                                              const egl::AttributeMap &attribs)
{
    UNIMPLEMENTED();
    return nullptr;
}

ImageImpl *DisplayWgpu::createImage(const egl::ImageState &state,
                                    const gl::Context *context,
                                    EGLenum target,
                                    const egl::AttributeMap &attribs)
{
    return new ImageWgpu(state, context);
}

ExternalImageSiblingImpl *DisplayWgpu::createExternalImageSibling(const gl::Context *context,
                                                                  EGLenum target,
                                                                  EGLClientBuffer buffer,
                                                                  const egl::AttributeMap &attribs)
{
    switch (target)
    {
        case EGL_WEBGPU_TEXTURE_ANGLE:
            return new WebGPUTextureImageSiblingWgpu(buffer, attribs);
        default:
            return DisplayImpl::createExternalImageSibling(context, target, buffer, attribs);
    }
}

rx::ContextImpl *DisplayWgpu::createContext(const gl::State &state,
                                            gl::ErrorSet *errorSet,
                                            const egl::Config *configuration,
                                            const gl::Context *shareContext,
                                            const egl::AttributeMap &attribs)
{
    return new ContextWgpu(state, errorSet, this);
}

StreamProducerImpl *DisplayWgpu::createStreamProducerD3DTexture(
    egl::Stream::ConsumerType consumerType,
    const egl::AttributeMap &attribs)
{
    UNIMPLEMENTED();
    return nullptr;
}

ShareGroupImpl *DisplayWgpu::createShareGroup(const egl::ShareGroupState &state)
{
    return new ShareGroupWgpu(state);
}

void DisplayWgpu::populateFeatureList(angle::FeatureList *features)
{
    mFeatures.populateFeatureList(features);
}

angle::NativeWindowSystem DisplayWgpu::getWindowSystem() const
{
    return mWindowSystem;
}

const webgpu::Format *DisplayWgpu::getFormatForImportedTexture(const egl::AttributeMap &attribs,
                                                               WGPUTextureFormat wgpuFormat) const
{
    GLenum requestedGLFormat = attribs.getAsInt(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_NONE);
    GLenum requestedGLType   = attribs.getAsInt(EGL_TEXTURE_TYPE_ANGLE, GL_NONE);

    if (requestedGLFormat != GL_NONE)
    {
        const gl::InternalFormat &internalFormat =
            gl::GetInternalFormatInfo(requestedGLFormat, requestedGLType);
        if (internalFormat.internalFormat == GL_NONE)
        {
            return nullptr;
        }

        const webgpu::Format &format = mFormatTable[internalFormat.sizedInternalFormat];
        if (format.getActualWgpuTextureFormat() != wgpuFormat)
        {
            return nullptr;
        }

        return &format;
    }
    else
    {
        return mFormatTable.findClosestTextureFormat(wgpuFormat);
    }
}

void DisplayWgpu::generateExtensions(egl::DisplayExtensions *outExtensions) const
{
    *outExtensions = mEGLExtensions;
}

void DisplayWgpu::generateCaps(egl::Caps *outCaps) const
{
    *outCaps = mEGLCaps;
}

void DisplayWgpu::initializeFeatures()
{
    ApplyFeatureOverrides(&mFeatures, getState().featureOverrides);
    if (mState.featureOverrides.allDisabled)
    {
        return;
    }

    // Disabled by default. Gets explicitly enabled by ANGLE embedders.
    ANGLE_FEATURE_CONDITION((&mFeatures), avoidWaitAny, false);
}

egl::Error DisplayWgpu::createWgpuDevice()
{
    if (!mInstance)
    {
        WGPUInstanceDescriptor instanceDescriptor = WGPU_INSTANCE_DESCRIPTOR_INIT;
        static constexpr auto kTimedWaitAny       = WGPUInstanceFeatureName_TimedWaitAny;
        instanceDescriptor.requiredFeatureCount   = 1;
        instanceDescriptor.requiredFeatures       = &kTimedWaitAny;
        mInstance                                 = webgpu::InstanceHandle::Acquire(&mProcTable,
                                                                                    mProcTable.createInstance(&instanceDescriptor));
    }

    struct RequestAdapterResult
    {
        WGPURequestAdapterStatus status;
        webgpu::AdapterHandle adapter;
        std::string message;
    };
    RequestAdapterResult adapterResult;

    WGPURequestAdapterOptions requestAdapterOptions = WGPU_REQUEST_ADAPTER_OPTIONS_INIT;

    WGPURequestAdapterCallbackInfo requestAdapterCallback = WGPU_REQUEST_ADAPTER_CALLBACK_INFO_INIT;
    requestAdapterCallback.mode                           = WGPUCallbackMode_WaitAnyOnly;
    requestAdapterCallback.callback = [](WGPURequestAdapterStatus status, WGPUAdapter adapter,
                                         struct WGPUStringView message, void *userdata1,
                                         void *userdata2) {
        RequestAdapterResult *result = reinterpret_cast<RequestAdapterResult *>(userdata1);
        const DawnProcTable *wgpu    = reinterpret_cast<const DawnProcTable *>(userdata2);

        result->status  = status;
        result->adapter = webgpu::AdapterHandle::Acquire(wgpu, adapter);
        result->message = std::string(message.data, message.length);
    };
    requestAdapterCallback.userdata1 = &adapterResult;
    requestAdapterCallback.userdata2 = &mProcTable;

    WGPUFutureWaitInfo futureWaitInfo;
    futureWaitInfo.future = mProcTable.instanceRequestAdapter(
        mInstance.get(), &requestAdapterOptions, requestAdapterCallback);

    WGPUWaitStatus status = mProcTable.instanceWaitAny(mInstance.get(), 1, &futureWaitInfo, -1);
    if (webgpu::IsWgpuError(status))
    {
        std::ostringstream err;
        err << "Failed to get WebGPU adapter: " << adapterResult.message;
        return egl::Error(EGL_BAD_ALLOC, err.str());
    }

    mAdapter = adapterResult.adapter;

    std::vector<WGPUFeatureName> requiredFeatures;  // empty for now

    WGPUDeviceDescriptor deviceDesc = WGPU_DEVICE_DESCRIPTOR_INIT;
    deviceDesc.requiredFeatureCount = requiredFeatures.size();
    deviceDesc.requiredFeatures     = requiredFeatures.data();
    deviceDesc.uncapturedErrorCallbackInfo.callback =
        [](WGPUDevice const *device, WGPUErrorType type, struct WGPUStringView message,
           void *userdata1, void *userdata2) {
            ASSERT(userdata1 == nullptr);
            ASSERT(userdata2 == nullptr);
            ERR() << "Error: " << static_cast<std::underlying_type<WGPUErrorType>::type>(type)
                  << " - message: " << std::string(message.data, message.length);
        };

    struct RequestDeviceResult
    {
        WGPURequestDeviceStatus status;
        webgpu::DeviceHandle device;
        std::string message;
    };
    RequestDeviceResult deviceResult;

    WGPURequestDeviceCallbackInfo requestDeviceCallback = WGPU_REQUEST_DEVICE_CALLBACK_INFO_INIT;
    requestDeviceCallback.mode                          = WGPUCallbackMode_WaitAnyOnly;
    requestDeviceCallback.callback = [](WGPURequestDeviceStatus status, WGPUDevice device,
                                        struct WGPUStringView message, void *userdata1,
                                        void *userdata2) {
        RequestDeviceResult *result = reinterpret_cast<RequestDeviceResult *>(userdata1);
        const DawnProcTable *wgpu   = reinterpret_cast<const DawnProcTable *>(userdata2);

        result->status  = status;
        result->device  = webgpu::DeviceHandle::Acquire(wgpu, device);
        result->message = std::string(message.data, message.length);
    };
    requestDeviceCallback.userdata1 = &deviceResult;
    requestDeviceCallback.userdata2 = &mProcTable;

    futureWaitInfo.future =
        mProcTable.adapterRequestDevice(mAdapter.get(), &deviceDesc, requestDeviceCallback);

    status = mProcTable.instanceWaitAny(mInstance.get(), 1, &futureWaitInfo, -1);
    if (webgpu::IsWgpuError(status))
    {
        std::ostringstream err;
        err << "Failed to get WebGPU device: " << deviceResult.message;
        return egl::Error(EGL_BAD_ALLOC, err.str());
    }

    mDevice = deviceResult.device;

    return egl::NoError();
}

DisplayImpl *CreateWgpuDisplay(const egl::DisplayState &state)
{
    return new DisplayWgpu(state);
}

}  // namespace rx
