// Copyright 2020 the Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/Surface.h"

#include <memory>
#include <string>
#include <utility>

#include "dawn/native/ValidationUtils_autogen.h"
#include "src/dawn/native/ChainUtils.h"
#include "src/dawn/native/Device.h"
#include "src/dawn/native/Instance.h"
#include "src/dawn/native/SwapChain.h"
#include "src/dawn/native/Texture.h"
#include "src/dawn/native/utils/WGPUHelpers.h"
#include "src/utils/platform.h"

#if DAWN_PLATFORM_IS(WINDOWS)
#include "src/utils/windows_with_undefs.h"
#endif  // DAWN_PLATFORM_IS(WINDOWS)

#if defined(DAWN_USE_WINDOWS_UI)
#include <windows.ui.core.h>
#include <windows.ui.xaml.controls.h>
#endif  // defined(DAWN_USE_WINDOWS_UI)

#if defined(DAWN_USE_X11)
#include "src/dawn/common/xlib_with_undefs.h"
#include "src/dawn/native/X11Functions.h"
#endif  // defined(DAWN_USE_X11)

namespace dawn::native {

absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
    Surface::Type value,
    const absl::FormatConversionSpec& spec,
    absl::FormatSink* s) {
    switch (value) {
        case Surface::Type::AndroidWindow:
            s->Append("AndroidWindow");
            break;
        case Surface::Type::MetalLayer:
            s->Append("MetalLayer");
            break;
        case Surface::Type::WaylandSurface:
            s->Append("WaylandSurface");
            break;
        case Surface::Type::WindowsHWND:
            s->Append("WindowsHWND");
            break;
        case Surface::Type::WindowsCoreWindow:
            s->Append("WindowsCoreWindow");
            break;
        case Surface::Type::WindowsUWPSwapChainPanel:
            s->Append("WindowsUWPSwapChainPanel");
            break;
        case Surface::Type::WindowsWinUISwapChainPanel:
            s->Append("WindowsWinUISwapChainPanel");
            break;
        case Surface::Type::XlibWindow:
            s->Append("XlibWindow");
            break;
        case Surface::Type::Undefined:
            DAWN_UNREACHABLE();
            break;
    }
    return {true};
}

#if defined(DAWN_ENABLE_BACKEND_METAL)
bool InheritsFromCAMetalLayer(void* obj);
#endif  // defined(DAWN_ENABLE_BACKEND_METAL)

