Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "OVR_Linux_DeviceManager.h"
00017
00018
00019 #include "OVR_LatencyTestImpl.h"
00020 #include "OVR_SensorImpl.h"
00021 #include "OVR_Linux_HIDDevice.h"
00022 #include "OVR_Linux_HMDDevice.h"
00023
00024 #include "Kernel/OVR_Timer.h"
00025 #include "Kernel/OVR_Std.h"
00026 #include "Kernel/OVR_Log.h"
00027
00028 namespace OVR { namespace Linux {
00029
00030
00031
00032
00033
00034 DeviceManager::DeviceManager()
00035 {
00036 }
00037
00038 DeviceManager::~DeviceManager()
00039 {
00040 }
00041
00042 bool DeviceManager::Initialize(DeviceBase*)
00043 {
00044 if (!DeviceManagerImpl::Initialize(0))
00045 return false;
00046
00047 pThread = *new DeviceManagerThread();
00048 if (!pThread || !pThread->Start())
00049 return false;
00050
00051
00052 pThread->StartupEvent.Wait();
00053
00054
00055 HidDeviceManager = *HIDDeviceManager::CreateInternal(this);
00056
00057 pCreateDesc->pDevice = this;
00058 LogText("OVR::DeviceManager - initialized.\n");
00059 return true;
00060 }
00061
00062 void DeviceManager::Shutdown()
00063 {
00064 LogText("OVR::DeviceManager - shutting down.\n");
00065
00066
00067
00068 pCreateDesc->pLock->pManager = 0;
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 pThread->PushExitCommand(false);
00080 pThread.Clear();
00081
00082 DeviceManagerImpl::Shutdown();
00083 }
00084
00085 ThreadCommandQueue* DeviceManager::GetThreadQueue()
00086 {
00087 return pThread;
00088 }
00089
00090 ThreadId DeviceManager::GetThreadId() const
00091 {
00092 return pThread->GetThreadId();
00093 }
00094
00095 bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const
00096 {
00097 if ((info->InfoClassType != Device_Manager) &&
00098 (info->InfoClassType != Device_None))
00099 return false;
00100
00101 info->Type = Device_Manager;
00102 info->Version = 0;
00103 OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, "DeviceManager");
00104 OVR_strcpy(info->Manufacturer,DeviceInfo::MaxNameLength, "Oculus VR, Inc.");
00105 return true;
00106 }
00107
00108 DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args)
00109 {
00110
00111 pThread->PushCall((DeviceManagerImpl*)this,
00112 &DeviceManager::EnumerateAllFactoryDevices, true);
00113
00114 return DeviceManagerImpl::EnumerateDevicesEx(args);
00115 }
00116
00117
00118
00119
00120
00121 DeviceManagerThread::DeviceManagerThread()
00122 : Thread(ThreadStackSize)
00123 {
00124 int result = pipe(CommandFd);
00125 OVR_ASSERT(!result);
00126
00127 AddSelectFd(NULL, CommandFd[0]);
00128 }
00129
00130 DeviceManagerThread::~DeviceManagerThread()
00131 {
00132 if (CommandFd[0])
00133 {
00134 RemoveSelectFd(NULL, CommandFd[0]);
00135 close(CommandFd[0]);
00136 close(CommandFd[1]);
00137 }
00138 }
00139
00140 bool DeviceManagerThread::AddSelectFd(Notifier* notify, int fd)
00141 {
00142 struct pollfd pfd;
00143 pfd.fd = fd;
00144 pfd.events = POLLIN|POLLHUP|POLLERR;
00145 pfd.revents = 0;
00146
00147 FdNotifiers.PushBack(notify);
00148 PollFds.PushBack(pfd);
00149
00150 OVR_ASSERT(FdNotifiers.GetSize() == PollFds.GetSize());
00151 return true;
00152 }
00153
00154 bool DeviceManagerThread::RemoveSelectFd(Notifier* notify, int fd)
00155 {
00156
00157
00158 for (UPInt i = 0; i < FdNotifiers.GetSize(); i++)
00159 {
00160 if ((FdNotifiers[i] == notify) && (PollFds[i].fd == fd))
00161 {
00162 FdNotifiers.RemoveAt(i);
00163 PollFds.RemoveAt(i);
00164 return true;
00165 }
00166 }
00167 return false;
00168 }
00169
00170
00171
00172 int DeviceManagerThread::Run()
00173 {
00174 ThreadCommand::PopBuffer command;
00175
00176 SetThreadName("OVR::DeviceManagerThread");
00177 LogText("OVR::DeviceManagerThread - running (ThreadId=%p).\n", GetThreadId());
00178
00179
00180 StartupEvent.SetEvent();
00181
00182 while(!IsExiting())
00183 {
00184
00185 if (PopCommand(&command))
00186 {
00187 command.Execute();
00188 }
00189 else
00190 {
00191 bool commands = 0;
00192 do
00193 {
00194 int waitMs = -1;
00195
00196
00197
00198 if (!TicksNotifiers.IsEmpty())
00199 {
00200 UInt64 ticksMks = Timer::GetTicks();
00201 int waitAllowed;
00202
00203 for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++)
00204 {
00205 waitAllowed = (int)(TicksNotifiers[j]->OnTicks(ticksMks) / Timer::MksPerMs);
00206 if (waitAllowed < waitMs)
00207 waitMs = waitAllowed;
00208 }
00209 }
00210
00211
00212 int n = poll(&PollFds[0], PollFds.GetSize(), waitMs);
00213
00214 if (n > 0)
00215 {
00216
00217
00218
00219
00220
00221 for (int i=PollFds.GetSize()-1; i>=0; i--)
00222 {
00223 if (PollFds[i].revents & POLLERR)
00224 {
00225 OVR_DEBUG_LOG(("poll: error on [%d]: %d", i, PollFds[i].fd));
00226 }
00227 else if (PollFds[i].revents & POLLIN)
00228 {
00229 if (FdNotifiers[i])
00230 FdNotifiers[i]->OnEvent(i, PollFds[i].fd);
00231 else if (i == 0)
00232 {
00233 char dummy[128];
00234 read(PollFds[i].fd, dummy, 128);
00235 commands = 1;
00236 }
00237 }
00238
00239 if (PollFds[i].revents & POLLHUP)
00240 PollFds[i].events = 0;
00241
00242 if (PollFds[i].revents != 0)
00243 {
00244 n--;
00245 if (n == 0)
00246 break;
00247 }
00248 }
00249 }
00250 } while (PollFds.GetSize() > 0 && !commands);
00251 }
00252 }
00253
00254 LogText("OVR::DeviceManagerThread - exiting (ThreadId=%p).\n", GetThreadId());
00255 return 0;
00256 }
00257
00258 bool DeviceManagerThread::AddTicksNotifier(Notifier* notify)
00259 {
00260 TicksNotifiers.PushBack(notify);
00261 return true;
00262 }
00263
00264 bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify)
00265 {
00266 for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++)
00267 {
00268 if (TicksNotifiers[i] == notify)
00269 {
00270 TicksNotifiers.RemoveAt(i);
00271 return true;
00272 }
00273 }
00274 return false;
00275 }
00276
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 DeviceManager* DeviceManager::Create()
00286 {
00287 if (!System::IsInitialized())
00288 {
00289
00290 OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
00291 LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); );
00292 return 0;
00293 }
00294
00295 Ptr<Linux::DeviceManager> manager = *new Linux::DeviceManager;
00296
00297 if (manager)
00298 {
00299 if (manager->Initialize(0))
00300 {
00301 manager->AddFactory(&LatencyTestDeviceFactory::Instance);
00302 manager->AddFactory(&SensorDeviceFactory::Instance);
00303 manager->AddFactory(&Linux::HMDDeviceFactory::Instance);
00304
00305 manager->AddRef();
00306 }
00307 else
00308 {
00309 manager.Clear();
00310 }
00311
00312 }
00313
00314 return manager.GetPtr();
00315 }
00316
00317
00318 }
00319