// Copyright 2018 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 "dawn/native/opengl/DeviceGL.h"

#include <utility>

#include "dawn/common/Log.h"
#include "dawn/native/BackendConnection.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/ErrorData.h"
#include "dawn/native/Instance.h"
#include "dawn/native/opengl/BindGroupGL.h"
#include "dawn/native/opengl/BindGroupLayoutGL.h"
#include "dawn/native/opengl/BufferGL.h"
#include "dawn/native/opengl/CommandBufferGL.h"
#include "dawn/native/opengl/ComputePipelineGL.h"
#include "dawn/native/opengl/ContextEGL.h"
#include "dawn/native/opengl/DisplayEGL.h"
#include "dawn/native/opengl/PhysicalDeviceGL.h"
#include "dawn/native/opengl/PipelineLayoutGL.h"
#include "dawn/native/opengl/QuerySetGL.h"
#include "dawn/native/opengl/QueueGL.h"
#include "dawn/native/opengl/RenderPipelineGL.h"
#include "dawn/native/opengl/SamplerGL.h"
#include "dawn/native/opengl/ShaderModuleGL.h"
#include "dawn/native/opengl/SharedFenceEGL.h"
#include "dawn/native/opengl/SharedTextureMemoryEGL.h"
#include "dawn/native/opengl/SwapChainEGL.h"
#include "dawn/native/opengl/TextureGL.h"
#include "dawn/native/opengl/UtilsGL.h"
#include "dawn/native/opengl/opengl_platform.h"

#if DAWN_PLATFORM_IS(ANDROID)
#include "dawn/native/AHBFunctions.h"
#endif  // DAWN_PLATFORM_IS(ANDROID)

namespace {

void KHRONOS_APIENTRY OnGLDebugMessage(GLenum source,
                                       GLenum type,
                                       GLuint id,
                                       GLenum severity,
                                       GLsizei length,
                                       const GLchar* message,
                                       const void* userParam) {
    const char* sourceText;
    switch (source) {
        case GL_DEBUG_SOURCE_API:
            sourceText = "OpenGL";
            break;
        case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
            sourceText = "Window System";
            break;
        case GL_DEBUG_SOURCE_SHADER_COMPILER:
            sourceText = "Shader Compiler";
            break;
        case GL_DEBUG_SOURCE_THIRD_PARTY:
            sourceText = "Third Party";
            break;
        case GL_DEBUG_SOURCE_APPLICATION:
            sourceText = "Application";
            break;
        case GL_DEBUG_SOURCE_OTHER:
            sourceText = "Other";
            break;
        default:
            sourceText = "UNKNOWN";
            break;
    }

    const char* severityText;
    switch (severity) {
        case GL_DEBUG_SEVERITY_HIGH:
            severityText = "High";
            break;
        case GL_DEBUG_SEVERITY_MEDIUM:
            severityText = "Medium";
            break;
        case GL_DEBUG_SEVERITY_LOW:
            severityText = "Low";
            break;
        case GL_DEBUG_SEVERITY_NOTIFICATION:
            severityText = "Notification";
            break;
        default:
            severityText = "UNKNOWN";
            break;
    }

    if (type == GL_DEBUG_TYPE_ERROR) {
        dawn::WarningLog() << "OpenGL error:" << "\n    Source: " << sourceText  //
                           << "\n    ID: " << id                                 //
                           << "\n    Severity: " << severityText                 //
                           << "\n    Message: " << message;

        // Abort on an error when in Debug mode.
        DAWN_UNREACHABLE();
    }
}

}  // anonymous namespace

