1 //
2 // Copyright (c) 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 // DeviceD3D.cpp: D3D implementation of egl::Device
8 
9 #include "libANGLE/renderer/d3d/DeviceD3D.h"
10 #include "libANGLE/renderer/d3d/RendererD3D.h"
11 
12 #include "libANGLE/Device.h"
13 #include "libANGLE/Display.h"
14 
15 #include <EGL/eglext.h>
16 
17 namespace rx
18 {
19 
DeviceD3D()20 DeviceD3D::DeviceD3D()
21     : mDevice(0), mDeviceType(0), mDeviceExternallySourced(false), mIsInitialized(false)
22 {
23 }
24 
~DeviceD3D()25 DeviceD3D::~DeviceD3D()
26 {
27 #if defined(ANGLE_ENABLE_D3D11)
28     if (mDeviceType == EGL_D3D11_DEVICE_ANGLE)
29     {
30         // DeviceD3D holds a ref to an externally-sourced D3D11 device. We must release it.
31         ID3D11Device *device = reinterpret_cast<ID3D11Device *>(mDevice);
32         device->Release();
33     }
34 #endif
35 }
36 
getDevice(void ** outValue)37 egl::Error DeviceD3D::getDevice(void **outValue)
38 {
39     if (!mIsInitialized)
40     {
41         *outValue = nullptr;
42         return egl::EglBadDevice();
43     }
44 
45     *outValue = mDevice;
46     return egl::NoError();
47 }
48 
initialize(void * device,EGLint deviceType,EGLBoolean deviceExternallySourced)49 egl::Error DeviceD3D::initialize(void *device,
50                                  EGLint deviceType,
51                                  EGLBoolean deviceExternallySourced)
52 {
53     ASSERT(!mIsInitialized);
54     if (mIsInitialized)
55     {
56         return egl::EglBadDevice();
57     }
58 
59 #if defined(ANGLE_ENABLE_D3D11)
60     if (deviceType == EGL_D3D11_DEVICE_ANGLE)
61     {
62         // Validate the device
63         IUnknown *iunknown = reinterpret_cast<IUnknown *>(device);
64 
65         ID3D11Device *d3dDevice = nullptr;
66         HRESULT hr =
67             iunknown->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast<void **>(&d3dDevice));
68         if (FAILED(hr))
69         {
70             return egl::EglBadAttribute() << "Invalid D3D device passed into EGLDeviceEXT";
71         }
72 
73         // The QI to ID3D11Device adds a ref to the D3D11 device.
74         // Deliberately don't release the ref here, so that the DeviceD3D holds a ref to the
75         // D3D11 device.
76     }
77     else
78 #endif
79     {
80         ASSERT(deviceExternallySourced == EGL_FALSE);
81     }
82 
83     mDevice                  = device;
84     mDeviceType              = deviceType;
85     mDeviceExternallySourced = !!deviceExternallySourced;
86     mIsInitialized           = true;
87 
88     return egl::NoError();
89 }
90 
getType()91 EGLint DeviceD3D::getType()
92 {
93     return mDeviceType;
94 }
95 
generateExtensions(egl::DeviceExtensions * outExtensions) const96 void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const
97 {
98     outExtensions->deviceD3D = true;
99 }
100 
deviceExternallySourced()101 bool DeviceD3D::deviceExternallySourced()
102 {
103     return mDeviceExternallySourced;
104 }
105 }
106