ResultOrError<UnpackedPtr<SurfaceDescriptor>> ValidateSurfaceDescriptor(
    InstanceBase* instance,
    const SurfaceDescriptor* rawDescriptor) {
    DAWN_INVALID_IF(rawDescriptor->nextInChain == nullptr,
                    "Surface cannot be created with %s. nextInChain is not specified.",
                    rawDescriptor);
    UnpackedPtr<SurfaceDescriptor> descriptor;
    DAWN_TRY_ASSIGN(descriptor, ValidateAndUnpack(rawDescriptor));

    if (descriptor.Has<SurfaceColorManagement>()) {
        return DAWN_VALIDATION_ERROR("SurfaceColorManagement unsupported.");
    }

    wgpu::SType type;
    DAWN_TRY_ASSIGN(
        type, (descriptor.ValidateBranches<
                  Branch<SurfaceSourceAndroidNativeWindow>, Branch<SurfaceSourceMetalLayer>,
                  Branch<SurfaceSourceWindowsHWND>, Branch<SurfaceDescriptorFromWindowsCoreWindow>,
                  Branch<SurfaceDescriptorFromWindowsUWPSwapChainPanel>,
                  Branch<SurfaceDescriptorFromWindowsWinUISwapChainPanel>,
                  Branch<SurfaceSourceXlibWindow>, Branch<SurfaceSourceWaylandSurface>>()));
    switch (type) {
#if DAWN_PLATFORM_IS(ANDROID)
        case wgpu::SType::SurfaceSourceAndroidNativeWindow: {
            auto* subDesc = descriptor.Get<SurfaceSourceAndroidNativeWindow>();
            DAWN_ASSERT(subDesc != nullptr);
            DAWN_INVALID_IF(subDesc->window == nullptr, "Android window is not set.");
            return descriptor;
        }
#endif  // DAWN_PLATFORM_IS(ANDROID)
#if defined(DAWN_ENABLE_BACKEND_METAL)
        case wgpu::SType::SurfaceSourceMetalLayer: {
            auto* subDesc = descriptor.Get<SurfaceSourceMetalLayer>();
            DAWN_ASSERT(subDesc != nullptr);
            // Check that the layer is a CAMetalLayer (or a derived class).
            DAWN_INVALID_IF(!InheritsFromCAMetalLayer(subDesc->layer),
                            "Layer must be a CAMetalLayer");
            return descriptor;
        }
#endif  // defined(DAWN_ENABLE_BACKEND_METAL)
#if DAWN_PLATFORM_IS(WIN32)
        case wgpu::SType::SurfaceSourceWindowsHWND: {
            auto* subDesc = descriptor.Get<SurfaceSourceWindowsHWND>();
            DAWN_ASSERT(subDesc != nullptr);
            DAWN_INVALID_IF(IsWindow(static_cast<HWND>(subDesc->hwnd)) == 0, "Invalid HWND");
            return descriptor;
        }
#endif  // DAWN_PLATFORM_IS(WIN32)
#if defined(DAWN_USE_WINDOWS_UI)
        case wgpu::SType::SurfaceDescriptorFromWindowsCoreWindow: {
            auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsCoreWindow>();
            DAWN_ASSERT(subDesc != nullptr);
            // Validate the coreWindow by query for ICoreWindow interface
            ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
            DAWN_INVALID_IF(subDesc->coreWindow == nullptr ||
                                FAILED(static_cast<IUnknown*>(subDesc->coreWindow)
                                           ->QueryInterface(IID_PPV_ARGS(&coreWindow))),
                            "Invalid CoreWindow");
            return descriptor;
        }
        case wgpu::SType::SurfaceDescriptorFromWindowsUWPSwapChainPanel: {
            auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsUWPSwapChainPanel>();
            DAWN_ASSERT(subDesc != nullptr);
            // Validate the swapChainPanel by querying for ISwapChainPanel interface
            ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
            DAWN_INVALID_IF(subDesc->swapChainPanel == nullptr ||
                                FAILED(static_cast<IUnknown*>(subDesc->swapChainPanel)
                                           ->QueryInterface(IID_PPV_ARGS(&swapChainPanel))),
                            "Invalid SwapChainPanel");
            return descriptor;
        }
        case wgpu::SType::SurfaceDescriptorFromWindowsWinUISwapChainPanel: {
            auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsWinUISwapChainPanel>();
            DAWN_ASSERT(subDesc != nullptr);
            // Unfortunately, checking whether this is a valid
            // Microsoft.UI.Xaml.Controls.SwapChainPanel would require the WindowsAppSDK as a
            // dependency, which is not trivial. So we'll only check for nullptr here.
            DAWN_INVALID_IF(subDesc->swapChainPanel == nullptr, "SwapChainPanel is nullptr.");
            return descriptor;
        }
#endif  // defined(DAWN_USE_WINDOWS_UI)
#if defined(DAWN_USE_WAYLAND)
        case wgpu::SType::SurfaceSourceWaylandSurface: {
            auto* subDesc = descriptor.Get<SurfaceSourceWaylandSurface>();
            DAWN_ASSERT(subDesc != nullptr);
            // Unfortunately we can\'t check the validity of wayland objects. Only that they
            // aren't nullptr.
            DAWN_INVALID_IF(subDesc->display == nullptr, "Wayland display is nullptr.");
            DAWN_INVALID_IF(subDesc->surface == nullptr, "Wayland surface is nullptr.");
            return descriptor;
        }
#endif  // defined(DAWN_USE_WAYLAND)
#if defined(DAWN_USE_X11)
        case wgpu::SType::SurfaceSourceXlibWindow: {
            auto* subDesc = descriptor.Get<SurfaceSourceXlibWindow>();
            DAWN_ASSERT(subDesc != nullptr);
            // Check the validity of the window by calling a getter function on the window that
            // returns a status code. If the window is bad the call return a status of zero. We
            // need to set a temporary X11 error handler while doing this because the default
            // X11 error handler exits the program on any error.
            const X11Functions* x11 = instance->GetOrLoadX11Functions();
            DAWN_INVALID_IF(!x11->IsX11Loaded(), "Couldn't load libX11.");

            XErrorHandler oldErrorHandler =
                x11->xSetErrorHandler([](Display*, XErrorEvent*) { return 0; });
            XWindowAttributes attributes;
            int status =
                x11->xGetWindowAttributes(reinterpret_cast<Display*>(subDesc->display),
                                          static_cast<Window>(subDesc->window), &attributes);
            x11->xSetErrorHandler(oldErrorHandler);

            DAWN_INVALID_IF(status == 0, "Invalid X Window");
            return descriptor;
        }
#endif  // defined(DAWN_USE_X11)
        default:
            return DAWN_VALIDATION_ERROR("Unsupported sType (%s)", type);
    }
}

