summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/Device.cpp
blob: 3ebf48b919cf5cea8e4f6f89f2b08ca9dabba8e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//
// 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 <platform/Platform.h>
#include <EGL/eglext.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(void *devicePointer, EGLint deviceType, Device **outDevice)
{
    *outDevice = nullptr;

#if defined(ANGLE_ENABLE_D3D11)
    if (deviceType == EGL_D3D11_DEVICE_ANGLE)
    {
        std::unique_ptr<rx::DeviceD3D> deviceD3D(new rx::DeviceD3D());
        ANGLE_TRY(deviceD3D->initialize(devicePointer, deviceType, EGL_TRUE));
        *outDevice = new Device(nullptr, deviceD3D.release());
        GetDeviceSet()->insert(*outDevice);
        return NoError();
    }
#endif

    // Note that creating an EGL device from inputted D3D9 parameters isn't currently supported
    return EglBadAttribute();
}

egl::Error Device::CreateDevice(Display *owningDisplay, rx::DeviceImpl *impl, Device **outDevice)
{
    *outDevice = new Device(owningDisplay, impl);
    GetDeviceSet()->insert(*outDevice);
    return NoError();
}

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

Device::Device(Display *owningDisplay, rx::DeviceImpl *impl)
    : mOwningDisplay(owningDisplay), mImplementation(impl)
{
    initDeviceExtensions();
}

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

    if (mImplementation->deviceExternallySourced())
    {
        // If the device isn't externally sourced then it is up to the renderer to delete the impl
        SafeDelete(mImplementation);
    }
}

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;
}

}