namespace dawn::native::opengl {

// static
ResultOrError<Ref<Device>> Device::Create(AdapterBase* adapter,
                                          const UnpackedPtr<DeviceDescriptor>& descriptor,
                                          const OpenGLFunctions& functions,
                                          std::unique_ptr<ContextEGL> context,
                                          const TogglesState& deviceToggles,
                                          Ref<DeviceBase::DeviceLostEvent>&& lostEvent) {
    Ref<Device> device = AcquireRef(new Device(adapter, descriptor, functions, std::move(context),
                                               deviceToggles, std::move(lostEvent)));
    DAWN_TRY(device->Initialize(descriptor));
    return device;
}

Device::Device(AdapterBase* adapter,
               const UnpackedPtr<DeviceDescriptor>& descriptor,
               const OpenGLFunctions& functions,
               std::unique_ptr<ContextEGL> context,
               const TogglesState& deviceToggles,
               Ref<DeviceBase::DeviceLostEvent>&& lostEvent)
    : DeviceBase(adapter, descriptor, deviceToggles, std::move(lostEvent)),
      mGL(functions),
      mContext(std::move(context)) {}

Device::~Device() {
    Destroy(DestroyReason::CppDestructor);
}

MaybeError Device::Initialize(const UnpackedPtr<DeviceDescriptor>& descriptor) {
    // Directly set the context current and use mGL instead of calling GetGL as GetGL will notify
    // the (yet inexistent) queue that GL was used.
    ContextEGL::ScopedMakeCurrent scopedCurrentContext;
    DAWN_TRY_ASSIGN(scopedCurrentContext, mContext->MakeCurrent());
    mContext->RequestRequiredExtensionsExplicitly();

    const OpenGLFunctions& gl = mGL;

    mFormatTable = BuildGLFormatTable(gl);

    // Use the debug output functionality to get notified about GL errors
    // TODO(crbug.com/dawn/1475): add support for the KHR_debug and ARB_debug_output
    // extensions
    bool hasDebugOutput = gl.IsAtLeastGL(4, 3) || gl.IsAtLeastGLES(3, 2);

    if (GetAdapter()->GetInstance()->IsBackendValidationEnabled() && hasDebugOutput) {
        DAWN_GL_TRY(gl, Enable(GL_DEBUG_OUTPUT));
        DAWN_GL_TRY(gl, Enable(GL_DEBUG_OUTPUT_SYNCHRONOUS));

        // Any GL error; dangerous undefined behavior; any shader compiler and linker errors
        DAWN_GL_TRY(gl, DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
                                            nullptr, GL_TRUE));

        // Severe performance warnings; GLSL or other shader compiler and linker warnings;
        // use of currently deprecated behavior
        DAWN_GL_TRY(gl, DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0,
                                            nullptr, GL_TRUE));

        // Performance warnings from redundant state changes; trivial undefined behavior
        // This is disabled because we do an incredible amount of redundant state changes.
        DAWN_GL_TRY(gl, DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
                                            nullptr, GL_FALSE));

        // Any message which is not an error or performance concern
        DAWN_GL_TRY(gl, DebugMessageControl(GL_DONT_CARE, GL_DONT_CARE,
                                            GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE));
        DAWN_GL_TRY(gl, DebugMessageCallback(&OnGLDebugMessage, nullptr));
    }

    // Set initial state.
    DAWN_GL_TRY(gl, Enable(GL_DEPTH_TEST));
    DAWN_GL_TRY(gl, Enable(GL_SCISSOR_TEST));
    if (gl.GetVersion().IsDesktop()) {
        // These are not necessary on GLES. The functionality is enabled by default, and
        // works by specifying sample counts and SRGB textures, respectively.
        DAWN_GL_TRY(gl, Enable(GL_MULTISAMPLE));
        DAWN_GL_TRY(gl, Enable(GL_FRAMEBUFFER_SRGB));
    }
    DAWN_GL_TRY(gl, Enable(GL_SAMPLE_MASK));

    Ref<Queue> queue;
    DAWN_TRY_ASSIGN(queue, Queue::Create(this, &descriptor->defaultQueue));
    if (HasAnisotropicFiltering(gl)) {
        DAWN_GL_TRY(gl, GetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxTextureMaxAnisotropy));
    }

    DAWN_TRY(DeviceBase::Initialize(descriptor, std::move(queue)));

    // Create internal buffers needed for workarounds.
    if (mTextureBuiltinsBuffer.Get() == nullptr) {
        BufferDescriptor desc = {};
        // The uniform buffer will contain an array of vec4u so make sure that it contains the last
        // possible vec4u entirely by rounding the size to 4 u32s. Check that the constant is indeed
        // a multiple of 4.
        static_assert(kGLMaxTextureImageUnitsReported % 4 == 0);
        desc.size = kGLMaxTextureImageUnitsReported * sizeof(uint32_t);
        desc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
        Ref<BufferBase> buffer;
        DAWN_TRY_ASSIGN(buffer, Buffer::CreateInternalBuffer(this, &desc, false));
        mTextureBuiltinsBuffer = ToBackend(std::move(buffer));
    }

    if (IsToggleEnabled(Toggle::GLUseArrayLengthFromUniform) &&
        mArrayLengthBuffer.Get() == nullptr) {
        BufferDescriptor desc = {};
        desc.size = kGLMaxShaderStorageBufferBindingsReported * sizeof(uint32_t);
        desc.usage = wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst;
        Ref<BufferBase> buffer;
        DAWN_TRY_ASSIGN(buffer, Buffer::CreateInternalBuffer(this, &desc, false));
        mArrayLengthBuffer = ToBackend(std::move(buffer));
    }

    return scopedCurrentContext.End();
}