MaybeError ValidateSurfaceConfiguration(DeviceBase* device,
                                        const PhysicalDeviceSurfaceCapabilities& capabilities,
                                        const SurfaceConfiguration* config,
                                        const Surface* surface) {
    UnpackedPtr<SurfaceConfiguration> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(config));

    DAWN_TRY(config->device->ValidateIsAlive());

    // Check that config matches capabilities, this implicitly validates the value of the enums.
    DAWN_INVALID_IF(!IsSubset(config->usage, capabilities.usages),
                    "Usages requested (%s) are not supported by the adapter (%s) which supports "
                    "only %s for this surface.",
                    config->usage, config->device->GetAdapter(), capabilities.usages);

    auto formatIt =
        std::find(capabilities.formats.begin(), capabilities.formats.end(), config->format);
    DAWN_INVALID_IF(formatIt == capabilities.formats.end(),
                    "Format (%s) is not supported by the adapter (%s) for this surface.",
                    config->format, config->device->GetAdapter());

    auto presentModeIt = std::find(capabilities.presentModes.begin(),
                                   capabilities.presentModes.end(), config->presentMode);
    DAWN_INVALID_IF(presentModeIt == capabilities.presentModes.end(),
                    "Present mode (%s) is not supported by the adapter (%s) for this surface.",
                    config->presentMode, config->device->GetAdapter());

    auto alphaModeIt = std::find(capabilities.alphaModes.begin(), capabilities.alphaModes.end(),
                                 config->alphaMode);
    DAWN_INVALID_IF(alphaModeIt == capabilities.alphaModes.end(),
                    "Alpha mode (%s) is not supported by the adapter (%s) for this surface.",
                    config->alphaMode, config->device->GetAdapter());

    // Validate the surface would produce valid textures.
    TextureDescriptor textureDesc;
    textureDesc.usage = config->usage;
    textureDesc.size = {config->width, config->height};
    textureDesc.format = config->format;
    textureDesc.dimension = wgpu::TextureDimension::e2D;
    textureDesc.viewFormats = config->viewFormats;

    UnpackedPtr<TextureDescriptor> unpackedTextureDesc;
    DAWN_TRY_ASSIGN(unpackedTextureDesc, ValidateAndUnpack(&textureDesc));
    DAWN_TRY_CONTEXT(ValidateTextureDescriptor(device, unpackedTextureDesc),
                     "validating the configuration of %s would produce valid textures", surface);

    return {};
}

class AdapterSurfaceCapCache {
  public:
    template <typename F>
    MaybeError WithAdapterCapabilities(AdapterBase* adapter, const Surface* surface, F f) {
        if (mCachedCapabilitiesAdapter.Promote().Get() != adapter) {
            const PhysicalDeviceBase* physicalDevice = adapter->GetPhysicalDevice();
            DAWN_TRY_ASSIGN(mCachedCapabilities, physicalDevice->GetSurfaceCapabilities(
                                                     adapter->GetInstance(), surface));
            mCachedCapabilitiesAdapter = GetWeakRef(adapter);
        }
        return f(mCachedCapabilities);
    }

  private:
    WeakRef<AdapterBase> mCachedCapabilitiesAdapter = nullptr;
    PhysicalDeviceSurfaceCapabilities mCachedCapabilities;
};

// static
Ref<Surface> Surface::MakeError(InstanceBase* instance) {
    return AcquireRef(new Surface(instance, ErrorMonad::kError));
}

Surface::Surface(InstanceBase* instance, ErrorTag tag) : ErrorMonad(tag), mInstance(instance) {}

