1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Device.cpp: Implements the egl::Device class, representing the abstract
8 // device. Implements EGLDevice.
9
10 #include "libANGLE/Device.h"
11
12 #include <iterator>
13
14 #include <EGL/eglext.h>
15 #include <platform/PlatformMethods.h>
16
17 #include "anglebase/no_destructor.h"
18 #include "common/debug.h"
19 #include "common/platform.h"
20 #include "libANGLE/renderer/DeviceImpl.h"
21
22 #if defined(ANGLE_ENABLE_D3D11)
23 # include "libANGLE/renderer/d3d/d3d11/Device11.h"
24 #endif
25
26 namespace egl
27 {
28
29 template <typename T>
GenerateExtensionsString(const T & extensions)30 static std::string GenerateExtensionsString(const T &extensions)
31 {
32 std::vector<std::string> extensionsVector = extensions.getStrings();
33
34 std::ostringstream stream;
35 std::copy(extensionsVector.begin(), extensionsVector.end(),
36 std::ostream_iterator<std::string>(stream, " "));
37 return stream.str();
38 }
39
40 typedef std::set<egl::Device *> DeviceSet;
GetDeviceSet()41 static DeviceSet *GetDeviceSet()
42 {
43 static angle::base::NoDestructor<DeviceSet> devices;
44 return devices.get();
45 }
46
47 // Static factory methods
CreateDevice(EGLint deviceType,void * nativeDevice,Device ** outDevice)48 egl::Error Device::CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice)
49 {
50 *outDevice = nullptr;
51
52 std::unique_ptr<rx::DeviceImpl> newDeviceImpl;
53
54 #if defined(ANGLE_ENABLE_D3D11)
55 if (deviceType == EGL_D3D11_DEVICE_ANGLE)
56 {
57 newDeviceImpl.reset(new rx::Device11(nativeDevice));
58 }
59 #endif
60
61 // Note that creating an EGL device from inputted D3D9 parameters isn't currently supported
62
63 if (newDeviceImpl == nullptr)
64 {
65 return EglBadAttribute();
66 }
67
68 ANGLE_TRY(newDeviceImpl->initialize());
69 *outDevice = new Device(nullptr, newDeviceImpl.release());
70
71 return NoError();
72 }
73
IsValidDevice(const Device * device)74 bool Device::IsValidDevice(const Device *device)
75 {
76 const DeviceSet *deviceSet = GetDeviceSet();
77 return deviceSet->find(const_cast<Device *>(device)) != deviceSet->end();
78 }
79
Device(Display * owningDisplay,rx::DeviceImpl * impl)80 Device::Device(Display *owningDisplay, rx::DeviceImpl *impl)
81 : mLabel(nullptr), mOwningDisplay(owningDisplay), mImplementation(impl)
82 {
83 ASSERT(GetDeviceSet()->find(this) == GetDeviceSet()->end());
84 GetDeviceSet()->insert(this);
85 initDeviceExtensions();
86 }
87
~Device()88 Device::~Device()
89 {
90 ASSERT(GetDeviceSet()->find(this) != GetDeviceSet()->end());
91 GetDeviceSet()->erase(this);
92 }
93
setLabel(EGLLabelKHR label)94 void Device::setLabel(EGLLabelKHR label)
95 {
96 mLabel = label;
97 }
98
getLabel() const99 EGLLabelKHR Device::getLabel() const
100 {
101 return mLabel;
102 }
103
getAttribute(EGLint attribute,EGLAttrib * value)104 Error Device::getAttribute(EGLint attribute, EGLAttrib *value)
105 {
106 void *nativeAttribute = nullptr;
107 egl::Error error =
108 getImplementation()->getAttribute(getOwningDisplay(), attribute, &nativeAttribute);
109 *value = reinterpret_cast<EGLAttrib>(nativeAttribute);
110 return error;
111 }
112
initDeviceExtensions()113 void Device::initDeviceExtensions()
114 {
115 mImplementation->generateExtensions(&mDeviceExtensions);
116 mDeviceExtensionString = GenerateExtensionsString(mDeviceExtensions);
117 }
118
getExtensions() const119 const DeviceExtensions &Device::getExtensions() const
120 {
121 return mDeviceExtensions;
122 }
123
getExtensionString() const124 const std::string &Device::getExtensionString() const
125 {
126 return mDeviceExtensionString;
127 }
128
getDeviceString(EGLint name)129 const std::string &Device::getDeviceString(EGLint name)
130 {
131 if (mDeviceStrings.find(name) == mDeviceStrings.end())
132 {
133 mDeviceStrings.emplace(name, mImplementation.get()->getDeviceString(name));
134 }
135
136 return mDeviceStrings.find(name)->second;
137 }
138 } // namespace egl
139