mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-23 00:35:31 +00:00
added linux makefile
This commit is contained in:
331
modules/oculus_sdk_linux/LibOVR/Src/OVR_Linux_DeviceManager.cpp
Normal file
331
modules/oculus_sdk_linux/LibOVR/Src/OVR_Linux_DeviceManager.cpp
Normal file
@ -0,0 +1,331 @@
|
||||
/************************************************************************************
|
||||
|
||||
Filename : OVR_Linux_DeviceManager.h
|
||||
Content : Linux implementation of DeviceManager.
|
||||
Created :
|
||||
Authors :
|
||||
|
||||
Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
|
||||
|
||||
Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
|
||||
you may not use the Oculus VR Rift SDK except in compliance with the License,
|
||||
which is provided at the time of installation or download, or which
|
||||
otherwise accompanies this software in either electronic or hard copy form.
|
||||
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.oculusvr.com/licenses/LICENSE-3.1
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*************************************************************************************/
|
||||
|
||||
#include "OVR_Linux_DeviceManager.h"
|
||||
|
||||
// Sensor & HMD Factories
|
||||
#include "OVR_LatencyTestImpl.h"
|
||||
#include "OVR_SensorImpl.h"
|
||||
#include "OVR_Linux_HIDDevice.h"
|
||||
#include "OVR_Linux_HMDDevice.h"
|
||||
|
||||
#include "Kernel/OVR_Timer.h"
|
||||
#include "Kernel/OVR_Std.h"
|
||||
#include "Kernel/OVR_Log.h"
|
||||
|
||||
namespace OVR { namespace Linux {
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// **** Linux::DeviceManager
|
||||
|
||||
DeviceManager::DeviceManager()
|
||||
{
|
||||
}
|
||||
|
||||
DeviceManager::~DeviceManager()
|
||||
{
|
||||
}
|
||||
|
||||
bool DeviceManager::Initialize(DeviceBase*)
|
||||
{
|
||||
if (!DeviceManagerImpl::Initialize(0))
|
||||
return false;
|
||||
|
||||
pThread = *new DeviceManagerThread();
|
||||
if (!pThread || !pThread->Start())
|
||||
return false;
|
||||
|
||||
// Wait for the thread to be fully up and running.
|
||||
pThread->StartupEvent.Wait();
|
||||
|
||||
// Do this now that we know the thread's run loop.
|
||||
HidDeviceManager = *HIDDeviceManager::CreateInternal(this);
|
||||
|
||||
pCreateDesc->pDevice = this;
|
||||
LogText("OVR::DeviceManager - initialized.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceManager::Shutdown()
|
||||
{
|
||||
LogText("OVR::DeviceManager - shutting down.\n");
|
||||
|
||||
// Set Manager shutdown marker variable; this prevents
|
||||
// any existing DeviceHandle objects from accessing device.
|
||||
pCreateDesc->pLock->pManager = 0;
|
||||
|
||||
// Push for thread shutdown *WITH NO WAIT*.
|
||||
// This will have the following effect:
|
||||
// - Exit command will get enqueued, which will be executed later on the thread itself.
|
||||
// - Beyond this point, this DeviceManager object may be deleted by our caller.
|
||||
// - Other commands, such as CreateDevice, may execute before ExitCommand, but they will
|
||||
// fail gracefully due to pLock->pManager == 0. Future commands can't be enqued
|
||||
// after pManager is null.
|
||||
// - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last
|
||||
// reference to the thread object.
|
||||
pThread->PushExitCommand(false);
|
||||
pThread.Clear();
|
||||
|
||||
DeviceManagerImpl::Shutdown();
|
||||
}
|
||||
|
||||
ThreadCommandQueue* DeviceManager::GetThreadQueue()
|
||||
{
|
||||
return pThread;
|
||||
}
|
||||
|
||||
ThreadId DeviceManager::GetThreadId() const
|
||||
{
|
||||
return pThread->GetThreadId();
|
||||
}
|
||||
|
||||
bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const
|
||||
{
|
||||
if ((info->InfoClassType != Device_Manager) &&
|
||||
(info->InfoClassType != Device_None))
|
||||
return false;
|
||||
|
||||
info->Type = Device_Manager;
|
||||
info->Version = 0;
|
||||
info->ProductName = "DeviceManager";
|
||||
info->Manufacturer = "Oculus VR, Inc.";
|
||||
return true;
|
||||
}
|
||||
|
||||
DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args)
|
||||
{
|
||||
// TBD: Can this be avoided in the future, once proper device notification is in place?
|
||||
pThread->PushCall((DeviceManagerImpl*)this,
|
||||
&DeviceManager::EnumerateAllFactoryDevices, true);
|
||||
|
||||
return DeviceManagerImpl::EnumerateDevicesEx(args);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** DeviceManager Thread
|
||||
|
||||
DeviceManagerThread::DeviceManagerThread()
|
||||
: Thread(ThreadStackSize)
|
||||
{
|
||||
int result = pipe(CommandFd);
|
||||
OVR_ASSERT(!result);
|
||||
OVR_UNUSED(result);
|
||||
|
||||
AddSelectFd(NULL, CommandFd[0]);
|
||||
}
|
||||
|
||||
DeviceManagerThread::~DeviceManagerThread()
|
||||
{
|
||||
if (CommandFd[0])
|
||||
{
|
||||
RemoveSelectFd(NULL, CommandFd[0]);
|
||||
close(CommandFd[0]);
|
||||
close(CommandFd[1]);
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceManagerThread::AddSelectFd(Notifier* notify, int fd)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN|POLLHUP|POLLERR;
|
||||
pfd.revents = 0;
|
||||
|
||||
FdNotifiers.PushBack(notify);
|
||||
PollFds.PushBack(pfd);
|
||||
|
||||
OVR_ASSERT(FdNotifiers.GetSize() == PollFds.GetSize());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceManagerThread::RemoveSelectFd(Notifier* notify, int fd)
|
||||
{
|
||||
// [0] is reserved for thread commands with notify of null, but we still
|
||||
// can use this function to remove it.
|
||||
for (UPInt i = 0; i < FdNotifiers.GetSize(); i++)
|
||||
{
|
||||
if ((FdNotifiers[i] == notify) && (PollFds[i].fd == fd))
|
||||
{
|
||||
FdNotifiers.RemoveAt(i);
|
||||
PollFds.RemoveAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int DeviceManagerThread::Run()
|
||||
{
|
||||
ThreadCommand::PopBuffer command;
|
||||
|
||||
SetThreadName("OVR::DeviceManagerThread");
|
||||
LogText("OVR::DeviceManagerThread - running (ThreadId=%p).\n", GetThreadId());
|
||||
|
||||
// Signal to the parent thread that initialization has finished.
|
||||
StartupEvent.SetEvent();
|
||||
|
||||
while(!IsExiting())
|
||||
{
|
||||
// PopCommand will reset event on empty queue.
|
||||
if (PopCommand(&command))
|
||||
{
|
||||
command.Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
bool commands = 0;
|
||||
do
|
||||
{
|
||||
int waitMs = -1;
|
||||
|
||||
// If devices have time-dependent logic registered, get the longest wait
|
||||
// allowed based on current ticks.
|
||||
if (!TicksNotifiers.IsEmpty())
|
||||
{
|
||||
double timeSeconds = Timer::GetSeconds();
|
||||
unsigned waitAllowed;
|
||||
|
||||
for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++)
|
||||
{
|
||||
waitAllowed = (unsigned)(TicksNotifiers[j]->OnTicks(timeSeconds) * Timer::MsPerSecond);
|
||||
if (waitAllowed < (unsigned)waitMs)
|
||||
waitMs = waitAllowed;
|
||||
}
|
||||
}
|
||||
|
||||
// wait until there is data available on one of the devices or the timeout expires
|
||||
int n = poll(&PollFds[0], PollFds.GetSize(), waitMs);
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
// Iterate backwards through the list so the ordering will not be
|
||||
// affected if the called object gets removed during the callback
|
||||
// Also, the HID data streams are located toward the back of the list
|
||||
// and servicing them first will allow a disconnect to be handled
|
||||
// and cleaned directly at the device first instead of the general HID monitor
|
||||
for (int i=PollFds.GetSize()-1; i>=0; i--)
|
||||
{
|
||||
if (PollFds[i].revents & POLLERR)
|
||||
{
|
||||
OVR_DEBUG_LOG(("poll: error on [%d]: %d", i, PollFds[i].fd));
|
||||
}
|
||||
else if (PollFds[i].revents & POLLIN)
|
||||
{
|
||||
if (FdNotifiers[i])
|
||||
FdNotifiers[i]->OnEvent(i, PollFds[i].fd);
|
||||
else if (i == 0) // command
|
||||
{
|
||||
char dummy[128];
|
||||
read(PollFds[i].fd, dummy, 128);
|
||||
commands = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (PollFds[i].revents & POLLHUP)
|
||||
PollFds[i].events = 0;
|
||||
|
||||
if (PollFds[i].revents != 0)
|
||||
{
|
||||
n--;
|
||||
if (n == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (PollFds.GetSize() > 0 && !commands);
|
||||
}
|
||||
}
|
||||
|
||||
LogText("OVR::DeviceManagerThread - exiting (ThreadId=%p).\n", GetThreadId());
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DeviceManagerThread::AddTicksNotifier(Notifier* notify)
|
||||
{
|
||||
TicksNotifiers.PushBack(notify);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify)
|
||||
{
|
||||
for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++)
|
||||
{
|
||||
if (TicksNotifiers[i] == notify)
|
||||
{
|
||||
TicksNotifiers.RemoveAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Linux
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// ***** Creation
|
||||
|
||||
|
||||
// Creates a new DeviceManager and initializes OVR.
|
||||
DeviceManager* DeviceManager::Create()
|
||||
{
|
||||
if (!System::IsInitialized())
|
||||
{
|
||||
// Use custom message, since Log is not yet installed.
|
||||
OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
|
||||
LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); );
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ptr<Linux::DeviceManager> manager = *new Linux::DeviceManager;
|
||||
|
||||
if (manager)
|
||||
{
|
||||
if (manager->Initialize(0))
|
||||
{
|
||||
manager->AddFactory(&LatencyTestDeviceFactory::GetInstance());
|
||||
manager->AddFactory(&SensorDeviceFactory::GetInstance());
|
||||
manager->AddFactory(&Linux::HMDDeviceFactory::GetInstance());
|
||||
|
||||
manager->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
manager.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return manager.GetPtr();
|
||||
}
|
||||
|
||||
|
||||
} // namespace OVR
|
||||
|
Reference in New Issue
Block a user