Surface::Surface(InstanceBase* instance, const UnpackedPtr<SurfaceDescriptor>& descriptor)
    : ErrorMonad(),
      mInstance(instance),
      mCapabilityCache(std::make_unique<AdapterSurfaceCapCache>()) {
    mLabel = std::string(descriptor->label);

    // Type is validated in validation, otherwise this may crash with an assert failure.
    wgpu::SType type =
        descriptor
            .ValidateBranches<
                Branch<SurfaceSourceAndroidNativeWindow>, Branch<SurfaceSourceMetalLayer>,
                Branch<SurfaceSourceWindowsHWND>, Branch<SurfaceDescriptorFromWindowsCoreWindow>,
                Branch<SurfaceDescriptorFromWindowsUWPSwapChainPanel>,
                Branch<SurfaceDescriptorFromWindowsWinUISwapChainPanel>,
                Branch<SurfaceSourceXlibWindow>, Branch<SurfaceSourceWaylandSurface>>()
            .AcquireSuccess();
    switch (type) {
        case wgpu::SType::SurfaceSourceAndroidNativeWindow: {
            auto* subDesc = descriptor.Get<SurfaceSourceAndroidNativeWindow>();
            mType = Type::AndroidWindow;
            mAndroidNativeWindow = subDesc->window;
            break;
        }
        case wgpu::SType::SurfaceSourceMetalLayer: {
            auto* subDesc = descriptor.Get<SurfaceSourceMetalLayer>();
            mType = Type::MetalLayer;
            mMetalLayer = subDesc->layer;
            break;
        }
        case wgpu::SType::SurfaceSourceWindowsHWND: {
            auto* subDesc = descriptor.Get<SurfaceSourceWindowsHWND>();
            mType = Type::WindowsHWND;
            mHInstance = subDesc->hinstance;
            mHWND = subDesc->hwnd;
            break;
        }
#if defined(DAWN_USE_WINDOWS_UI)
        case wgpu::SType::SurfaceDescriptorFromWindowsCoreWindow: {
            auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsCoreWindow>();
            mType = Type::WindowsCoreWindow;
            mCoreWindow = static_cast<IUnknown*>(subDesc->coreWindow);
            break;
        }
        case wgpu::SType::SurfaceDescriptorFromWindowsUWPSwapChainPanel: {
            auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsUWPSwapChainPanel>();
            mType = Type::WindowsUWPSwapChainPanel;
            mUWPSwapChainPanel = static_cast<IUnknown*>(subDesc->swapChainPanel);
            break;
        }
        case wgpu::SType::SurfaceDescriptorFromWindowsWinUISwapChainPanel: {
            auto* subDesc = descriptor.Get<SurfaceDescriptorFromWindowsWinUISwapChainPanel>();
            mType = Type::WindowsWinUISwapChainPanel;
            mWinUISwapChainPanel = static_cast<IUnknown*>(subDesc->swapChainPanel);
            break;
        }
#endif  // defined(DAWN_USE_WINDOWS_UI)
        case wgpu::SType::SurfaceSourceWaylandSurface: {
            auto* subDesc = descriptor.Get<SurfaceSourceWaylandSurface>();
            mType = Type::WaylandSurface;
            mWaylandDisplay = subDesc->display;
            mWaylandSurface = subDesc->surface;
            break;
        }
        case wgpu::SType::SurfaceSourceXlibWindow: {
            auto* subDesc = descriptor.Get<SurfaceSourceXlibWindow>();
            mType = Type::XlibWindow;
            mXDisplay = subDesc->display;
            mXWindow = subDesc->window;
            break;
        }
        default:
            DAWN_UNREACHABLE();
    }
}

Surface::~Surface() {
    if (mSwapChain != nullptr) {
        [[maybe_unused]] bool error = mInstance->ConsumedError(Unconfigure());
    }

    if (mRecycledSwapChain != nullptr) {
        mRecycledSwapChain->DetachFromSurface();
        mRecycledSwapChain = nullptr;
    }
}

InstanceBase* Surface::GetInstance() const {
    return mInstance.Get();
}

DeviceBase* Surface::GetCurrentDevice() const {
    return mCurrentDevice.Get();
}

Surface::Type Surface::GetType() const {
    DAWN_CHECK(!IsError());
    return mType;
}

void* Surface::GetAndroidNativeWindow() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::AndroidWindow);
    return mAndroidNativeWindow;
}

void* Surface::GetMetalLayer() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::MetalLayer);
    return mMetalLayer;
}

void* Surface::GetWaylandDisplay() const {
    DAWN_CHECK(mType == Type::WaylandSurface);
    return mWaylandDisplay;
}

void* Surface::GetWaylandSurface() const {
    DAWN_CHECK(mType == Type::WaylandSurface);
    return mWaylandSurface;
}

void* Surface::GetHInstance() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::WindowsHWND);
    return mHInstance;
}
void* Surface::GetHWND() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::WindowsHWND);
    return mHWND;
}

IUnknown* Surface::GetCoreWindow() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::WindowsCoreWindow);
#if defined(DAWN_USE_WINDOWS_UI)
    return mCoreWindow.Get();
