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_OSX_DeviceManager.h"
00017
00018
00019 #include "OVR_LatencyTestImpl.h"
00020 #include "OVR_SensorImpl.h"
00021 #include "OVR_OSX_HMDDevice.h"
00022 #include "OVR_OSX_HIDDevice.h"
00023
00024 #include "Kernel/OVR_Timer.h"
00025 #include "Kernel/OVR_Std.h"
00026 #include "Kernel/OVR_Log.h"
00027
00028 #include <IOKit/hid/IOHIDManager.h>
00029 #include <IOKit/hid/IOHIDKeys.h>
00030
00031
00032 namespace OVR { namespace OSX {
00033
00034
00035
00036
00037 DeviceManager::DeviceManager()
00038 {
00039 }
00040
00041 DeviceManager::~DeviceManager()
00042 {
00043 OVR_DEBUG_LOG(("OSX::DeviceManager::~DeviceManager was called"));
00044 }
00045
00046 bool DeviceManager::Initialize(DeviceBase*)
00047 {
00048 if (!DeviceManagerImpl::Initialize(0))
00049 return false;
00050
00051
00052 pThread = *new DeviceManagerThread();
00053 if (!pThread || !pThread->Start())
00054 return false;
00055
00056
00057 pThread->StartupEvent.Wait();
00058
00059
00060 HidDeviceManager = *HIDDeviceManager::CreateInternal(this);
00061
00062 CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, this);
00063
00064 pCreateDesc->pDevice = this;
00065 LogText("OVR::DeviceManager - initialized.\n");
00066
00067 return true;
00068 }
00069
00070 void DeviceManager::Shutdown()
00071 {
00072 LogText("OVR::DeviceManager - shutting down.\n");
00073
00074 CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallBack, this);
00075
00076
00077
00078 pCreateDesc->pLock->pManager = 0;
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 pThread->Shutdown();
00090 pThread.Clear();
00091
00092 DeviceManagerImpl::Shutdown();
00093 }
00094
00095 ThreadCommandQueue* DeviceManager::GetThreadQueue()
00096 {
00097 return pThread;
00098 }
00099
00100 ThreadId DeviceManager::GetThreadId() const
00101 {
00102 return pThread->GetThreadId();
00103 }
00104
00105 bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const
00106 {
00107 if ((info->InfoClassType != Device_Manager) &&
00108 (info->InfoClassType != Device_None))
00109 return false;
00110
00111 info->Type = Device_Manager;
00112 info->Version = 0;
00113 OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, "DeviceManager");
00114 OVR_strcpy(info->Manufacturer,DeviceInfo::MaxNameLength, "Oculus VR, Inc.");
00115 return true;
00116 }
00117
00118 DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args)
00119 {
00120
00121 pThread->PushCall((DeviceManagerImpl*)this,
00122 &DeviceManager::EnumerateAllFactoryDevices, true);
00123
00124 return DeviceManagerImpl::EnumerateDevicesEx(args);
00125 }
00126
00127 void DeviceManager::displayReconfigurationCallBack (CGDirectDisplayID display,
00128 CGDisplayChangeSummaryFlags flags,
00129 void *userInfo)
00130 {
00131 DeviceManager* manager = reinterpret_cast<DeviceManager*>(userInfo);
00132 OVR_UNUSED(manager);
00133
00134 if (flags & kCGDisplayAddFlag)
00135 {
00136 LogText("Display Added, id = %d\n", int(display));
00137 manager->EnumerateDevices<HMDDevice>();
00138 }
00139 else if (flags & kCGDisplayRemoveFlag)
00140 {
00141 LogText("Display Removed, id = %d\n", int(display));
00142 manager->EnumerateDevices<HMDDevice>();
00143 }
00144 }
00145
00146
00147
00148
00149 DeviceManagerThread::DeviceManagerThread()
00150 : Thread(ThreadStackSize)
00151 {
00152 }
00153
00154 DeviceManagerThread::~DeviceManagerThread()
00155 {
00156 }
00157
00158 int DeviceManagerThread::Run()
00159 {
00160
00161 SetThreadName("OVR::DeviceManagerThread");
00162 LogText("OVR::DeviceManagerThread - running (ThreadId=0x%p).\n", GetThreadId());
00163
00164
00165 RunLoop = CFRunLoopGetCurrent();
00166
00167
00168 CFRunLoopSourceContext sourceContext;
00169 memset(&sourceContext, 0, sizeof(sourceContext));
00170 sourceContext.version = 0;
00171 sourceContext.info = this;
00172 sourceContext.perform = &staticCommandQueueSourceCallback;
00173
00174 CommandQueueSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 , &sourceContext);
00175
00176 CFRunLoopAddSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode);
00177
00178
00179
00180 StartupEvent.SetEvent();
00181
00182
00183 ThreadCommand::PopBuffer command;
00184
00185 while(!IsExiting())
00186 {
00187
00188 if (PopCommand(&command))
00189 {
00190 command.Execute();
00191 }
00192 else
00193 {
00194 SInt32 exitReason = 0;
00195 do {
00196
00197 UInt32 waitMs = INT_MAX;
00198
00199
00200
00201 if (!TicksNotifiers.IsEmpty())
00202 {
00203 UInt64 ticksMks = Timer::GetTicks();
00204 UInt32 waitAllowed;
00205
00206 for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++)
00207 {
00208 waitAllowed = (UInt32)(TicksNotifiers[j]->OnTicks(ticksMks) / Timer::MksPerMs);
00209 if (waitAllowed < waitMs)
00210 waitMs = waitAllowed;
00211 }
00212 }
00213
00214
00215
00216
00217
00218 CFTimeInterval blockInterval = 0.001 * (double) waitMs;
00219 exitReason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, blockInterval, false);
00220
00221 if (exitReason == kCFRunLoopRunFinished)
00222 {
00223
00224 break;
00225 }
00226 else if (exitReason == kCFRunLoopRunStopped )
00227 {
00228
00229 break;
00230 }
00231 else if (exitReason == kCFRunLoopRunTimedOut)
00232 {
00233
00234 continue;
00235 }
00236 else if (exitReason == kCFRunLoopRunHandledSource)
00237 {
00238
00239
00240 OVR_ASSERT(false);
00241 break;
00242 }
00243 else
00244 {
00245 OVR_ASSERT_LOG(false, ("CFRunLoopRunInMode returned unexpected code"));
00246 break;
00247 }
00248 }
00249 while(true);
00250 }
00251 }
00252
00253
00254 CFRunLoopRemoveSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode);
00255 CFRelease(CommandQueueSource);
00256
00257 LogText("OVR::DeviceManagerThread - exiting (ThreadId=0x%p).\n", GetThreadId());
00258
00259 return 0;
00260 }
00261
00262 void DeviceManagerThread::staticCommandQueueSourceCallback(void* pContext)
00263 {
00264 DeviceManagerThread* pThread = (DeviceManagerThread*) pContext;
00265 pThread->commandQueueSourceCallback();
00266 }
00267
00268 void DeviceManagerThread::commandQueueSourceCallback()
00269 {
00270 CFRunLoopStop(RunLoop);
00271 }
00272
00273 bool DeviceManagerThread::AddTicksNotifier(Notifier* notify)
00274 {
00275 TicksNotifiers.PushBack(notify);
00276 return true;
00277 }
00278
00279 bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify)
00280 {
00281 for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++)
00282 {
00283 if (TicksNotifiers[i] == notify)
00284 {
00285 TicksNotifiers.RemoveAt(i);
00286 return true;
00287 }
00288 }
00289 return false;
00290 }
00291
00292 void DeviceManagerThread::Shutdown()
00293 {
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 PushExitCommand(false);
00304
00305
00306 CFRunLoopSourceSignal(CommandQueueSource);
00307 CFRunLoopWakeUp(RunLoop);
00308 }
00309
00310 }
00311
00312
00313
00314
00315
00316
00317 DeviceManager* DeviceManager::Create()
00318 {
00319
00320 if (!System::IsInitialized())
00321 {
00322
00323 OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
00324 LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); );
00325 return 0;
00326 }
00327
00328 Ptr<OSX::DeviceManager> manager = *new OSX::DeviceManager;
00329
00330 if (manager)
00331 {
00332 if (manager->Initialize(0))
00333 {
00334 manager->AddFactory(&LatencyTestDeviceFactory::Instance);
00335 manager->AddFactory(&SensorDeviceFactory::Instance);
00336 manager->AddFactory(&OSX::HMDDeviceFactory::Instance);
00337
00338 manager->AddRef();
00339 }
00340 else
00341 {
00342 manager.Clear();
00343 }
00344 }
00345
00346 return manager.GetPtr();
00347 }
00348
00349 }