const GLFormat& Device::GetGLFormat(const Format& format) {
    DAWN_ASSERT(format.IsSupported());
    DAWN_ASSERT(format.GetIndex() < mFormatTable.size());

    const GLFormat& result = mFormatTable[format.GetIndex()];
    DAWN_ASSERT(result.isSupportedOnBackend);
    return result;
}

ResultOrError<Ref<BindGroupBase>> Device::CreateBindGroupImpl(
    const UnpackedPtr<BindGroupDescriptor>& descriptor) {
    return BindGroup::Create(this, descriptor);
}
ResultOrError<Ref<BindGroupLayoutInternalBase>> Device::CreateBindGroupLayoutImpl(
    const UnpackedPtr<BindGroupLayoutDescriptor>& descriptor) {
    return AcquireRef(new BindGroupLayout(this, descriptor));
}
ResultOrError<Ref<BufferBase>> Device::CreateBufferImpl(
    const UnpackedPtr<BufferDescriptor>& descriptor) {
    return Buffer::Create(this, descriptor);
}
ResultOrError<Ref<CommandBufferBase>> Device::CreateCommandBuffer(
    CommandEncoder* encoder,
    const CommandBufferDescriptor* descriptor) {
    return AcquireRef(new CommandBuffer(encoder, descriptor));
}
Ref<ComputePipelineBase> Device::CreateUninitializedComputePipelineImpl(
    const UnpackedPtr<ComputePipelineDescriptor>& descriptor) {
    return ComputePipeline::CreateUninitialized(this, descriptor);
}
ResultOrError<Ref<PipelineLayoutBase>> Device::CreatePipelineLayoutImpl(
    const UnpackedPtr<PipelineLayoutDescriptor>& descriptor) {
    return AcquireRef(new PipelineLayout(this, descriptor));
}
ResultOrError<Ref<QuerySetBase>> Device::CreateQuerySetImpl(const QuerySetDescriptor* descriptor) {
    return QuerySet::Create(this, descriptor);
}
Ref<RenderPipelineBase> Device::CreateUninitializedRenderPipelineImpl(
    const UnpackedPtr<RenderPipelineDescriptor>& descriptor) {
    return RenderPipeline::CreateUninitialized(this, descriptor);
}
ResultOrError<Ref<ResourceTableBase>> Device::CreateResourceTableImpl(
    const ResourceTableDescriptor* descriptor) {
    return DAWN_UNIMPLEMENTED_ERROR("ResourceTable is not supported on OpenGL");
}
ResultOrError<Ref<SamplerBase>> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
    return Sampler::Create(this, descriptor);
}
ResultOrError<Ref<ShaderModuleBase>> Device::CreateShaderModuleImpl(
    const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
    const std::vector<tint::wgsl::Extension>& internalExtensions) {
    return ShaderModule::Create(this, descriptor, internalExtensions);
}
ResultOrError<Ref<SwapChainBase>> Device::CreateSwapChainImpl(Surface* surface,
                                                              SwapChainBase* previousSwapChain,
                                                              const SurfaceConfiguration* config) {
    return SwapChainEGL::Create(this, surface, previousSwapChain, config);
}
ResultOrError<Ref<TextureBase>> Device::CreateTextureImpl(
    const UnpackedPtr<TextureDescriptor>& descriptor) {
    return Texture::Create(this, descriptor);
}
ResultOrError<Ref<TextureViewBase>> Device::CreateTextureViewImpl(
    TextureBase* texture,
    const UnpackedPtr<TextureViewDescriptor>& descriptor) {
    return TextureView::Create(texture, descriptor);
}