#else
    return nullptr;
#endif
}

IUnknown* Surface::GetUWPSwapChainPanel() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::WindowsUWPSwapChainPanel);
#if defined(DAWN_USE_WINDOWS_UI)
    return mUWPSwapChainPanel.Get();
#else
    return nullptr;
#endif
}

IUnknown* Surface::GetWinUISwapChainPanel() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::WindowsWinUISwapChainPanel);
#if defined(DAWN_USE_WINDOWS_UI)
    return mWinUISwapChainPanel.Get();
#else
    return nullptr;
#endif
}

void* Surface::GetXDisplay() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::XlibWindow);
    return mXDisplay;
}
uint64_t Surface::GetXWindow() const {
    DAWN_CHECK(!IsError());
    DAWN_CHECK(mType == Type::XlibWindow);
    return mXWindow;
}

MaybeError Surface::Configure(const SurfaceConfiguration* configIn) {
    SurfaceConfiguration config = configIn->WithTrivialFrontendDefaults();
    DAWN_CHECK(config.device);
    // Configured-or-not is specified as a client-side state, so it must be
    // maintained even on error surfaces.
    mCurrentDevice = config.device;
    // Any errors are routed to the new device.

    DAWN_INVALID_IF(IsError(), "%s is invalid.", this);

    DAWN_TRY(mCapabilityCache->WithAdapterCapabilities(
        GetCurrentDevice()->GetAdapter(), this,
        [&](const PhysicalDeviceSurfaceCapabilities& caps) -> MaybeError {
            // The auto alphaMode default to alphaModes[0].
            if (config.alphaMode == wgpu::CompositeAlphaMode::Auto) {
                config.alphaMode = caps.alphaModes[0];
            }

            return ValidateSurfaceConfiguration(GetCurrentDevice(), caps, &config, this);
        }));

    // Reuse either the current swapchain, or the recycled swap chain
    SwapChainBase* previousSwapChain = mSwapChain.Get();
    if (previousSwapChain == nullptr && mRecycledSwapChain != nullptr &&
        mRecycledSwapChain->GetDevice() == config.device) {
        previousSwapChain = mRecycledSwapChain.Get();
    }

    {
        auto deviceGuard = GetCurrentDevice()->GetGuard();
        ResultOrError<Ref<SwapChainBase>> maybeNewSwapChain =
            GetCurrentDevice()->CreateSwapChain(this, previousSwapChain, &config);

        // Don't keep swap chains older than 1 call to Configure
        if (mRecycledSwapChain) {
            mRecycledSwapChain->DetachFromSurface();
            mRecycledSwapChain = nullptr;
        }

        if (mSwapChain && maybeNewSwapChain.IsSuccess()) {
            mSwapChain->DetachFromSurface();
        }
        DAWN_TRY_ASSIGN(mSwapChain, std::move(maybeNewSwapChain));

        mSwapChain->SetIsAttached();
    }

    return {};
}

MaybeError Surface::Unconfigure() {
    if (IsError()) {
        DAWN_CHECK(mSwapChain == nullptr);
        DAWN_CHECK(mCurrentDevice == nullptr);
        return DAWN_VALIDATION_ERROR("%s is invalid.", this);
    }
    mCurrentDevice = nullptr;
    DAWN_INVALID_IF(!mSwapChain.Get(), "%s is not configured.", this);

    if (mSwapChain != nullptr) {
        if (mRecycledSwapChain != nullptr) {
            mRecycledSwapChain->DetachFromSurface();
            mRecycledSwapChain = nullptr;
        }
        mRecycledSwapChain = mSwapChain;
        mSwapChain = nullptr;
    }

    return {};
}

MaybeError Surface::GetCapabilities(AdapterBase* adapter, SurfaceCapabilities* capabilities) const {
    DAWN_INVALID_IF(IsError(), "%s is invalid.", this);

    DAWN_TRY(mCapabilityCache->WithAdapterCapabilities(
        adapter, this,
        [&capabilities](const PhysicalDeviceSurfaceCapabilities& caps) -> MaybeError {
            capabilities->nextInChain = nullptr;
            capabilities->usages = caps.usages;
            capabilities->formats = utils::AllocateApiSeqFromStdVector(caps.formats);
            capabilities->presentModes = utils::AllocateApiSeqFromStdVector(caps.presentModes);
            capabilities->alphaModes = utils::AllocateApiSeqFromStdVector(caps.alphaModes);
            return {};
        }));

    return {};
}

