rev |
line source |
nuclear@1
|
1 /************************************************************************************
|
nuclear@1
|
2
|
nuclear@1
|
3 Filename : OVR_DeviceHandle.cpp
|
nuclear@1
|
4 Content : Implementation of device handle class
|
nuclear@1
|
5 Created : February 5, 2013
|
nuclear@1
|
6 Authors : Lee Cooper
|
nuclear@1
|
7
|
nuclear@1
|
8 Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
|
nuclear@1
|
9
|
nuclear@1
|
10 Use of this software is subject to the terms of the Oculus license
|
nuclear@1
|
11 agreement provided at the time of installation or download, or which
|
nuclear@1
|
12 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@1
|
13
|
nuclear@1
|
14 *************************************************************************************/
|
nuclear@1
|
15
|
nuclear@1
|
16 #include "OVR_DeviceHandle.h"
|
nuclear@1
|
17
|
nuclear@1
|
18 #include "OVR_DeviceImpl.h"
|
nuclear@1
|
19
|
nuclear@1
|
20 namespace OVR {
|
nuclear@1
|
21
|
nuclear@1
|
22 //-------------------------------------------------------------------------------------
|
nuclear@1
|
23 // ***** DeviceHandle
|
nuclear@1
|
24
|
nuclear@1
|
25 DeviceHandle::DeviceHandle(DeviceCreateDesc* impl) : pImpl(impl)
|
nuclear@1
|
26 {
|
nuclear@1
|
27 if (pImpl)
|
nuclear@1
|
28 pImpl->AddRef();
|
nuclear@1
|
29 }
|
nuclear@1
|
30
|
nuclear@1
|
31 DeviceHandle::DeviceHandle(const DeviceHandle& src) : pImpl(src.pImpl)
|
nuclear@1
|
32 {
|
nuclear@1
|
33 if (pImpl)
|
nuclear@1
|
34 pImpl->AddRef();
|
nuclear@1
|
35 }
|
nuclear@1
|
36
|
nuclear@1
|
37 DeviceHandle::~DeviceHandle()
|
nuclear@1
|
38 {
|
nuclear@1
|
39 if (pImpl)
|
nuclear@1
|
40 pImpl->Release();
|
nuclear@1
|
41 }
|
nuclear@1
|
42
|
nuclear@1
|
43 void DeviceHandle::operator = (const DeviceHandle& src)
|
nuclear@1
|
44 {
|
nuclear@1
|
45 if (src.pImpl)
|
nuclear@1
|
46 src.pImpl->AddRef();
|
nuclear@1
|
47 if (pImpl)
|
nuclear@1
|
48 pImpl->Release();
|
nuclear@1
|
49 pImpl = src.pImpl;
|
nuclear@1
|
50 }
|
nuclear@1
|
51
|
nuclear@1
|
52 DeviceBase* DeviceHandle::GetDevice_AddRef() const
|
nuclear@1
|
53 {
|
nuclear@1
|
54 if (pImpl && pImpl->pDevice)
|
nuclear@1
|
55 {
|
nuclear@1
|
56 pImpl->pDevice->AddRef();
|
nuclear@1
|
57 return pImpl->pDevice;
|
nuclear@1
|
58 }
|
nuclear@1
|
59 return NULL;
|
nuclear@1
|
60 }
|
nuclear@1
|
61
|
nuclear@1
|
62 // Returns true, if the handle contains the same device ptr
|
nuclear@1
|
63 // as specified in the parameter.
|
nuclear@1
|
64 bool DeviceHandle::IsDevice(DeviceBase* pdev) const
|
nuclear@1
|
65 {
|
nuclear@1
|
66 return (pdev && pImpl && pImpl->pDevice) ?
|
nuclear@1
|
67 pImpl->pDevice == pdev : false;
|
nuclear@1
|
68 }
|
nuclear@1
|
69
|
nuclear@1
|
70 DeviceType DeviceHandle::GetType() const
|
nuclear@1
|
71 {
|
nuclear@1
|
72 return pImpl ? pImpl->Type : Device_None;
|
nuclear@1
|
73 }
|
nuclear@1
|
74
|
nuclear@1
|
75 bool DeviceHandle::GetDeviceInfo(DeviceInfo* info) const
|
nuclear@1
|
76 {
|
nuclear@1
|
77 return pImpl ? pImpl->GetDeviceInfo(info) : false;
|
nuclear@1
|
78 }
|
nuclear@1
|
79 bool DeviceHandle::IsAvailable() const
|
nuclear@1
|
80 {
|
nuclear@1
|
81 // This isn't "atomically safe", but the function only returns the
|
nuclear@1
|
82 // recent state that may change.
|
nuclear@1
|
83 return pImpl ? (pImpl->Enumerated && pImpl->pLock->pManager) : false;
|
nuclear@1
|
84 }
|
nuclear@1
|
85
|
nuclear@1
|
86 bool DeviceHandle::IsCreated() const
|
nuclear@1
|
87 {
|
nuclear@1
|
88 return pImpl ? (pImpl->pDevice != 0) : false;
|
nuclear@1
|
89 }
|
nuclear@1
|
90
|
nuclear@1
|
91 DeviceBase* DeviceHandle::CreateDevice()
|
nuclear@1
|
92 {
|
nuclear@1
|
93 if (!pImpl)
|
nuclear@1
|
94 return 0;
|
nuclear@1
|
95
|
nuclear@1
|
96 DeviceBase* device = 0;
|
nuclear@1
|
97 Ptr<DeviceManagerImpl> manager= 0;
|
nuclear@1
|
98
|
nuclear@1
|
99 // Since both manager and device pointers can only be destroyed during a lock,
|
nuclear@1
|
100 // hold it while checking for availability.
|
nuclear@1
|
101 // AddRef to manager so that it doesn't get released on us.
|
nuclear@1
|
102 {
|
nuclear@1
|
103 Lock::Locker deviceLockScope(pImpl->GetLock());
|
nuclear@1
|
104
|
nuclear@1
|
105 if (pImpl->pDevice)
|
nuclear@1
|
106 {
|
nuclear@1
|
107 pImpl->pDevice->AddRef();
|
nuclear@1
|
108 return pImpl->pDevice;
|
nuclear@1
|
109 }
|
nuclear@1
|
110 manager = pImpl->GetManagerImpl();
|
nuclear@1
|
111 }
|
nuclear@1
|
112
|
nuclear@1
|
113 if (manager)
|
nuclear@1
|
114 {
|
nuclear@1
|
115 if (manager->GetThreadId() != OVR::GetCurrentThreadId())
|
nuclear@1
|
116 {
|
nuclear@1
|
117 // Queue up a CreateDevice request. This fills in '&device' with AddRefed value,
|
nuclear@1
|
118 // or keep it at null.
|
nuclear@1
|
119 manager->GetThreadQueue()->PushCallAndWaitResult(
|
nuclear@1
|
120 manager.GetPtr(), &DeviceManagerImpl::CreateDevice_MgrThread,
|
nuclear@1
|
121 &device, pImpl, (DeviceBase*)0);
|
nuclear@1
|
122 }
|
nuclear@1
|
123 else
|
nuclear@1
|
124 device = manager->CreateDevice_MgrThread(pImpl, (DeviceBase*)0);
|
nuclear@1
|
125 }
|
nuclear@1
|
126 return device;
|
nuclear@1
|
127 }
|
nuclear@1
|
128
|
nuclear@1
|
129 void DeviceHandle::Clear()
|
nuclear@1
|
130 {
|
nuclear@1
|
131 if (pImpl)
|
nuclear@1
|
132 {
|
nuclear@1
|
133 pImpl->Release();
|
nuclear@1
|
134 pImpl = 0;
|
nuclear@1
|
135 }
|
nuclear@1
|
136 }
|
nuclear@1
|
137
|
nuclear@1
|
138 bool DeviceHandle::enumerateNext(const DeviceEnumerationArgs& args)
|
nuclear@1
|
139 {
|
nuclear@1
|
140 if (GetType() == Device_None)
|
nuclear@1
|
141 return false;
|
nuclear@1
|
142
|
nuclear@1
|
143 Ptr<DeviceManagerImpl> managerKeepAlive;
|
nuclear@1
|
144 Lock::Locker lockScope(pImpl->GetLock());
|
nuclear@1
|
145
|
nuclear@1
|
146 DeviceCreateDesc* next = pImpl;
|
nuclear@1
|
147 // If manager was destroyed, we get removed from the list.
|
nuclear@1
|
148 if (!pImpl->pNext)
|
nuclear@1
|
149 return false;
|
nuclear@1
|
150
|
nuclear@1
|
151 managerKeepAlive = next->GetManagerImpl();
|
nuclear@1
|
152 OVR_ASSERT(managerKeepAlive);
|
nuclear@1
|
153
|
nuclear@1
|
154 do {
|
nuclear@1
|
155 next = next->pNext;
|
nuclear@1
|
156
|
nuclear@1
|
157 if (managerKeepAlive->Devices.IsNull(next))
|
nuclear@1
|
158 {
|
nuclear@1
|
159 pImpl->Release();
|
nuclear@1
|
160 pImpl = 0;
|
nuclear@1
|
161 return false;
|
nuclear@1
|
162 }
|
nuclear@1
|
163
|
nuclear@1
|
164 } while(!args.MatchRule(next->Type, next->Enumerated));
|
nuclear@1
|
165
|
nuclear@1
|
166 next->AddRef();
|
nuclear@1
|
167 pImpl->Release();
|
nuclear@1
|
168 pImpl = next;
|
nuclear@1
|
169
|
nuclear@1
|
170 return true;
|
nuclear@1
|
171 }
|
nuclear@1
|
172
|
nuclear@1
|
173 } // namespace OVR
|
nuclear@1
|
174
|