ResultOrError<Ref<SharedTextureMemoryBase>> Device::ImportSharedTextureMemoryImpl(
    const SharedTextureMemoryDescriptor* descriptor) {
    UnpackedPtr<SharedTextureMemoryDescriptor> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(descriptor));

    wgpu::SType type;
    DAWN_TRY_ASSIGN(
        type, (unpacked.ValidateBranches<Branch<SharedTextureMemoryAHardwareBufferDescriptor>>()));

    switch (type) {
        case wgpu::SType::SharedTextureMemoryAHardwareBufferDescriptor:
            DAWN_INVALID_IF(!HasFeature(Feature::SharedTextureMemoryAHardwareBuffer),
                            "%s is not enabled.",
                            wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer);
            return SharedTextureMemoryEGL::Create(
                this, descriptor->label,
                unpacked.Get<SharedTextureMemoryAHardwareBufferDescriptor>());
        default:
            DAWN_UNREACHABLE();
    }
}

ResultOrError<Ref<SharedFenceBase>> Device::ImportSharedFenceImpl(
    const SharedFenceDescriptor* descriptor) {
    UnpackedPtr<SharedFenceDescriptor> unpacked;
    DAWN_TRY_ASSIGN(unpacked, ValidateAndUnpack(descriptor));

    wgpu::SType type;
    DAWN_TRY_ASSIGN(type, (unpacked.ValidateBranches<Branch<SharedFenceSyncFDDescriptor>,
                                                     Branch<SharedFenceEGLSyncDescriptor>>()));

    switch (type) {
        case wgpu::SType::SharedFenceSyncFDDescriptor:
            DAWN_INVALID_IF(!HasFeature(Feature::SharedFenceSyncFD), "%s is not enabled.",
                            wgpu::FeatureName::SharedFenceSyncFD);
            return SharedFenceEGL::Create(this, descriptor->label,
                                          unpacked.Get<SharedFenceSyncFDDescriptor>());
        case wgpu::SType::SharedFenceEGLSyncDescriptor:
            DAWN_INVALID_IF(!HasFeature(Feature::SharedFenceEGLSync), "%s is not enabled.",
                            wgpu::FeatureName::SharedFenceEGLSync);
            return SharedFenceEGL::Create(this, descriptor->label,
                                          unpacked.Get<SharedFenceEGLSyncDescriptor>());
        default:
            DAWN_UNREACHABLE();
    }
}

MaybeError Device::ValidateTextureCanBeWrapped(const UnpackedPtr<TextureDescriptor>& descriptor) {
    DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D,
                    "Texture dimension (%s) is not %s.", descriptor->dimension,
                    wgpu::TextureDimension::e2D);

    DAWN_INVALID_IF(descriptor->mipLevelCount != 1, "Mip level count (%u) is not 1.",
                    descriptor->mipLevelCount);

    DAWN_INVALID_IF(descriptor->size.depthOrArrayLayers != 1, "Array layer count (%u) is not 1.",
                    descriptor->size.depthOrArrayLayers);

    DAWN_INVALID_IF(descriptor->sampleCount != 1, "Sample count (%u) is not 1.",
                    descriptor->sampleCount);

    return {};
}

Ref<TextureBase> Device::CreateTextureWrappingEGLImage(const ExternalImageDescriptor* descriptor,
                                                       ::EGLImage image) {
    Ref<TextureBase> result;
    if (ConsumedError(CreateTextureWrappingEGLImageImpl(descriptor, image), &result,
                      "calling %s.CreateTextureWrappingEGLImage(%s).", this, descriptor)) {
        return nullptr;
    }
    return result;
}