void APISurfaceCapabilitiesFreeMembers(WGPUSurfaceCapabilities capabilities) {
    utils::FreeApiSeq(&capabilities.formats, &capabilities.formatCount);
    utils::FreeApiSeq(&capabilities.presentModes, &capabilities.presentModeCount);
    utils::FreeApiSeq(&capabilities.alphaModes, &capabilities.alphaModeCount);
}

MaybeError Surface::GetCurrentTexture(SurfaceTexture* surfaceTexture) const {
    surfaceTexture->texture = nullptr;

    // Set an error status that will be overwritten if there is a success or some other more
    // specific error.
    surfaceTexture->status = wgpu::SurfaceGetCurrentTextureStatus::Error;
    DAWN_INVALID_IF(IsError(), "%s is invalid.", this);
    DAWN_INVALID_IF(!mSwapChain.Get(), "%s is not configured.", this);

    if (GetCurrentDevice()->IsLost()) {
        TextureDescriptor textureDesc = GetSwapChainBaseTextureDescriptor(mSwapChain.Get());
        surfaceTexture->status = wgpu::SurfaceGetCurrentTextureStatus::SuccessOptimal;
        surfaceTexture->texture =
            ReturnToAPI(TextureBase::MakeError(GetCurrentDevice(), &textureDesc));
        return {};
    }

    auto deviceGuard = GetCurrentDevice()->GetGuard();
    DAWN_TRY_ASSIGN(*surfaceTexture, mSwapChain->GetCurrentTexture());

    return {};
}

const std::string& Surface::GetLabel() const {
    return mLabel;
}

void Surface::APIConfigure(const SurfaceConfiguration* config) {
    MaybeError maybeError = Configure(config);
    if (!GetCurrentDevice()) {
        [[maybe_unused]] bool error = mInstance->ConsumedError(std::move(maybeError));
    } else {
        [[maybe_unused]] bool error = GetCurrentDevice()->ConsumedError(
            std::move(maybeError), "calling %s.Configure().", this);
    }
}

wgpu::Status Surface::APIGetCapabilities(AdapterBase* adapter,
                                         SurfaceCapabilities* capabilities) const {
    MaybeError maybeError = GetCapabilities(adapter, capabilities);
    if (!GetCurrentDevice()) {
        return mInstance->ConsumedError(std::move(maybeError)) ? wgpu::Status::Error
                                                               : wgpu::Status::Success;
    } else {
        return GetCurrentDevice()->ConsumedError(std::move(maybeError), "calling %s.Configure().",
                                                 this)
                   ? wgpu::Status::Error
                   : wgpu::Status::Success;
    }
}

void Surface::APIGetCurrentTexture(SurfaceTexture* surfaceTexture) const {
    MaybeError maybeError = GetCurrentTexture(surfaceTexture);

    if (!GetCurrentDevice()) {
        [[maybe_unused]] bool error = mInstance->ConsumedError(std::move(maybeError));
    } else {
        [[maybe_unused]] bool error = GetCurrentDevice()->ConsumedError(std::move(maybeError));
    }
}

wgpu::Status Surface::APIPresent() {
    // Validation that the surface is configured. Note this is synchronous
    // validation so it can't be skipped even if the surface is an error.
    if (!GetCurrentDevice()) {
        [[maybe_unused]] bool error = mInstance->ConsumedError(
            DAWN_VALIDATION_ERROR("%s is in the unconfigured state.", this));
        return wgpu::Status::Error;
    }

    [[maybe_unused]] bool error = GetCurrentDevice()->ConsumedError([&]() -> MaybeError {
        DAWN_INVALID_IF(IsError(), "%s is invalid.", this);
        DAWN_INVALID_IF(!mSwapChain.Get(), "%s is not successfully configured.", this);
        {
            auto deviceGuard = GetCurrentDevice()->GetGuard();
            DAWN_TRY(mSwapChain->Present());
        }
        return {};
    }());
    return wgpu::Status::Success;
}

void Surface::APIUnconfigure() {
    MaybeError maybeError = Unconfigure();
    if (!GetCurrentDevice()) {
        [[maybe_unused]] bool error = mInstance->ConsumedError(std::move(maybeError));
    } else {
        [[maybe_unused]] bool error = GetCurrentDevice()->ConsumedError(std::move(maybeError));
    }
}

void Surface::APISetLabel(StringView label) {
    mLabel = utils::NormalizeMessageString(label);
}

}  // namespace dawn::native
