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

// Device.cpp: Implements the egl::Device class, representing the abstract
// device. Implements EGLDevice.

#include "libANGLE/Device.h"

#include <iterator>

#include <EGL/eglext.h>
#include <platform/Platform.h>

#include "common/debug.h"
#include "common/platform.h"
#include "libANGLE/renderer/DeviceImpl.h"

#if defined(ANGLE_ENABLE_D3D11)
#    include "libANGLE/renderer/d3d/DeviceD3D.h"
#endif

namespace egl
{

template <typename T>
static std::string GenerateExtensionsString(const T &extensions)
{
    std::vector<std::string> extensionsVector = extensions.getStrings();

    std::ostringstream stream;
    std::copy(extensionsVector.begin(), extensionsVector.end(),
              std::ostream_iterator<std::string>(stream, " "));
    return stream.str();
}

typedef std::set<egl::Device *> DeviceSet;
static DeviceSet *GetDeviceSet()
{
    static DeviceSet devices;
    return &devices;
}

// Static factory methods
egl::Error Device::CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice)
{
    *outDevice = nullptr;

    std::unique_ptr<rx::DeviceImpl> newDeviceImpl;

#if defined(ANGLE_ENABLE_D3D11)
    if (deviceType == EGL_D3D11_DEVICE_ANGLE)
    {
        newDeviceImpl.reset(new rx::DeviceD3D(deviceType, nativeDevice));
    }
#endif

    // Note that creating an EGL device from inputted D3D9 parameters isn't currently supported

    if (newDeviceImpl == nullptr)
    {
        return EglBadAttribute();
    }

    ANGLE_TRY(newDeviceImpl->initialize());
    *outDevice = new Device(nullptr, newDeviceImpl.release());

    return NoError();
}

bool Device::IsValidDevice(const Device *device)
{
    const DeviceSet *deviceSet = GetDeviceSet();
    return deviceSet->find(const_cast<Device *>(device)) != deviceSet->end();
}

Device::Device(Display *owningDisplay, rx::DeviceImpl *impl)
    : mLabel(nullptr), mOwningDisplay(owningDisplay), mImplementation(impl)
{
    ASSERT(GetDeviceSet()->find(this) == GetDeviceSet()->end());
    GetDeviceSet()->insert(this);
    initDeviceExtensions();
}

Device::~Device()
{
    ASSERT(GetDeviceSet()->find(this) != GetDeviceSet()->end());
    GetDeviceSet()->erase(this);
}

void Device::setLabel(EGLLabelKHR label)
{
    mLabel = label;
}

EGLLabelKHR Device::getLabel() const
{
    return mLabel;
}

Error Device::getDevice(EGLAttrib *value)
{
    void *nativeDevice = nullptr;
    egl::Error error   = getImplementation()->getDevice(&nativeDevice);
    *value             = reinterpret_cast<EGLAttrib>(nativeDevice);
    return error;
}

EGLint Device::getType()
{
    return getImplementation()->getType();
}

void Device::initDeviceExtensions()
{
    mImplementation->generateExtensions(&mDeviceExtensions);
    mDeviceExtensionString = GenerateExtensionsString(mDeviceExtensions);
}

const DeviceExtensions &Device::getExtensions() const
{
    return mDeviceExtensions;
}

const std::string &Device::getExtensionString() const
{
    return mDeviceExtensionString;
}
}  // namespace egl