ResultOrError<Ref<TextureBase>> Device::CreateTextureWrappingEGLImageImpl(
    const ExternalImageDescriptor* descriptor,
    ::EGLImage image) {
    // TODO(451928481): We cannot defer the GL work here because the external texture may be
    // deleted after this method returns. In the future, we should deprecate this method and
    // require clients to use SharedTextureMemory for better lifetime management.
    ContextEGL::ScopedMakeCurrent scopedCurrentContext;
    DAWN_TRY_ASSIGN(scopedCurrentContext, mContext->MakeCurrent());
    const OpenGLFunctions& gl = GetGL(/*makeCurrent=*/false);

    TextureDescriptor reifiedDescriptor =
        FromAPI(descriptor->cTextureDescriptor)->WithTrivialFrontendDefaults();
    UnpackedPtr<TextureDescriptor> textureDescriptor;
    DAWN_TRY_ASSIGN(textureDescriptor, ValidateAndUnpack(&reifiedDescriptor));
    DAWN_TRY(ValidateTextureDescriptor(this, textureDescriptor));
    DAWN_TRY(ValidateTextureCanBeWrapped(textureDescriptor));
    // The EGLImage was created from outside of Dawn so it must be on the same display that was
    // provided to create the device. The best check we can do is that we indeed have
    // EGL_KHR_image_base.
    DAWN_ASSERT(GetEGL(false).HasExt(EGLExt::ImageBase));

    GLuint tex;
    DAWN_GL_TRY(gl, GenTextures(1, &tex));
    DAWN_GL_TRY(gl, BindTexture(GL_TEXTURE_2D, tex));
    DAWN_GL_TRY(gl, EGLImageTargetTexture2DOES(GL_TEXTURE_2D, image));
    DAWN_GL_TRY(gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));

    GLint width, height;
    DAWN_GL_TRY(gl, GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width));
    DAWN_GL_TRY(gl, GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height));

    if (textureDescriptor->size.width != static_cast<uint32_t>(width) ||
        textureDescriptor->size.height != static_cast<uint32_t>(height) ||
        textureDescriptor->size.depthOrArrayLayers != 1) {
        DAWN_GL_TRY(gl, DeleteTextures(1, &tex));

        return DAWN_VALIDATION_ERROR(
            "EGLImage size (width: %u, height: %u, depth: 1) doesn't match descriptor size %s.",
            width, height, textureDescriptor->size);
    }

    // TODO(dawn:803): Validate the OpenGL texture format from the EGLImage against the format
    // in the passed-in TextureDescriptor.
    auto result = AcquireRef(new Texture(this, textureDescriptor, tex, OwnsHandle::No));
    result->SetIsSubresourceContentInitialized(descriptor->isInitialized,
                                               result->GetAllSubresources());

    DAWN_TRY(scopedCurrentContext.End());

    return result;
}

Ref<TextureBase> Device::CreateTextureWrappingGLTexture(const ExternalImageDescriptor* descriptor,
                                                        GLuint texture) {
    Ref<TextureBase> result;
    if (ConsumedError(CreateTextureWrappingGLTextureImpl(descriptor, texture), &result,
                      "calling %s.CreateTextureWrappingGLTexture(%s).", this, descriptor)) {
        return nullptr;
    }
    return result;
}

ResultOrError<Ref<TextureBase>> Device::CreateTextureWrappingGLTextureImpl(
    const ExternalImageDescriptor* descriptor,
    GLuint texture) {
    // TODO(451928481): We cannot defer the GL work here because the external texture may be
    // deleted after this method returns. In the future, we should deprecate this method and
    // require clients to use SharedTextureMemory for better lifetime management.
    ContextEGL::ScopedMakeCurrent scopedCurrentContext;
    DAWN_TRY_ASSIGN(scopedCurrentContext, mContext->MakeCurrent());
    const OpenGLFunctions& gl = GetGL(/*makeCurrent=*/false);

    TextureDescriptor reifiedDescriptor =
        FromAPI(descriptor->cTextureDescriptor)->WithTrivialFrontendDefaults();
    UnpackedPtr<TextureDescriptor> textureDescriptor;
    DAWN_TRY_ASSIGN(textureDescriptor, ValidateAndUnpack(&reifiedDescriptor));
    DAWN_TRY(ValidateTextureDescriptor(this, textureDescriptor));
    if (!HasFeature(Feature::ANGLETextureSharing)) {
        return DAWN_VALIDATION_ERROR("Device does not support ANGLE GL texture sharing.");
    }
    DAWN_TRY(ValidateTextureCanBeWrapped(textureDescriptor));

    DAWN_GL_TRY(gl, BindTexture(GL_TEXTURE_2D, texture));

    GLint width, height;
    DAWN_GL_TRY(gl, GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width));
    DAWN_GL_TRY(gl, GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height));

    if (textureDescriptor->size.width != static_cast<uint32_t>(width) ||
        textureDescriptor->size.height != static_cast<uint32_t>(height) ||
        textureDescriptor->size.depthOrArrayLayers != 1) {
        return DAWN_VALIDATION_ERROR(
            "GL texture size (width: %u, height: %u, depth: 1) doesn't match descriptor size %s.",
            width, height, textureDescriptor->size);
    }

    auto result = AcquireRef(new Texture(this, textureDescriptor, texture, OwnsHandle::No));
    result->SetIsSubresourceContentInitialized(descriptor->isInitialized,
                                               result->GetAllSubresources());

    DAWN_TRY(scopedCurrentContext.End());

    return result;
}

