oculus1

annotate libovr/Src/OVR_DeviceHandle.cpp @ 29:9a973ef0e2a3

fixed the performance issue under MacOSX by replacing glutSolidTeapot (which uses glEvalMesh) with my own teapot generator.
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 27 Oct 2013 06:31:18 +0200
parents
children
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