MaybeError Device::TickImpl() {
    DAWN_TRY(ToBackend(GetQueue())->SubmitFenceSync());
    return {};
}

MaybeError Device::FlushPendingGLCommands() {
    std::vector<GLWorkFunc> workList;
    mPendingGLWorkList.Use([&](auto pendingList) { std::swap(workList, *pendingList); });

    if (workList.empty()) {
        return {};
    }

    ContextEGL::ScopedMakeCurrent scopedCurrentContext;
    DAWN_TRY_ASSIGN(scopedCurrentContext, mContext->MakeCurrent());
    MarkGLUsed(ExecutionQueueBase::SubmitMode::Normal);
    for (auto& work : workList) {
        DAWN_TRY(work(mGL));
    }
    return scopedCurrentContext.End();
}

MaybeError Device::CopyFromStagingToBuffer(BufferBase* source,
                                           uint64_t sourceOffset,
                                           BufferBase* destination,
                                           uint64_t destinationOffset,
                                           uint64_t size) {
    return DAWN_UNIMPLEMENTED_ERROR("Device unable to copy from staging buffer.");
}

MaybeError Device::CopyFromStagingToTextureImpl(BufferBase* source,
                                                const TexelCopyBufferLayout& src,
                                                const TextureCopy& dst,
                                                const Extent3D& copySizePixels) {
    // If implemented, be sure to call SynchronizeTextureBeforeUse on the destination texture.
    return DAWN_UNIMPLEMENTED_ERROR("Device unable to copy from staging buffer to texture.");
}

void Device::DestroyImpl(DestroyReason reason) {
    DAWN_ASSERT(GetState() == State::Disconnected);

    mTextureBuiltinsBuffer = nullptr;
    mArrayLengthBuffer = nullptr;
}

void Device::MarkGLUsed(ExecutionQueueBase::SubmitMode submitMode) const {
    if (submitMode == ExecutionQueueBase::SubmitMode::Normal) {
        // - Only need fence sync if submit mode is normal. So the commands will be flushed and a
        // fence is inserted in next Tick().
        // - For passive mode, the commands will eventually be flushed in Queue::Submit().
        ToBackend(GetQueue())->SetNeedsFenceSync();
    }
}

uint32_t Device::GetOptimalBytesPerRowAlignment() const {
    return 1;
}

uint64_t Device::GetOptimalBufferToTextureCopyOffsetAlignment() const {
    return 1;
}

float Device::GetTimestampPeriodInNS() const {
    return 1.0f;
}

bool Device::MayRequireDuplicationOfIndirectParameters() const {
    return true;
}

bool Device::ShouldApplyIndexBufferOffsetToFirstIndex() const {
    return true;
}

const AHBFunctions* Device::GetOrLoadAHBFunctions() {
#if DAWN_PLATFORM_IS(ANDROID)
    if (mAHBFunctions == nullptr) {
        mAHBFunctions = std::make_unique<AHBFunctions>();
    }
    return mAHBFunctions.get();
#else
    DAWN_UNREACHABLE();
#endif  // DAWN_PLATFORM_IS(ANDROID)
}

const OpenGLFunctions& Device::GetGL(bool makeCurrent) const {
    if (makeCurrent) {
        mContext->DeprecatedMakeCurrent();
    }
    MarkGLUsed(ExecutionQueueBase::SubmitMode::Normal);
    return mGL;
}

int Device::GetMaxTextureMaxAnisotropy() const {
    return mMaxTextureMaxAnisotropy;
}

const EGLFunctions& Device::GetEGL(bool makeCurrent) const {
    if (makeCurrent) {
        mContext->DeprecatedMakeCurrent();
        MarkGLUsed(ExecutionQueueBase::SubmitMode::Normal);
    }
    return ToBackend(GetPhysicalDevice())->GetDisplay()->egl.get();
}

EGLDisplay Device::GetEGLDisplay() const {
    return ToBackend(GetPhysicalDevice())->GetDisplay()->GetDisplay();
}

ContextEGL* Device::GetContext() const {
    return mContext.get();
}

const Buffer* Device::GetInternalTextureBuiltinsUniformBuffer() const {
    return mTextureBuiltinsBuffer.Get();
}

const Buffer* Device::GetInternalArrayLengthUniformBuffer() const {
    return mArrayLengthBuffer.Get();
}

}  // namespace dawn::native::opengl
