diff options
Diffstat (limited to 'LibOVR/Src/Util')
-rw-r--r-- | LibOVR/Src/Util/GUIConsole.h | 51 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_DataLogger.h | 168 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_ImageWindow.cpp | 574 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_ImageWindow.h | 204 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_Interface.h | 2 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_LatencyTest2Reader.cpp | 4 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_LatencyTest2Reader.h | 6 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_LatencyTest2State.h | 17 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_MatFile.cpp | 496 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_MatFile.h | 116 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_Render_Stereo.cpp | 81 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_Render_Stereo.h | 22 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_Stopwatch.h | 139 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_SystemGUI.cpp | 190 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_SystemGUI.h | 39 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_SystemGUI_OSX.mm | 69 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_SystemInfo.cpp | 289 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_SystemInfo.h | 51 | ||||
-rw-r--r-- | LibOVR/Src/Util/Util_SystemInfo_OSX.mm | 106 |
19 files changed, 1006 insertions, 1618 deletions
diff --git a/LibOVR/Src/Util/GUIConsole.h b/LibOVR/Src/Util/GUIConsole.h deleted file mode 100644 index a1b35ed..0000000 --- a/LibOVR/Src/Util/GUIConsole.h +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************ - -Filename : GUIConsole.h -Content : A stdout console window that runs alongside Windows GUI applications -Created : Feb 4, 2013 -Authors : Brant Lewis - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 - -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. - -*************************************************************************************/ - -#ifndef GUICONSOLE_H -#define GUICONSOLE_H - -#include "../../Include/OVR_Kernel.h" - -#ifdef OVR_INTERNAL_USE - -#include <WinSock2.h> -#include <WS2tcpip.h> -#define WIN32_LEAN_AND_MEAN -#include <Windows.h> - -class GUIConsole -{ -public: - // constructors - GUIConsole(); - ~GUIConsole(); - - // member variables - HANDLE hStdIn, hStdOut, hStdError; -}; -#endif // #ifdef OVR_INTERNAL_USE - -#endif diff --git a/LibOVR/Src/Util/Util_DataLogger.h b/LibOVR/Src/Util/Util_DataLogger.h new file mode 100644 index 0000000..e21c9f2 --- /dev/null +++ b/LibOVR/Src/Util/Util_DataLogger.h @@ -0,0 +1,168 @@ +/************************************************************************************ + +Filename : Util_DataLogger.h +Content : General purpose data logging to Matlab +Created : Oct 3, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 + +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. + +*************************************************************************************/ + +#ifndef OVR_Util_DataLogger_h +#define OVR_Util_DataLogger_h + +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_String.h" +#include "Util_MatFile.h" + +#ifndef OVR_ENABLE_DATALOGGER +#define OVR_ENABLE_DATALOGGER 1 +#endif + +namespace OVR { + +template<typename T> class Vector3; +template<typename T> class Quat; +template<typename T> class Pose; + +namespace Util { + +#if OVR_ENABLE_DATALOGGER + +class DataLogger; + + +// DataLogger Channel +class DataLoggerChannel +{ +public: + void Log(const void* data, int sampleSize); + + bool IsLogging() const; + bool IsFull() const; + + // Logging functions for some common types + template<typename T> + void Log(const Quat<T>& q); + + template<typename T> + void Log(const Vector3<T>& v); + + template<typename T> + void Log(const Pose<T>& p); + +private: + friend class DataLogger; + + DataLoggerChannel(DataLogger* logger, const char* name, int sampleSize, int sampleRate, bool doubleMatrix); + ~DataLoggerChannel(); + + bool Write(MatFile& matfile); + +private: + DataLogger* Logger; + String Name; + int SampleSize; + int SampleRate; + int SampleCount; + int MaxSampleCount; + bool DoubleMatrix; + uint8_t* SampleData; +}; + +// DataLogger class +class DataLogger +{ +public: + DataLogger(); + ~DataLogger(); + + // Parses C command line parameters "-log <objectIndex> <matFileName> <logTime>" + static bool ParseCommandLine(int* pargc, const char** pargv[], int& logIndex, String& logFile, double& logTime); + + void SetLogFile(const char* filename, double logTime); + bool SaveLogFile(); + + bool IsLogging() const { return LogTime > 0; } + + DataLoggerChannel* GetChannel(const char* name); + DataLoggerChannel* CreateChannel(const char* name, int sampleSize, int sampleRate, bool doubleMatrix = true); + + void Log(const char* name, const void* data, int sampleSize, int sampleRate, bool doubleMatrix = true) + { + DataLoggerChannel *channel = CreateChannel(name, sampleSize, sampleRate, doubleMatrix); + if (channel) channel->Log(data, sampleSize); + } + +private: + friend class DataLoggerChannel; + + DataLoggerChannel* GetChannelNoLock(const char* name); + + Lock TheLock; + double LogTime; + String Filename; + ArrayPOD<DataLoggerChannel*> Channels; +}; + +#else // OVR_ENABLE_DATALOGGER + +// Disabled, no-op implementation +class DataLoggerChannel +{ +public: + OVR_FORCE_INLINE void Log(const void* data, int sampleSize) { OVR_UNUSED2(data, sampleSize); } + + OVR_FORCE_INLINE bool IsLogging() const { return false; } + OVR_FORCE_INLINE bool IsFull() const { return false; } + + template<typename T> + OVR_FORCE_INLINE void Log(const Quat<T>& q) { OVR_UNUSED(q); } + + template<typename T> + OVR_FORCE_INLINE void Log(const Vector3<T>& v) { OVR_UNUSED(v); } + + template<typename T> + OVR_FORCE_INLINE void Log(const Pose<T>& p) { OVR_UNUSED(p); } +}; + +class DataLogger +{ +public: + static bool ParseCommandLine(int* pargc, const char** pargv[], int& logIndex, String& logFile, double& logTime) { OVR_UNUSED5(pargc, pargv, logIndex, logFile, logTime); return false; } + + OVR_FORCE_INLINE void SetLogFile(const char* filename, double logTime) { OVR_UNUSED2(filename, logTime); } + OVR_FORCE_INLINE bool SaveLogFile() { return true; } + + OVR_FORCE_INLINE bool IsLogging() const { return false; } + + OVR_FORCE_INLINE DataLoggerChannel* GetChannel(const char* name) { OVR_UNUSED(name); return &NullChannel; } + OVR_FORCE_INLINE DataLoggerChannel* CreateChannel(const char* name, int sampleSize, int sampleRate) { OVR_UNUSED3(name, sampleSize, sampleRate); return &NullChannel; } + +private: + friend class DataLoggerChannel; + static DataLoggerChannel NullChannel; +}; + +#endif // OVR_ENABLE_DATALOGGER + + +}} // namespace OVR::Util + +#endif // OVR_Util_DataLogger_h diff --git a/LibOVR/Src/Util/Util_ImageWindow.cpp b/LibOVR/Src/Util/Util_ImageWindow.cpp deleted file mode 100644 index 4c120f9..0000000 --- a/LibOVR/Src/Util/Util_ImageWindow.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/************************************************************************************ - -Filename : Util_ImageWindow.cpp -Content : An output object for windows that can display raw images for testing -Created : March 13, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 - -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 "../../Include/OVR_Kernel.h" - -#include "Util_ImageWindow.h" - -#if defined(OVR_OS_WIN32) - -#define WIN32_LEAN_AND_MEAN -#include <Windows.h> - -#include "DWrite.h" - -typedef HRESULT (WINAPI *D2D1CreateFactoryFn)( - _In_ D2D1_FACTORY_TYPE, - _In_ REFIID, - _In_opt_ const D2D1_FACTORY_OPTIONS*, - _Out_ ID2D1Factory ** - ); - -typedef HRESULT (WINAPI *DWriteCreateFactoryFn)( - _In_ DWRITE_FACTORY_TYPE factoryType, - _In_ REFIID iid, - _Out_ IUnknown **factory - ); - - -namespace OVR { namespace Util { - -ID2D1Factory* ImageWindow::pD2DFactory = NULL; -IDWriteFactory* ImageWindow::pDWriteFactory = NULL; -HINSTANCE ImageWindow::hInstD2d1 = NULL; -HINSTANCE ImageWindow::hInstDwrite = NULL; - - -// TODO(review): This appears to be (at present) necessary, the global list is accessed by the -// render loop in Samples. In the current version, windows will just be lost when windowCount -// exceeds MaxWindows; I've left that in place, since this is unfamiliar code. I'm not sure what -// thread-safety guarantees this portion of the code needs to satisfy, so I don't want to -// change it to a list or whatever. Asserts added to catch the error. -ImageWindow* ImageWindow::globalWindow[ImageWindow::MaxWindows]; -int ImageWindow::windowCount = 0; - -LRESULT CALLBACK MainWndProc( - HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - switch (uMsg) - { - case WM_CREATE: - return 0; - - case WM_PAINT: - { - LONG_PTR ptr = GetWindowLongPtr( hwnd, GWLP_USERDATA ); - if( ptr ) - { - ImageWindow* iw = (ImageWindow*)ptr; - iw->OnPaint(); - } - } - - return 0; - - case WM_SIZE: - // Set the size and position of the window. - return 0; - - case WM_DESTROY: - // Clean up window-specific data objects. - return 0; - - // - // Process other messages. - // - - default: - return DefWindowProc(hwnd, uMsg, wParam, lParam); - } - //return 0; -} - - -ImageWindow::ImageWindow( uint32_t width, uint32_t height ) : - hWindow(NULL), - pRT(NULL), - //resolution(), - frontBufferMutex( new Mutex() ), - frames(), - greyBitmap(NULL), - colorBitmap(NULL) -{ - D2D1CreateFactoryFn createFactory = NULL; - DWriteCreateFactoryFn writeFactory = NULL; - - if (!hInstD2d1) - { - hInstD2d1 = LoadLibraryW( L"d2d1.dll" ); - } - - if (!hInstD2d1) - { - hInstD2d1 = LoadLibraryW( L"Dwrite.dll" ); - } - - if( hInstD2d1 ) - { - createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInstD2d1, "D2D1CreateFactory" ); - } - - if( hInstDwrite ) - { - writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstDwrite, "DWriteCreateFactory" ); - } - - // TODO: see note where globalWindow is declared. - globalWindow[windowCount++ % MaxWindows] = this; - OVR_ASSERT(windowCount < MaxWindows); - - if( pD2DFactory == NULL && createFactory && writeFactory ) - { - // Create a Direct2D factory. - HRESULT hResult = createFactory( - D2D1_FACTORY_TYPE_MULTI_THREADED, - __uuidof(ID2D1Factory), - NULL, - &pD2DFactory // This will be AddRef'd for us. - ); - OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); - - // Create a DirectWrite factory. - hResult = writeFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(pDWriteFactory), // This probably should instead be __uuidof(IDWriteFactory) - reinterpret_cast<IUnknown **>(&pDWriteFactory) // This will be AddRef'd for us. - ); - OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); - } - - resolution = D2D1::SizeU( width, height ); - - if (hWindow) - { - SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this ); - } -} - -ImageWindow::~ImageWindow() -{ - for( int i = 0; i < MaxWindows; ++i ) - { - if( globalWindow[i] == this ) - { - globalWindow[i] = NULL; - break; - } - } - - if( greyBitmap ) - greyBitmap->Release(); - - if( colorBitmap ) - colorBitmap->Release(); - - if( pRT ) - pRT->Release(); - - { - Mutex::Locker locker( frontBufferMutex ); - - while( frames.GetSize() ) - { - Ptr<Frame> aFrame = frames.PopBack(); - } - } - - delete frontBufferMutex; - - if (hWindow) - { - ShowWindow( hWindow, SW_HIDE ); - DestroyWindow( hWindow ); - } - - if (pD2DFactory) - { - pD2DFactory->Release(); - pD2DFactory = NULL; - } - - if (pDWriteFactory) - { - pDWriteFactory->Release(); - pDWriteFactory = NULL; - } - - if( hInstD2d1 ) - { - FreeLibrary(hInstD2d1); - hInstD2d1 = NULL; - } - - if( hInstDwrite ) - { - FreeLibrary(hInstDwrite); - hInstDwrite = NULL; - } -} - -void ImageWindow::AssociateSurface( void* surface ) -{ - if (pD2DFactory) - { - // Assume an IUnknown - IUnknown* unknown = (IUnknown*)surface; - - IDXGISurface *pDxgiSurface = NULL; - HRESULT hr = unknown->QueryInterface(&pDxgiSurface); - if( hr == S_OK ) - { - D2D1_RENDER_TARGET_PROPERTIES props = - D2D1::RenderTargetProperties( - D2D1_RENDER_TARGET_TYPE_DEFAULT, - D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), - 96, - 96 - ); - - pRT = NULL; - ID2D1RenderTarget* tmpTarget; - - hr = pD2DFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &props, &tmpTarget ); - - if( hr == S_OK ) - { - DXGI_SURFACE_DESC desc = {0}; - pDxgiSurface->GetDesc( &desc ); - int width = desc.Width; - int height = desc.Height; - - D2D1_SIZE_U size = D2D1::SizeU( width, height ); - - D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat( - DXGI_FORMAT_A8_UNORM, - D2D1_ALPHA_MODE_PREMULTIPLIED - ); - - D2D1_PIXEL_FORMAT colorPixelFormat = D2D1::PixelFormat( - DXGI_FORMAT_B8G8R8A8_UNORM, - D2D1_ALPHA_MODE_PREMULTIPLIED - ); - - D2D1_BITMAP_PROPERTIES bitmapProps; - bitmapProps.dpiX = 96; - bitmapProps.dpiY = 96; - bitmapProps.pixelFormat = pixelFormat; - - D2D1_BITMAP_PROPERTIES colorBitmapProps; - colorBitmapProps.dpiX = 96; - colorBitmapProps.dpiY = 96; - colorBitmapProps.pixelFormat = colorPixelFormat; - - HRESULT result = tmpTarget->CreateBitmap( size, bitmapProps, &greyBitmap ); - if( result != S_OK ) - { - tmpTarget->Release(); - tmpTarget = NULL; - } - - if (tmpTarget) - { - result = tmpTarget->CreateBitmap(size, colorBitmapProps, &colorBitmap); - if (result != S_OK) - { - tmpTarget->Release(); - tmpTarget = NULL; - } - } - pRT = tmpTarget; - } - } - } -} - -void ImageWindow::Process() -{ - if( pRT && greyBitmap ) - { - OnPaint(); - - pRT->Flush(); - } -} - -void ImageWindow::Complete() -{ - Mutex::Locker locker( frontBufferMutex ); - - if( frames.IsEmpty() ) - return; - - if( frames.PeekBack(0)->ready ) - return; - - Ptr<Frame> frame = frames.PeekBack(0); - - frame->ready = true; -} - -void ImageWindow::OnPaint() -{ - Mutex::Locker locker( frontBufferMutex ); - - // Nothing to do - if( frames.IsEmpty() ) - return; - - if( !frames.PeekFront(0)->ready ) - return; - - Ptr<Frame> currentFrame = frames.PopFront(); - - Ptr<Frame> nextFrame = NULL; - - if( !frames.IsEmpty() ) - nextFrame = frames.PeekFront(0); - - while( nextFrame && nextFrame->ready ) - { - // Free up the current frame since it's been removed from the deque - currentFrame = frames.PopFront(); - - if( frames.IsEmpty() ) - break; - - nextFrame = frames.PeekFront(0); - } - - if( currentFrame->imageData ) - greyBitmap->CopyFromMemory( NULL, currentFrame->imageData, currentFrame->width ); - - if( currentFrame->colorImageData ) - colorBitmap->CopyFromMemory( NULL, currentFrame->colorImageData, currentFrame->colorPitch ); - - pRT->BeginDraw(); - - pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); - - pRT->Clear( D2D1::ColorF(D2D1::ColorF::Black) ); - - // This will mirror our image - D2D1_MATRIX_3X2_F m; - m._11 = -1; m._12 = 0; - m._21 = 0; m._22 = 1; - m._31 = 0; m._32 = 0; - pRT->SetTransform( m ); - - ID2D1SolidColorBrush* whiteBrush; - - pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush ); - - if( currentFrame->imageData ) - { - pRT->FillOpacityMask( greyBitmap, whiteBrush, - D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, - D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), - //D2D1::RectF( 0.0f, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), - D2D1::RectF( 0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height ) ); - } - else if( currentFrame->colorImageData ) - { - pRT->DrawBitmap( colorBitmap, - D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) ); - - } - - pRT->SetTransform(D2D1::Matrix3x2F::Identity()); - - whiteBrush->Release(); - - Array<CirclePlot>::Iterator it; - - for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it ) - { - ID2D1SolidColorBrush* aBrush; - - pRT->CreateSolidColorBrush( D2D1::ColorF( it->r, it->g, it->b), &aBrush ); - - D2D1_ELLIPSE ellipse; - ellipse.point.x = it->x; - ellipse.point.y = it->y; - ellipse.radiusX = it->radius; - ellipse.radiusY = it->radius; - - if( it->fill ) - pRT->FillEllipse( &ellipse, aBrush ); - else - pRT->DrawEllipse( &ellipse, aBrush ); - - aBrush->Release(); - } - - static const WCHAR msc_fontName[] = L"Verdana"; - static const FLOAT msc_fontSize = 20; - - IDWriteTextFormat* textFormat = NULL; - - // Create a DirectWrite text format object. - pDWriteFactory->CreateTextFormat( - msc_fontName, - NULL, - DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - msc_fontSize, - L"", //locale - &textFormat - ); - - D2D1_SIZE_F renderTargetSize = pRT->GetSize(); - - Array<TextPlot>::Iterator textIt; - for( textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); ++textIt ) - { - ID2D1SolidColorBrush* aBrush; - - pRT->CreateSolidColorBrush( D2D1::ColorF( textIt->r, textIt->g, textIt->b), &aBrush ); - - WCHAR* tmpString = (WCHAR*)calloc( textIt->text.GetLength(), sizeof( WCHAR ) ); - for( unsigned i = 0; i < textIt->text.GetLength(); ++i ) - { - tmpString[i] = (WCHAR)textIt->text.GetCharAt( i ); - } - - pRT->DrawTextW( tmpString, (UINT32)textIt->text.GetLength(), textFormat, - D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), aBrush ); - - free( tmpString ); - - aBrush->Release(); - } - - if( textFormat ) - textFormat->Release(); - - pRT->EndDraw(); - - pRT->Flush(); -} - -Ptr<Frame> ImageWindow::lastUnreadyFrame() -{ - static int framenumber = 0; - - if( frames.GetSize() && !frames.PeekBack( 0 )->ready ) - return frames.PeekBack( 0 ); - - // Create a new frame if an unready one doesn't already exist - Ptr<Frame> tmpFrame = *new Frame( framenumber ); - frames.PushBack( tmpFrame ); - - ++framenumber; - - return tmpFrame; -} - -void ImageWindow::UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) -{ - if( pRT && greyBitmap ) - { - Mutex::Locker locker( frontBufferMutex ); - - Ptr<Frame> frame = lastUnreadyFrame(); - frame->imageData = malloc( width * height ); - frame->width = width; - frame->height = height; - memcpy( frame->imageData, imageData, width * height ); - } -} - -void ImageWindow::UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) -{ - if( pRT && colorBitmap ) - { - Mutex::Locker locker( frontBufferMutex ); - - Ptr<Frame> frame = lastUnreadyFrame(); - frame->colorImageData = malloc( pitch * height ); - frame->width = width; - frame->height = height; - frame->colorPitch = pitch; - memcpy( frame->colorImageData, imageData, pitch * height ); - } -} - -void ImageWindow::addCircle( float x, float y, float radius, float r, float g, float b, bool fill ) -{ - if( pRT ) - { - CirclePlot cp; - - cp.x = x; - cp.y = y; - cp.radius = radius; - cp.r = r; - cp.g = g; - cp.b = b; - cp.fill = fill; - - Mutex::Locker locker( frontBufferMutex ); - - Ptr<Frame> frame = lastUnreadyFrame(); - frame->plots.PushBack( cp ); - } - -} - -void ImageWindow::addText( float x, float y, float r, float g, float b, OVR::String text ) -{ - if( pRT ) - { - TextPlot tp; - - tp.x = x; - tp.y = y; - tp.r = r; - tp.g = g; - tp.b = b; - tp.text = text; - - Mutex::Locker locker( frontBufferMutex ); - Ptr<Frame> frame = lastUnreadyFrame(); - frame->textLines.PushBack( tp ); - } -} - -}} - -#else //defined(OVR_OS_WIN32) - -namespace OVR { namespace Util { - -ImageWindow* ImageWindow::globalWindow[4]; -int ImageWindow::windowCount = 0; - -}} - -#endif //#else //defined(OVR_OS_WIN32) - diff --git a/LibOVR/Src/Util/Util_ImageWindow.h b/LibOVR/Src/Util/Util_ImageWindow.h deleted file mode 100644 index 979dd93..0000000 --- a/LibOVR/Src/Util/Util_ImageWindow.h +++ /dev/null @@ -1,204 +0,0 @@ -/************************************************************************************ - -Filename : Util_ImageWindow.h -Content : An output object for windows that can display raw images for testing -Created : March 13, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 - -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. - -*************************************************************************************/ - -#ifndef UTIL_IMAGEWINDOW_H -#define UTIL_IMAGEWINDOW_H - -#if defined(OVR_OS_WIN32) -#include <WinSock2.h> -#include <WS2tcpip.h> -#define WIN32_LEAN_AND_MEAN -#include <Windows.h> -#include <d2d1.h> -#include <dwrite.h> -#endif - -#include "../Kernel/OVR_Hash.h" -#include "../Kernel/OVR_Array.h" -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_Deque.h" - -#include <stdint.h> - -namespace OVR { namespace Util { - - typedef struct - { - float x; - float y; - float radius; - float r; - float g; - float b; - bool fill; - } CirclePlot; - - typedef struct - { - float x; - float y; - float r; - float g; - float b; - OVR::String text; - } TextPlot; - -class Frame : virtual public RefCountBaseV<Frame> - { -public: - - Frame( int frame ) : - frameNumber( frame ), - imageData( NULL ), - colorImageData( NULL ), - plots(), - textLines(), - width( 0 ), - height( 0 ), - colorPitch( 0 ), - ready( false ) - { - - } - - ~Frame() - { - if( imageData ) - free( imageData ); - if( colorImageData ) - free( colorImageData ); - - plots.ClearAndRelease(); - textLines.ClearAndRelease(); - } - - int frameNumber; - - Array<CirclePlot> plots; - Array<TextPlot> textLines; - void* imageData; - void* colorImageData; - int width; - int height; - int colorPitch; - bool ready; -}; - -#if defined(OVR_OS_WIN32) -class ImageWindow -{ - HWND hWindow; - ID2D1RenderTarget* pRT; - D2D1_SIZE_U resolution; - - Mutex* frontBufferMutex; - - InPlaceMutableDeque< Ptr<Frame> > frames; - - ID2D1Bitmap* greyBitmap; - ID2D1Bitmap* colorBitmap; - -public: - // constructors - ImageWindow(); - ImageWindow( uint32_t width, uint32_t height ); - virtual ~ImageWindow(); - - void GetResolution( size_t& width, size_t& height ) { width = resolution.width; height = resolution.height; } - - void OnPaint(); // Called by Windows when it receives a WM_PAINT message - - void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } - void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ); - void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ); - void Complete(); // Called by drawing thread to submit a frame - - void Process(); // Called by rendering thread to do window processing - - void AssociateSurface( void* surface ); - - void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ); - void addText( float x, float y, float r, float g, float b, OVR::String text ); - - static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } - static int WindowCount() { return windowCount; } - -private: - - Ptr<Frame> lastUnreadyFrame(); - - static const int MaxWindows = 4; - static ImageWindow* globalWindow[MaxWindows]; - static int windowCount; - static ID2D1Factory* pD2DFactory; - static IDWriteFactory* pDWriteFactory; - static HINSTANCE hInstD2d1; - static HINSTANCE hInstDwrite; - -}; - -#else - -class ImageWindow -{ -public: - // constructors - ImageWindow() {} - ImageWindow( uint32_t width, uint32_t height ) { OVR_UNUSED( width ); OVR_UNUSED( height ); } - virtual ~ImageWindow() { } - - void GetResolution( size_t& width, size_t& height ) { width = 0; height = 0; } - - void OnPaint() { } - - void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } - void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) { OVR_UNUSED( imageData ); OVR_UNUSED( width ); OVR_UNUSED( height ); } - void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) { OVR_UNUSED( imageData ); OVR_UNUSED( width ); OVR_UNUSED( height ); OVR_UNUSED( pitch ); } - void Complete() { } - - void Process() { } - - void AssociateSurface( void* surface ) { OVR_UNUSED(surface); } - - void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ) { OVR_UNUSED( x ); OVR_UNUSED( y ); OVR_UNUSED( radius ); OVR_UNUSED( r ); OVR_UNUSED( g ); OVR_UNUSED( b ); OVR_UNUSED( fill ); } - void addText( float x, float y, float r, float g, float b, OVR::String text ) { OVR_UNUSED( x ); OVR_UNUSED( y ); OVR_UNUSED( r ); OVR_UNUSED( g ); OVR_UNUSED( b ); OVR_UNUSED( text ); } - - static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } - static int WindowCount() { return windowCount; } - -private: - - static const int MaxWindows = 4; - static ImageWindow* globalWindow[4]; - static int windowCount; -}; - -#endif - -}} // namespace OVR::Util - - -#endif diff --git a/LibOVR/Src/Util/Util_Interface.h b/LibOVR/Src/Util/Util_Interface.h index ab08715..eb2257f 100644 --- a/LibOVR/Src/Util/Util_Interface.h +++ b/LibOVR/Src/Util/Util_Interface.h @@ -29,7 +29,7 @@ limitations under the License. #ifndef OVR_Util_Interface_h #define OVR_Util_Interface_h -#include "../OVR_CAPI.h" +#include "OVR_CAPI.h" //Files left in to ease its possible return...... diff --git a/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp b/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp index e34bf19..6131c30 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp +++ b/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp @@ -63,7 +63,7 @@ FrameTimeRecordSet::FrameTimeRecordSet() void FrameTimeRecordSet::AddValue(int readValue, double timeSeconds) { Records[NextWriteIndex].ReadbackIndex = readValue; - Records[NextWriteIndex].TimeSeconds = timeSeconds; + Records[NextWriteIndex].TimeSeconds = timeSeconds; NextWriteIndex++; if (NextWriteIndex == RecordCount) NextWriteIndex = 0; @@ -110,7 +110,7 @@ void RecordStateReader::GetRecordSet(FrameTimeRecordSet& recordset) return; } - recordset = Updater->SharedLatencyTestState.GetState(); + recordset = Updater->LatencyTest.GetState(); return; } diff --git a/LibOVR/Src/Util/Util_LatencyTest2Reader.h b/LibOVR/Src/Util/Util_LatencyTest2Reader.h index 1863e62..fb7e5cb 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2Reader.h +++ b/LibOVR/Src/Util/Util_LatencyTest2Reader.h @@ -27,7 +27,7 @@ limitations under the License. #ifndef OVR_Util_LatencyTest2Reader_h #define OVR_Util_LatencyTest2Reader_h -#include "../Tracking/Tracking_SensorState.h" +#include "Vision/SensorFusion/Vision_SensorState.h" #include "Util_LatencyTest2State.h" namespace OVR { namespace Util { @@ -40,7 +40,7 @@ namespace OVR { namespace Util { class RecordStateReader : public NewOverrideBase { protected: - const Tracking::CombinedSharedStateUpdater* Updater; + const Vision::CombinedHmdUpdater* Updater; public: RecordStateReader() @@ -49,7 +49,7 @@ public: } // Initialize the updater - void SetUpdater(const Tracking::CombinedSharedStateUpdater *updater) + void SetUpdater(const Vision::CombinedHmdUpdater *updater) { Updater = updater; } diff --git a/LibOVR/Src/Util/Util_LatencyTest2State.h b/LibOVR/Src/Util/Util_LatencyTest2State.h index 0b4ffd6..ced3d70 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2State.h +++ b/LibOVR/Src/Util/Util_LatencyTest2State.h @@ -27,7 +27,7 @@ limitations under the License. #ifndef OVR_Util_LatencyTest2_State_h #define OVR_Util_LatencyTest2_State_h -#include "../Kernel/OVR_Lockless.h" +#include "Kernel/OVR_Lockless.h" namespace OVR { namespace Util { @@ -45,10 +45,11 @@ enum LatencyTester2Constants // FrameTimeRecord // Describes frame scan-out time used for latency testing. -struct FrameTimeRecord +struct OVR_ALIGNAS(8) FrameTimeRecord { - int ReadbackIndex; - double TimeSeconds; + int32_t ReadbackIndex; + int32_t Pad; + double TimeSeconds; // Utility functions to convert color to readBack indices and back. // The purpose of ReadbackIndex is to allow direct comparison by value. @@ -63,14 +64,15 @@ struct FrameTimeRecord // FrameTimeRecordSet is a container holding multiple consecutive frame timing records // returned from the lock-less state. Used by FrameTimeManager. -struct FrameTimeRecordSet +struct OVR_ALIGNAS(8) FrameTimeRecordSet { enum { RecordCount = 4, RecordMask = RecordCount - 1 }; FrameTimeRecord Records[RecordCount]; - int NextWriteIndex; + int32_t NextWriteIndex; + int32_t Pad4; FrameTimeRecordSet(); @@ -88,9 +90,6 @@ struct FrameTimeRecordSet bool IsAllZeroes() const; }; -typedef LocklessUpdater<FrameTimeRecordSet, FrameTimeRecordSet> LockessRecordUpdater; - - }} // namespace OVR::Util #endif // OVR_Util_LatencyTest2_State_h diff --git a/LibOVR/Src/Util/Util_MatFile.cpp b/LibOVR/Src/Util/Util_MatFile.cpp new file mode 100644 index 0000000..f17e269 --- /dev/null +++ b/LibOVR/Src/Util/Util_MatFile.cpp @@ -0,0 +1,496 @@ +/************************************************************************************ + +Filename : Util_MatFile.cpp +Content : Matlab .MAT file access functions +Created : June 1, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 + +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 "Util_MatFile.h" + +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_Alg.h" +#include "Kernel/OVR_Std.h" + +OVR_DISABLE_MSVC_WARNING(4996) // 'fopen': This function or variable may be unsafe. Consider using fopen_s inst + + +namespace OVR { namespace Util { + +using namespace OVR::Alg; + + +// Data structures relating to MATLAB .MAT binary files +#define FX_FORM_IEEE_LE 0000u +#define FX_FORM_IEEE_BE 1000u +#define FX_FORM_VAX_D_FLOAT 2000u +#define FX_FORM_VAX_G_FLOAT 3000u +#define FX_FORM_CRAY 4000u +#define FX_FORM(type) ((((type) / 1000u) % 10u) * 1000u) + +#define FX_PREC_UINT8 50u +#define FX_PREC_INTU 40u +#define FX_PREC_INTS 30u +#define FX_PREC_LONG 20u +#define FX_PREC_SINGLE 10u +#define FX_PREC_DOUBLE 00u +#define FX_PREC(type) ((((type) / 10u) % 10u) * 10u) + +// Note that the elements of a text matrix are stored as floating-point numbers +// between 0 and 255 representing ASCII-encoded characters. +#define FX_MAT_NUMERIC 0u +#define FX_MAT_TEXT 1u +#define FX_MAT_SPARSE 2u +#define FX_MAT(type) ((type) % 10u) + +struct Fmatrix +{ + uint32_t type; // Type - see #defines + uint32_t mrows; // Row dimension - NOTE: Column dimension for C Arrays! + uint32_t ncols; // Column dimension - NOTE: Row dimension for C Arrays! + uint32_t imagf; // 1=complex, 0=real + uint32_t namelen; // length including zero terminator +}; + + +uint32_t MatFile::GetMatlabType(ValueType type, size_t& valueSize) +{ + switch (type) + { + case ByteValue: valueSize = sizeof(uint8_t); return FX_PREC_UINT8; + case UInt16Value: valueSize = sizeof(uint16_t); return FX_PREC_INTU; + case Int16Value: valueSize = sizeof(int16_t); return FX_PREC_INTS; + case UInt32Value: valueSize = sizeof(uint32_t); return FX_PREC_LONG; // Not directly supported by matlab! + case Int32Value: valueSize = sizeof(int32_t); return FX_PREC_LONG; + case FloatValue: valueSize = sizeof(float); return FX_PREC_SINGLE; + case DoubleValue: valueSize = sizeof(double); return FX_PREC_DOUBLE; + case StringValue: valueSize = sizeof(char); return FX_MAT_TEXT; // special case for string arrays + default: + OVR_ASSERT(false); + valueSize = 0; + return 0; + } +} + +MatFile::ValueType MatFile::GetValueType(uint32_t matlabType, size_t& valueSize) +{ + switch (matlabType) + { + case FX_PREC_UINT8: valueSize = sizeof(uint8_t); return ByteValue; + case FX_PREC_INTU: valueSize = sizeof(uint16_t); return UInt16Value; + case FX_PREC_INTS: valueSize = sizeof(int16_t); return Int16Value; + case FX_PREC_LONG: valueSize = sizeof(int32_t); return Int32Value; + case FX_PREC_SINGLE: valueSize = sizeof(float); return FloatValue; + case FX_PREC_DOUBLE: valueSize = sizeof(double); return DoubleValue; + case FX_MAT_TEXT: valueSize = sizeof(char); return StringValue; + default: + OVR_ASSERT(false); + valueSize = 0; + return UnknownValue; + } +} + +MatFile::MatFile(void) +{ + m_f = NULL; +} + +MatFile::~MatFile(void) +{ + if (m_f) + fclose(m_f); + m_f = NULL; +} + +// Matlab arrays are stored column-major, while C/C++ arrays are stored row-major. +// This means that a C array appears to Matlab transposed, and vice versa. +// To deal with this we swap the row and column values stored in the Matlab matrix header. + +bool MatFile::Open(const char* pszFile, bool write) +{ + OVR_ASSERT(!m_f); + m_f = fopen(pszFile, write ? "wb" : "rb"); + return (m_f != nullptr); +} + +void MatFile::Close() +{ + if (m_f) + { + fclose(m_f); + m_f = NULL; + } +} + +int MatFile::ReadString(const char* name, char* text, size_t maxTextSize) +{ + int rows, cols; + ValueType valueType; + + maxTextSize = Alg::Min(maxTextSize, INT_MAX/sizeof(double)/2); + + if (!GetMatrixInfo(name, valueType, rows, cols)) + return 0; + + if (valueType != StringValue) + return 0; + + int count = rows * cols; // character count, not including zero terminator + + double* doubles = new double[count]; + ReadMatrixValues(doubles, StringValue, count, 1); + + if (maxTextSize > 0 && count > 0) + { + count = (int)Alg::Min(count, (int)(maxTextSize-1)); + for (int i = 0; i < count; i++) + text[i] = (char)doubles[i]; + text[count] = 0; // Always zero terminate + } + + delete[] doubles; + + return count; +} + +bool MatFile::WriteString(const char* name, const char* string) +{ + int length = (int)Alg::Min(strlen(string), INT_MAX/sizeof(double)/2); + + double* doubles = new double[length]; + for (int i = 0; i < length; i++) + doubles[i] = (double)((unsigned char)string[i]); + + bool ok = WriteMatrix(name, doubles, StringValue, (int)length, 1); + + delete[] doubles; + + return ok; +} + +void* MatFile::ReadMatrix(const char* name, ValueType valueType, int& rows, int& cols) +{ + ValueType fileValueType; + if (!GetMatrixInfo(name, fileValueType, rows, cols)) + return NULL; + + int valueCount = rows * cols; + + void* values = NULL; + switch (fileValueType) + { + case StringValue: // Text matrices are stored as doubles + case DoubleValue: + values = new double[valueCount]; + break; + case FloatValue: + values = new float[valueCount]; + break; + case ByteValue: + values = new uint8_t[valueCount]; + break; + case Int16Value: + values = new int16_t[valueCount]; + break; + case UInt16Value: + values = new uint16_t[valueCount]; + break; + case Int32Value: + /*case UInt32Value: -- not directly supported by matlab -v4 files */ + values = new int32_t[valueCount]; + break; + default: + OVR_ASSERT(false); + return NULL; + } + + bool ok = ReadMatrixValues(values, fileValueType, rows, cols); + + if (ok) + values = ConvertVector(values, valueCount, fileValueType, valueType); + + if (!ok) + { + delete[] (char*)values; + values = NULL; + } + + OVR_ASSERT(values); + return values; +} + +void* MatFile::ConvertVector(void* fromValues, int valueCount, ValueType fromType, ValueType toType) +{ + // Special case: Always convert characters stored as doubles to a char array + if (fromType == StringValue) + fromType = DoubleValue; + + if (fromType == toType) + return fromValues; + + // UInt32 values are stored as Int32 values by Matlab + if (fromType == Int32Value && toType == UInt32Value) + return fromValues; + + // When a .mat file is saved by Matlab, many datatypes are converted to double. + // We support conversion of doubles to some other types: float, long, byte, char + // and strings and floats to doubles. + // convert singles to doubles + bool ok = true; + if (fromType == DoubleValue) + { + const double* fromDoubles = (const double*)fromValues; + if (toType == FloatValue) + { + float* newValues = new float[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (float)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == Int32Value) + { + int32_t* newValues = new int32_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (int32_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == UInt32Value) + { + uint32_t* newValues = new uint32_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (uint32_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == Int16Value) + { + int16_t* newValues = new int16_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (int16_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == UInt16Value) + { + uint16_t* newValues = new uint16_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (uint16_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == ByteValue) + { + uint8_t* newValues = new uint8_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (uint8_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == StringValue) + { + char* newValues = new char[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (char)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else + { + // unsupported type conversion + ok = false; + } + } + else + { + ok = false; // only conversions from doubles supported + } + + if (!ok) + { + OVR_ASSERT(false); + delete[] (char*)fromValues; + fromValues = NULL; + } + + return fromValues; +} + +bool MatFile::GetMatrixInfo(const char* name, ValueType& valueType, int& rows, int& cols) +{ + OVR_ASSERT(m_f); + fseek(m_f, 0, SEEK_SET); // rewind to start of file + + static const int maxVarNameLen = 255; + char varName[maxVarNameLen+1]; + + while (ReadMatrixInfo(varName, maxVarNameLen, valueType, rows, cols)) + { + if (OVR_stricmp(name, varName) == 0) + return true; + // skip over data to next one + ReadMatrixValues(NULL, valueType, rows, cols); + } + + return false; +} + +bool MatFile::ReadMatrixInfo(char name[], size_t maxNameSize, ValueType& valueType, int& rows, int& cols) +{ + if (name && maxNameSize > 0) + name[0] = 0; + + valueType = UnknownValue; + rows = 0; + cols = 0; + + OVR_ASSERT(m_f); + if (!m_f) + return false; + + Fmatrix header; + if (fread(&header, sizeof(header), 1, m_f) != 1) + return false; + + // Read transpose of row and column values stored in the file + cols = header.mrows; + rows = header.ncols; + + if (FX_FORM(header.type) != FX_FORM_IEEE_LE) + { + OVR_ASSERT(false); + return false; + } + + // Imaginary not supported + if (header.imagf != 0) + { + OVR_ASSERT(false); + return false; + } + + // sparse matrices not supported + if (FX_MAT(header.type) == FX_MAT_SPARSE) + { + OVR_ASSERT(false); + return false; + } + + // Special case for strings as text matrixes: they are stored as doubles(!) + if (FX_MAT(header.type) == FX_MAT_TEXT) + { + valueType = StringValue; + } + else + { + // only numeric types supported + if (FX_MAT(header.type) != FX_MAT_NUMERIC) + { + OVR_ASSERT(false); + return false; + } + size_t valueSize; + valueType = GetValueType(FX_PREC(header.type), valueSize); + } + + // Read in name + OVR_ASSERT(maxNameSize >= header.namelen); + if (maxNameSize < header.namelen) + return false; + + if (fread(name, sizeof(char), header.namelen, m_f) != header.namelen) + return false; + + return true; +} + +bool MatFile::ReadMatrixValues(void* values, ValueType valueType, int rows, int cols) +{ + OVR_ASSERT(m_f); + if (!m_f) + return false; + + OVR_ASSERT(rows*cols > 0); + + size_t valueCount = (size_t)(rows * cols); + size_t valueSize = 0; + GetMatlabType(valueType, valueSize); + if (valueSize == 0) + return false; + + // If no values pointer specified, skip over data without reading + if (!values) + { + if (fseek(m_f, (long)(valueSize * valueCount), SEEK_CUR) != 0) + return false; + } + else + { + if (fread(values, valueSize, valueCount, m_f) != valueCount) + return false; + } + + return true; +} + +bool MatFile::WriteMatrix(const char* name, const void* values, ValueType valueType, int rows, int cols) +{ + if (!m_f) + return false; + + OVR_ASSERT(rows*cols > 0); + + size_t valueCount = (size_t)(rows * cols); + size_t valueSize = 0; + uint32_t matlabType = GetMatlabType(valueType, valueSize); + if (valueSize == 0) + return false; + + Fmatrix header; + if (valueType == StringValue) + { + header.type = (FX_FORM_IEEE_LE + FX_MAT_TEXT); + } + else + { + header.type = (FX_FORM_IEEE_LE + FX_MAT_NUMERIC) + matlabType; + } + + // NOTE: We store transposed dimensions! + header.mrows = cols; + header.ncols = rows; + header.imagf = 0; + header.namelen = (uint32_t)(strlen(name) + 1); + OVR_ASSERT(header.namelen > 1); + + if (fwrite(&header, sizeof(header), 1, m_f) != 1) + return false; + if (fwrite(name, sizeof(char), header.namelen, m_f) != header.namelen) + return false; + if (fwrite(values, valueSize, valueCount, m_f) != valueCount) + return false; + + return true; +} + + +}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_MatFile.h b/LibOVR/Src/Util/Util_MatFile.h new file mode 100644 index 0000000..8b763a2 --- /dev/null +++ b/LibOVR/Src/Util/Util_MatFile.h @@ -0,0 +1,116 @@ +/************************************************************************************ + +Filename : Util_MatFile.h +Content : Matlab .MAT file access functions +Created : June 1, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 + +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. + +*************************************************************************************/ + +#ifndef OVR_Util_MatFile_h +#define OVR_Util_MatFile_h + +#include "Kernel/OVR_Types.h" + +#include <stdint.h> +#include <stdio.h> + +// Read and write MatLab .MAT data files, in MatLab Version 4 format +namespace OVR { namespace Util { + + +class MatFile +{ +public: + MatFile(); + ~MatFile(void); + + bool Open(const char* pszFile, bool write); + void Close(); + + // Matrix element value types + enum ValueType { + UnknownValue = 0, + ByteValue = 1, + UInt16Value = 2, + Int16Value = 3, + UInt32Value = 4, // NOTE: Matlab -v4 don't support UInt32 directly: values stored as Int32. + Int32Value = 5, + FloatValue = 6, + DoubleValue = 7, + StringValue = 8 + }; + + // NOTE: A stored matrix is TRANSPOSED when read into MatLab + // MatLab uses Fortran column-major matrix storage conventions + + // Write a matrix, organized as rows x columns + // Vectors should be written with 1 column: they will appear in Matlab as a 1-row matrix. + // NOTE: this function reads StringValue matrices as an array of doubles (!) + bool WriteMatrix(const char* name, const void* values, ValueType valueType, int rows, int cols); + + bool WriteMatrix(const char* name, const uint8_t* values, int rows, int cols = 1) { return WriteMatrix(name, values, ByteValue, rows, cols); } + bool WriteMatrix(const char* name, const uint16_t* values, int rows, int cols = 1){ return WriteMatrix(name, values, UInt16Value, rows, cols); } + bool WriteMatrix(const char* name, const int16_t* values, int rows, int cols = 1) { return WriteMatrix(name, values, Int16Value, rows, cols); } + bool WriteMatrix(const char* name, const int32_t* values, int rows, int cols = 1) { return WriteMatrix(name, values, Int32Value, rows, cols); } + bool WriteMatrix(const char* name, const float* values, int rows, int cols = 1) { return WriteMatrix(name, values, FloatValue, rows, cols); } + bool WriteMatrix(const char* name, const double* values, int rows, int cols = 1) { return WriteMatrix(name, values, DoubleValue, rows, cols); } + bool WriteString(const char* name, const char* value); + + // NOTE: Matlab doesn't directly support uint32_t type: these values are saved and loaded as Int32Values + bool WriteMatrix(const char* name, const uint32_t* values, int rows, int cols = 1){ return WriteMatrix(name, values, Int32Value, rows, cols); } + + bool GetMatrixInfo(const char* name, ValueType& valueType, int& rows, int& cols); + + uint8_t* ReadByteMatrix(const char* name, int& rows, int& cols) { return (uint8_t*)ReadMatrix(name, ByteValue, rows, cols); } + uint16_t* ReadUInt16Matrix(const char* name, int& rows, int& cols) { return (uint16_t*)ReadMatrix(name, UInt16Value, rows, cols); } + int16_t* ReadInt16Matrix(const char* name, int& rows, int& cols) { return (int16_t*)ReadMatrix(name, Int16Value, rows, cols); } + int32_t* ReadInt32Matrix(const char* name, int& rows, int& cols) { return (int32_t*)ReadMatrix(name, Int32Value, rows, cols); } + float* ReadFloatMatrix(const char* name, int& rows, int& cols) { return (float*)ReadMatrix(name, FloatValue, rows, cols); } + double* ReadDoubleMatrix(const char* name, int& rows, int& cols) { return (double*)ReadMatrix(name, DoubleValue, rows, cols); } + + // NOTE: Matlab doesn't directly support uint32_t type: these values are saved and loaded as Int32Values + uint32_t* ReadUInt32Matrix(const char* name, int& rows, int& cols) { return (uint32_t*)ReadMatrix(name, Int32Value, rows, cols); } + + int ReadString(const char* name, char* string, size_t maxStringSize); + + // Read matrix values. This function performs (some) data type conversions to specified valueType in cases where data is stored in .mat file as doubles. + bool ReadMatrixValues(void* values, ValueType valueType, int rows, int cols); + +private: + static uint32_t GetMatlabType(ValueType valueType, size_t& valueSize); // returns Matlab FX_* type and size in bytes of data type element + static ValueType GetValueType(uint32_t matlabType, size_t& valueSize); + + // Read a matrix, organized as column-major rows x columns. Caller must delete returned vectors + void* ReadMatrix(const char* name, ValueType valueType, int& rows, int& cols); + + // Read next matrix name, value type, and dimensions + bool ReadMatrixInfo(char name[/*maxNameSize*/], size_t maxNameSize, ValueType& valueType, int& rows, int& cols); + + void* ConvertVector(void* fromValues, int valueCount, ValueType fromType, ValueType toType); + +private: + FILE* m_f; +}; + + +}} // namespace OVR::Util + +#endif // OVR_Util_MatFile_h diff --git a/LibOVR/Src/Util/Util_Render_Stereo.cpp b/LibOVR/Src/Util/Util_Render_Stereo.cpp index aa82b35..e60f5bd 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.cpp +++ b/LibOVR/Src/Util/Util_Render_Stereo.cpp @@ -28,9 +28,13 @@ limitations under the License. namespace OVR { namespace Util { namespace Render { -using namespace OVR::Tracking; +using namespace OVR::Vision; +#if defined (OVR_CC_MSVC) +static_assert(sizeof(DistortionMeshVertexData) == sizeof(ovrDistortionVertex), "DistortionMeshVertexData size mismatch"); +#endif + //----------------------------------------------------------------------------------- // **** Useful debug functions. @@ -51,8 +55,10 @@ char const* GetDebugNameEyeCupType ( EyeCupType eyeCupType ) case EyeCup_JamesA: return "James A"; case EyeCup_SunMandalaA: return "Sun Mandala A"; case EyeCup_DK2A: return "DK2 A"; + case EyeCup_BlackStar: return "BlackStar"; + case EyeCup_EVTProto: return "EVT A"; case EyeCup_LAST: return "LAST"; - default: OVR_ASSERT ( false ); return "Error"; + default: OVR_ASSERT ( false ); return "Error"; break; } } @@ -68,9 +74,11 @@ char const* GetDebugNameHmdType ( HmdTypeEnum hmdType ) case HmdType_DKHD2Proto: return "DK HD prototype 585"; case HmdType_CrystalCoveProto: return "Crystal Cove"; case HmdType_DK2: return "DK2"; + case HmdType_BlackStar: return "BlackStar"; + case HmdType_CB: return "Crescent Bay"; case HmdType_Unknown: return "Unknown"; case HmdType_LAST: return "LAST"; - default: OVR_ASSERT ( false ); return "Error"; + default: OVR_ASSERT ( false ); return "Error"; } } @@ -180,7 +188,8 @@ static StereoEyeParams CalculateStereoEyeParamsInternal ( StereoEye eyeType, Hmd FovPort const &fov, Sizei const &actualRendertargetSurfaceSize, Recti const &renderedViewport, - bool bRightHanded = true, float zNear = 0.01f, float zFar = 10000.0f, + bool bRightHanded = true, bool isOpenGL = false, + float zNear = 0.01f, float zFar = 10000.0f, bool bMonoRenderingMode = false, float zoomFactor = 1.0f ) { @@ -192,7 +201,7 @@ static StereoEyeParams CalculateStereoEyeParamsInternal ( StereoEye eyeType, Hmd zoomedFov.RightTan *= fovScale; zoomedFov.UpTan *= fovScale; zoomedFov.DownTan *= fovScale; - Matrix4f projection = CreateProjection ( bRightHanded, zoomedFov, zNear, zFar ); + Matrix4f projection = CreateProjection ( bRightHanded, isOpenGL, zoomedFov, eyeType, zNear, zFar ); // Find the mapping from TanAngle space to target NDC space. // Note this does NOT take the zoom factor into account because @@ -280,6 +289,7 @@ StereoEyeParams CalculateStereoEyeParams ( HmdRenderInfo const &hmd, Sizei const &actualRendertargetSurfaceSize, bool bRendertargetSharedByBothEyes, bool bRightHanded /*= true*/, + bool bOpenGL /*= false*/, float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, Sizei const *pOverrideRenderedPixelSize /* = NULL*/, FovPort const *pOverrideFovport /*= NULL*/, @@ -309,7 +319,7 @@ StereoEyeParams CalculateStereoEyeParams ( HmdRenderInfo const &hmd, distortionAndFov.Distortion, distortionAndFov.Fov, actualRendertargetSurfaceSize, viewport, - bRightHanded, zNear, zFar, false, zoomFactor ); + bRightHanded, bOpenGL, zNear, zFar, false, zoomFactor ); } @@ -416,6 +426,7 @@ StereoConfig::StereoConfig(StereoMode mode) ExtraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION; IsRendertargetSharedByBothEyes = true; RightHandedProjection = true; + UsingOpenGL = false; // This should cause an assert if the app does not call SetRendertargetSize() RendertargetSize = Sizei ( 0, 0 ); @@ -507,12 +518,14 @@ void StereoConfig::SetZeroVirtualIpdOverride ( bool enableOverride ) } -void StereoConfig::SetZClipPlanesAndHandedness ( float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, bool rightHandedProjection /*= true*/ ) +void StereoConfig::SetZClipPlanesAndHandedness ( float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, + bool rightHandedProjection /*= true*/, bool isOpenGL /*= false*/ ) { DirtyFlag = true; ZNear = zNear; ZFar = zFar; RightHandedProjection = rightHandedProjection; + UsingOpenGL = isOpenGL; } void StereoConfig::SetExtraEyeRotation ( float extraEyeRotationInRadians ) @@ -620,7 +633,7 @@ void StereoConfig::UpdateComputedState() EyeRenderParams[eyeNum].StereoEye = CalculateStereoEyeParamsInternal ( eyeType, Hmd, localDistortion, fov, RendertargetSize, tempViewport, - RightHandedProjection, ZNear, ZFar, + RightHandedProjection, UsingOpenGL, ZNear, ZFar, OverrideZeroIpd ); // We want to create a virtual 2D surface we can draw debug text messages to. @@ -771,7 +784,7 @@ Matrix4f StereoConfig::GetProjectionWithZoom ( StereoEye eye, float fovZoom ) co fovPort.RightTan *= fovScale; fovPort.UpTan *= fovScale; fovPort.DownTan *= fovScale; - return CreateProjection ( RightHandedProjection, fovPort, ZNear, ZFar ); + return CreateProjection ( RightHandedProjection, UsingOpenGL, fovPort, eye, ZNear, ZFar ); } @@ -799,12 +812,6 @@ DistortionMeshVertexData DistortionMeshMakeVertex ( Vector2f screenNDC, { DistortionMeshVertexData result; - float xOffset = 0.0f; - if (rightEye) - { - xOffset = 1.0f; - } - Vector2f tanEyeAnglesR, tanEyeAnglesG, tanEyeAnglesB; TransformScreenNDCToTanFovSpaceChroma ( &tanEyeAnglesR, &tanEyeAnglesG, &tanEyeAnglesB, distortion, screenNDC ); @@ -878,8 +885,32 @@ DistortionMeshVertexData DistortionMeshMakeVertex ( Vector2f screenNDC, // Note - this is NOT clamped negatively. // For rendering methods that interpolate over a coarse grid, we need the values to go negative for correct intersection with zero. result.Shade = Alg::Min ( edgeFadeIn, 1.0f ); - result.ScreenPosNDC.x = 0.5f * screenNDC.x - 0.5f + xOffset; - result.ScreenPosNDC.y = -screenNDC.y; + + float eyeOffset = rightEye ? 1.0f : 0.0f; + float xOffset = 0.5f * screenNDC.x - 0.5f + eyeOffset; + float yOffset = -screenNDC.y; + + // Rotate the mesh to match screen orientation. + if (hmdRenderInfo.Rotation == 270) + { + result.ScreenPosNDC.x = -yOffset; + result.ScreenPosNDC.y = xOffset; + } + else if (hmdRenderInfo.Rotation == 0) + { + result.ScreenPosNDC.x = xOffset; + result.ScreenPosNDC.y = yOffset; + } + else if (hmdRenderInfo.Rotation == 180) + { + result.ScreenPosNDC.x = -xOffset; + result.ScreenPosNDC.y = -yOffset; + } + else if (hmdRenderInfo.Rotation == 90) + { + result.ScreenPosNDC.x = yOffset; + result.ScreenPosNDC.y = -xOffset; + } return result; } @@ -1345,6 +1376,10 @@ Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorl return matRenderXform.Inverted(); } + +#if defined(OVR_ENABLE_TIMEWARP_MACHINE) +// This is deprecated by DistortionTiming code. -cat + TimewarpMachine::TimewarpMachine() : VsyncEnabled(false), RenderInfo(), @@ -1409,7 +1444,7 @@ double TimewarpMachine::GetViewRenderPredictionTime() return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToRenderedScene; } -bool TimewarpMachine::GetViewRenderPredictionPose(SensorStateReader* reader, Posef& pose) +bool TimewarpMachine::GetViewRenderPredictionPose(TrackingStateReader* reader, Posef& pose) { return reader->GetPoseAtTime(GetViewRenderPredictionTime(), pose); } @@ -1424,15 +1459,15 @@ double TimewarpMachine::GetVisiblePixelTimeEnd() // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us. return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToTimewarpEnd; } -bool TimewarpMachine::GetPredictedVisiblePixelPoseStart(SensorStateReader* reader, Posef& pose) +bool TimewarpMachine::GetPredictedVisiblePixelPoseStart(TrackingStateReader* reader, Posef& pose) { return reader->GetPoseAtTime(GetVisiblePixelTimeStart(), pose); } -bool TimewarpMachine::GetPredictedVisiblePixelPoseEnd(SensorStateReader* reader, Posef& pose) +bool TimewarpMachine::GetPredictedVisiblePixelPoseEnd(TrackingStateReader* reader, Posef& pose) { return reader->GetPoseAtTime(GetVisiblePixelTimeEnd(), pose); } -bool TimewarpMachine::GetTimewarpDeltaStart(SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform) +bool TimewarpMachine::GetTimewarpDeltaStart(TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform) { Posef visiblePose; if (!GetPredictedVisiblePixelPoseStart(reader, visiblePose)) @@ -1447,7 +1482,7 @@ bool TimewarpMachine::GetTimewarpDeltaStart(SensorStateReader* reader, Posef con return true; } -bool TimewarpMachine::GetTimewarpDeltaEnd(SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform) +bool TimewarpMachine::GetTimewarpDeltaEnd(TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform) { Posef visiblePose; if (!GetPredictedVisiblePixelPoseEnd(reader, visiblePose)) @@ -1549,6 +1584,8 @@ void TimewarpMachine::JustInTime_AfterDistortionTimeMeasurement(double timeNo } } +#endif // OVR_ENABLE_TIMEWARP_MACHINE + }}} // OVR::Util::Render diff --git a/LibOVR/Src/Util/Util_Render_Stereo.h b/LibOVR/Src/Util/Util_Render_Stereo.h index 2ac863c..7eb016c 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.h +++ b/LibOVR/Src/Util/Util_Render_Stereo.h @@ -27,8 +27,9 @@ limitations under the License. #ifndef OVR_Util_Render_Stereo_h #define OVR_Util_Render_Stereo_h -#include "../OVR_Stereo.h" -#include "../Tracking/Tracking_SensorStateReader.h" +#include "OVR_Stereo.h" +#include "Extras/OVR_Math.h" +#include "Vision/SensorFusion/Vision_SensorStateReader.h" namespace OVR { namespace Util { namespace Render { @@ -218,7 +219,7 @@ public: // Allows the app to specify near and far clip planes and the right/left-handedness of the projection matrix. void SetZClipPlanesAndHandedness ( float zNear = 0.01f, float zFar = 10000.0f, - bool rightHandedProjection = true ); + bool rightHandedProjection = true, bool isOpenGL = false ); // Allows the app to specify how much extra eye rotation to allow when determining the visible FOV. void SetExtraEyeRotation ( float extraEyeRotationInRadians = 0.0f ); @@ -291,6 +292,7 @@ private: float ExtraEyeRotationInRadians; bool IsRendertargetSharedByBothEyes; bool RightHandedProjection; + bool UsingOpenGL; // for projection clip depth calculation bool DirtyFlag; // Set when any if the modifiable state changed. Does NOT get set by SetRender*() @@ -415,6 +417,8 @@ Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matri Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&hmdToEyeViewOffset ); +#if defined(OVR_ENABLE_TIMEWARP_MACHINE) +// This is deprecated by DistortionTiming code. -cat // TimewarpMachine helps keep track of rendered frame timing and // handles predictions for time-warp rendering. @@ -438,7 +442,7 @@ public: // and the predicted pose of the HMD at that time. // You usually only need to call one of these functions. double GetViewRenderPredictionTime(); - bool GetViewRenderPredictionPose(Tracking::SensorStateReader* reader, Posef& transform); + bool GetViewRenderPredictionPose(Vision::TrackingStateReader* reader, Posef& transform); // Timewarp prediction functions. You usually only need to call one of these three sets of functions. @@ -447,13 +451,13 @@ public: double GetVisiblePixelTimeStart(); double GetVisiblePixelTimeEnd(); // Predicted poses of the HMD at those first and last pixels. - bool GetPredictedVisiblePixelPoseStart(Tracking::SensorStateReader* reader, Posef& transform); - bool GetPredictedVisiblePixelPoseEnd(Tracking::SensorStateReader* reader, Posef& transform); + bool GetPredictedVisiblePixelPoseStart(Vision::TrackingStateReader* reader, Posef& transform); + bool GetPredictedVisiblePixelPoseEnd(Vision::TrackingStateReader* reader, Posef& transform); // The delta matrices to feed to the timewarp distortion code, // given the pose that was used for rendering. // (usually the one returned by GetViewRenderPredictionPose() earlier) - bool GetTimewarpDeltaStart(Tracking::SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform); - bool GetTimewarpDeltaEnd(Tracking::SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform); + bool GetTimewarpDeltaStart(Vision::TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform); + bool GetTimewarpDeltaEnd(Vision::TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform); // Just-In-Time distortion aims to delay the second sensor reading & distortion // until the very last moment to improve prediction. However, it is a little scary, @@ -493,6 +497,8 @@ private: }; +#endif // OVR_ENABLE_TIMEWARP_MACHINE + }}} // OVR::Util::Render diff --git a/LibOVR/Src/Util/Util_Stopwatch.h b/LibOVR/Src/Util/Util_Stopwatch.h new file mode 100644 index 0000000..912de6c --- /dev/null +++ b/LibOVR/Src/Util/Util_Stopwatch.h @@ -0,0 +1,139 @@ +/************************************************************************************ + +Filename : Util_Stopwatch.h +Content : Handy classes for making timing measurements +Created : June 1, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 + +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 "Kernel/OVR_Timer.h" + +// NOTE: This file is designed to be included in multiple .cpp files +// with different settings of OVR_DISABLE_STOPWATCH, +// so there is no include guard or #pragma once. + +namespace OVR { namespace Util { + +// Declare a StopwatchTimer as a static, global, or member variable. +// Then use Stopwatch() to accumulate timings within a scope. +/* + +static StopwatchTimer FooTimer("Foo", 37, .003); // Compute average of 37 timing samples, print timing if average time is greater than .003 seconds +static StopwatchTimer BarTimer("Bar"); // Print time of each measurement + +void SomeFunction() +{ + CodeNotToIncludeInTiming(); + + { + Stopwatch sw(FooTimer); // sw times everything in its scope + Foo(); + } // Every 37 times through the loop, if average time of Foo() is > .003 seconds, the average time is printed with LogText() + + { + Stopwatch sw(BarTimer); + Bar(); + } // Elapsed time of Bar() is printed every time + + MoreCodeNotToIncludeInTiming(); +} +*/ + +#ifndef OVR_DISABLE_STOPWATCH + +class StopwatchTimer +{ +public: + StopwatchTimer(const char* label, int printCount = 1, double printThreshold = 0.0) : + StartTime(0), + ElapsedTime(0), + Label(label), + SampleCount(0), + PrintCount(printCount), + PrintThreshold(printThreshold) + { + } + + inline void Start() + { + StartTime = Timer::GetSeconds(); + } + + inline void Stop() + { + ElapsedTime += Timer::GetSeconds() - StartTime; + if (++SampleCount >= PrintCount) + PrintAndReset(); + } + +private: + + void PrintAndReset() + { + double dt = ElapsedTime / SampleCount; + if (dt > PrintThreshold) + LogText("%s: %.5f msec\n", Label, dt * 1000); + + // reset for next time + ElapsedTime = 0; + SampleCount = 0; + } + + double StartTime; + double ElapsedTime; + const char* Label; + int SampleCount; + int PrintCount; + double PrintThreshold; +}; + + +class Stopwatch +{ +public: + inline Stopwatch(StopwatchTimer& timer) : Timer(&timer) { Timer->Start(); } + inline ~Stopwatch() { Timer->Stop(); } +private: + StopwatchTimer* Timer; +}; + +#else // !OVR_DISABLE_STOPWATCH + +// Non-invasive, zero-code stopwatch implementation + +class StopwatchTimer +{ +public: + inline StopwatchTimer(const char* label, int printCount = 1, double printThreshold = 0.0) {} + inline void Start() {} + inline void Stop() {} +}; + +class Stopwatch +{ +public: + inline Stopwatch(StopwatchTimer& timer) {} + inline ~Stopwatch() {} +}; + +#endif // OVR_DISABLE_STOPWATCH + +}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_SystemGUI.cpp b/LibOVR/Src/Util/Util_SystemGUI.cpp deleted file mode 100644 index 76eb890..0000000 --- a/LibOVR/Src/Util/Util_SystemGUI.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemGUI.cpp -Content : OS GUI access, usually for diagnostics. -Created : October 20, 2014 -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 - -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 "Util_SystemGUI.h" -#include "../Kernel/OVR_UTF8Util.h" -#include <stdio.h> - -#if defined(OVR_OS_MS) - #include <Windows.h> -#endif - - -namespace OVR { namespace Util { - - -#if defined(OVR_OS_MS) - - // On Windows we implement a manual dialog message box. The reason for this is that there's no way to - // have a message box like this without either using MFC or WinForms or relying on Windows Vista+. - - bool DisplayMessageBox(const char* pTitle, const char* pText) - { - #define ID_EDIT 100 - - struct Dialog - { - static size_t LineCount(const char* pText) - { - size_t count = 0; - while(*pText) - { - if(*pText++ == '\n') - count++; - } - return count; - } - - static WORD* WordUp(WORD* pIn){ return (WORD*)((((uintptr_t)pIn + 3) >> 2) << 2); } - - static BOOL CALLBACK Proc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) - { - switch (iMsg) - { - case WM_INITDIALOG: - { - HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); - - const char* pText = (const char*)lParam; - SetWindowTextA(hWndEdit, pText); - - HFONT hFont = CreateFontW(-11, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, L"Courier New"); - if(hFont) - SendMessage(hWndEdit, WM_SETFONT, WPARAM(hFont), TRUE); - - SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); - - return TRUE; - } - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case ID_EDIT: - { - // Handle messages from the edit control here. - HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); - SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); - return TRUE; - } - - case IDOK: - EndDialog(hDlg, 0); - return TRUE; - } - break; - } - - return FALSE; - } - }; - - - char dialogTemplateMemory[1024]; - memset(dialogTemplateMemory, 0, sizeof(dialogTemplateMemory)); - DLGTEMPLATE* pDlg = (LPDLGTEMPLATE)dialogTemplateMemory; - - const size_t textLineCount = Dialog::LineCount(pText); - - // Sizes are in Windows dialog units, which are relative to a character size. Depends on the font and environment settings. Often the pixel size will be ~3x the dialog unit x size. Often the pixel size will be ~3x the dialog unit y size. - const int kGutterSize = 6; // Empty border space around controls within the dialog - const int kButtonWidth = 24; - const int kButtonHeight = 10; - const int kDialogWidth = 600; // To do: Clip this against screen bounds. - const int kDialogHeight = ((textLineCount > 100) ? 400 : ((textLineCount > 25) ? 300 : 200)); - - // Define a dialog box. - pDlg->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION; - pDlg->cdit = 2; // Control count - pDlg->x = 10; // X position To do: Center the dialog. - pDlg->y = 10; - pDlg->cx = (short)kDialogWidth; - pDlg->cy = (short)kDialogHeight; - WORD* pWord = (WORD*)(pDlg + 1); - *pWord++ = 0; // No menu - *pWord++ = 0; // Default dialog box class - - WCHAR* pWchar = (WCHAR*)pWord; - const size_t titleLength = strlen(pTitle); - size_t wcharCount = OVR::UTF8Util::DecodeString(pWchar, pTitle, (titleLength > 128) ? 128 : titleLength); - pWord += wcharCount + 1; - - // Define an OK button. - pWord = Dialog::WordUp(pWord); - - DLGITEMTEMPLATE* pDlgItem = (DLGITEMTEMPLATE*)pWord; - pDlgItem->x = pDlg->cx - (kGutterSize + kButtonWidth); - pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight); - pDlgItem->cx = kButtonWidth; - pDlgItem->cy = kButtonHeight; - pDlgItem->id = IDOK; - pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - pWord = (WORD*)(pDlgItem + 1); - *pWord++ = 0xFFFF; - *pWord++ = 0x0080; // button class - - pWchar = (WCHAR*)pWord; - pWchar[0] = 'O'; pWchar[1] = 'K'; pWchar[2] = '\0'; // Not currently localized. - pWord += 3; // OK\0 - *pWord++ = 0; // no creation data - - // Define an EDIT contol. - pWord = Dialog::WordUp(pWord); - - pDlgItem = (DLGITEMTEMPLATE*)pWord; - pDlgItem->x = kGutterSize; - pDlgItem->y = kGutterSize; - pDlgItem->cx = pDlg->cx - (kGutterSize + kGutterSize); - pDlgItem->cy = pDlg->cy - (kGutterSize + kButtonHeight + kGutterSize + (kGutterSize / 2)); - pDlgItem->id = ID_EDIT; - pDlgItem->style = ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | ES_READONLY | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE; - - pWord = (WORD*)(pDlgItem + 1); - *pWord++ = 0xFFFF; - *pWord++ = 0x0081; // edit class atom - *pWord++ = 0; // no creation data - - LRESULT ret = DialogBoxIndirectParam(NULL, (LPDLGTEMPLATE)pDlg, NULL, (DLGPROC)Dialog::Proc, (LPARAM)pText); - - return (ret != 0); - } -#elif defined(OVR_OS_MAC) - // For Apple we use the Objective C implementation in Util_GUI.mm -#else - // To do. - bool DisplayMessageBox(const char* pTitle, const char* pText) - { - printf("\n\nMessageBox\n%s\n", pTitle); - printf("%s\n\n", pText); - return false; - } -#endif - - -} } // namespace OVR::Util - - - - diff --git a/LibOVR/Src/Util/Util_SystemGUI.h b/LibOVR/Src/Util/Util_SystemGUI.h deleted file mode 100644 index c6b8d6f..0000000 --- a/LibOVR/Src/Util/Util_SystemGUI.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemGUI.h -Content : OS GUI access, usually for diagnostics. -Created : October 20, 2014 -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 - -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. - -*************************************************************************************/ - -#ifndef OVR_Util_GUI_h -#define OVR_Util_GUI_h - - -namespace OVR { namespace Util { - - // Displays a modal message box on the default GUI display (not on a VR device). - // The message box interface (e.g. OK button) is not localized. - bool DisplayMessageBox(const char* pTitle, const char* pText); - - -} } // namespace OVR::Util - - -#endif diff --git a/LibOVR/Src/Util/Util_SystemGUI_OSX.mm b/LibOVR/Src/Util/Util_SystemGUI_OSX.mm deleted file mode 100644 index cbfd057..0000000 --- a/LibOVR/Src/Util/Util_SystemGUI_OSX.mm +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************************
-
-Filename : Util_SystemGUI.mm
-Content : OS GUI access, usually for diagnostics.
-Created : October 20, 2014
-Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
-
-Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2
-
-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 "Util_SystemGUI.h"
-
-#include <Cocoa/Cocoa.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-
-namespace OVR { namespace Util {
-
-
-bool DisplayMessageBox(const char* pTitle, const char* pText)
-{
- // To consider: Replace usage of CFUserNotificationDisplayAlert with something a little smarter.
-
- size_t titleLength = strlen(pTitle);
- size_t textLength = strlen(pText);
- if(textLength > 1500) // CFUserNotificationDisplayAlert isn't smart enough to handle large text sizes and screws up its size if so.
- textLength = 1500; // Problem: this can theoretically split a UTF8 multibyte sequence. Need to find a divisible boundary.
- CFAllocatorRef allocator = NULL; // To do: support alternative allocator.
- CFStringRef titleRef = CFStringCreateWithBytes(allocator, (const UInt8*)pTitle, (CFIndex)titleLength, kCFStringEncodingUTF8, false);
- CFStringRef textRef = CFStringCreateWithBytes(allocator, (const UInt8*)pText, (CFIndex)textLength, kCFStringEncodingUTF8, false);
- CFOptionFlags result;
-
- CFUserNotificationDisplayAlert(0, // No timeout
- kCFUserNotificationNoteAlertLevel,
- NULL, // Icon URL, use default.
- NULL, // Unused
- NULL, // Localization of strings
- titleRef, // Title text
- textRef, // Body text
- CFSTR("OK"), // Default "OK" text in button
- CFSTR("Cancel"), // Other button title
- NULL, // Yet another button title, NULL means no other button.
- &result); // response flags
- CFRelease(titleRef);
- CFRelease(textRef);
-
- return (result == kCFUserNotificationDefaultResponse);
-}
-
-
-} } // namespace OVR { namespace Util {
-
-
diff --git a/LibOVR/Src/Util/Util_SystemInfo.cpp b/LibOVR/Src/Util/Util_SystemInfo.cpp deleted file mode 100644 index 0fca243..0000000 --- a/LibOVR/Src/Util/Util_SystemInfo.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemInfo.cpp -Content : Various operations to get information about the system -Created : September 26, 2014 -Author : Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 - -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 "Util_SystemInfo.h" -#include "../Kernel/OVR_Timer.h" -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_Array.h" - -/* -// Disabled, can't link RiftConfigUtil -#ifdef OVR_OS_WIN32 -#define _WIN32_DCOM -#include <comdef.h> -#include <Wbemidl.h> - -# pragma comment(lib, "wbemuuid.lib") -#endif -*/ - - -namespace OVR { namespace Util { - -// From http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx -#if defined (OVR_OS_WIN64) || defined (OVR_OS_WIN32) - -#pragma comment(lib, "version.lib") - -typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); -BOOL Is64BitWindows() -{ -#if defined(_WIN64) - return TRUE; // 64-bit programs run only on Win64 -#elif defined(_WIN32) - // 32-bit programs run on both 32-bit and 64-bit Windows - // so must sniff - BOOL f64 = FALSE; - LPFN_ISWOW64PROCESS fnIsWow64Process; - - fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process"); - if (NULL != fnIsWow64Process) - { - return fnIsWow64Process(GetCurrentProcess(), &f64) && f64; - } - return FALSE; -#else - return FALSE; // Win64 does not support Win16 -#endif -} -#endif - -const char * OSAsString() -{ -#if defined (OVR_OS_IPHONE) - return "IPhone"; -#elif defined (OVR_OS_DARWIN) - return "Darwin"; -#elif defined (OVR_OS_MAC) - return "Mac"; -#elif defined (OVR_OS_BSD) - return "BSD"; -#elif defined (OVR_OS_WIN64) || defined (OVR_OS_WIN32) - if (Is64BitWindows()) - return "Win64"; - else - return "Win32"; -#elif defined (OVR_OS_ANDROID) - return "Android"; -#elif defined (OVR_OS_LINUX) - return "Linux"; -#elif defined (OVR_OS_BSD) - return "BSD"; -#else - return "Other"; -#endif -} - -uint64_t GetGuidInt() -{ - uint64_t g = Timer::GetTicksNanos(); - - uint64_t lastTime, thisTime; - int j; - // Sleep a small random time, then use the last 4 bits as a source of randomness - for (j = 0; j < 8; j++) - { - lastTime = Timer::GetTicksNanos(); - Thread::MSleep(1); - Thread::MSleep(0); - thisTime = Timer::GetTicksNanos(); - uint64_t diff = thisTime - lastTime; - unsigned int diff4Bits = (unsigned int)(diff & 15); - diff4Bits <<= 32 - 4; - diff4Bits >>= j * 4; - ((char*)&g)[j] ^= diff4Bits; - } - - return g; -} -String GetGuidString() -{ - uint64_t guid = GetGuidInt(); - - char buff[64]; -#if defined(OVR_CC_MSVC) - OVR_sprintf(buff, sizeof(buff), "%I64u", guid); -#else - OVR_sprintf(buff, sizeof(buff), "%llu", (unsigned long long) guid); -#endif - return String(buff); -} - -const char * GetProcessInfo() -{ - #if defined (OVR_CPU_X86_64 ) - return "64 bit"; -#elif defined (OVR_CPU_X86) - return "32 bit"; -#else - return "TODO"; -#endif -} -#ifdef OVR_OS_WIN32 - - -String OSVersionAsString() -{ - return GetSystemFileVersionString("\\kernel32.dll"); -} -String GetSystemFileVersionString(String filePath) -{ - char strFilePath[MAX_PATH]; // Local variable - UINT sysDirLen = GetSystemDirectoryA(strFilePath, ARRAYSIZE(strFilePath)); - if (sysDirLen != 0) - { - OVR_strcat(strFilePath, MAX_PATH, filePath.ToCStr()); - return GetFileVersionString(strFilePath); - } - else - { - return "GetSystemDirectoryA failed"; - } -} -// See http://stackoverflow.com/questions/940707/how-do-i-programatically-get-the-version-of-a-dll-or-exe-file -String GetFileVersionString(String filePath) -{ - String result; - - DWORD dwSize = GetFileVersionInfoSizeA(filePath.ToCStr(), NULL); - if (dwSize == 0) - { - OVR_DEBUG_LOG(("Error in GetFileVersionInfoSizeA: %d (for %s)", GetLastError(), filePath.ToCStr())); - result = filePath + " not found"; - } - else - { - BYTE* pVersionInfo = new BYTE[dwSize]; - if (!pVersionInfo) - { - OVR_DEBUG_LOG(("Out of memory allocating %d bytes (for %s)", dwSize, filePath.ToCStr())); - result = "Out of memory"; - } - else - { - if (!GetFileVersionInfoA(filePath.ToCStr(), 0, dwSize, pVersionInfo)) - { - OVR_DEBUG_LOG(("Error in GetFileVersionInfo: %d (for %s)", GetLastError(), filePath.ToCStr())); - result = "Cannot get version info"; - } - else - { - VS_FIXEDFILEINFO* pFileInfo = NULL; - UINT pLenFileInfo = 0; - if (!VerQueryValue(pVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &pLenFileInfo)) - { - OVR_DEBUG_LOG(("Error in VerQueryValue: %d (for %s)", GetLastError(), filePath.ToCStr())); - result = "File has no version info"; - } - else - { - int major = (pFileInfo->dwFileVersionMS >> 16) & 0xffff; - int minor = (pFileInfo->dwFileVersionMS) & 0xffff; - int hotfix = (pFileInfo->dwFileVersionLS >> 16) & 0xffff; - int other = (pFileInfo->dwFileVersionLS) & 0xffff; - - char str[128]; - OVR::OVR_sprintf(str, 128, "%d.%d.%d.%d", major, minor, hotfix, other); - - result = str; - } - } - - delete[] pVersionInfo; - } - } - - return result; -} - - -String GetDisplayDriverVersion() -{ - return GetSystemFileVersionString("\\OVRDisplay32.dll"); -} -String GetCameraDriverVersion() -{ - return GetSystemFileVersionString("\\drivers\\OCUSBVID.sys"); -} - -// From http://stackoverflow.com/questions/9524309/enumdisplaydevices-function-not-working-for-me -void GetGraphicsCardList( Array< String > &gpus) -{ - gpus.Clear(); - - DISPLAY_DEVICEA dd; - - dd.cb = sizeof(dd); - - DWORD deviceNum = 0; - while( EnumDisplayDevicesA(NULL, deviceNum, &dd, 0) ){ - if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) - gpus.PushBack(dd.DeviceString); - deviceNum++; - } -} -#else - -// used for driver files - -String GetFileVersionString(String /*filePath*/) -{ - return String(); -} - -String GetSystemFileVersionString(String /*filePath*/) -{ - return String(); -} - -String GetDisplayDriverVersion() -{ - return String(); -} - -String GetCameraDriverVersion() -{ - return String(); -} - -#ifdef OVR_OS_MAC - //use objective c source -#else - -//todo linux, this requires searching /var/ files -void GetGraphicsCardList(OVR::Array< OVR::String > &gpus) -{ - gpus.Clear(); -} -String OSVersionAsString() -{ - return String(); -} -#endif //OVR_OS_MAC -#endif // WIN32 - -} } // namespace OVR { namespace Util { diff --git a/LibOVR/Src/Util/Util_SystemInfo.h b/LibOVR/Src/Util/Util_SystemInfo.h deleted file mode 100644 index b150560..0000000 --- a/LibOVR/Src/Util/Util_SystemInfo.h +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemInfo.h -Content : Various operations to get information about the system -Created : September 26, 2014 -Author : Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2 - -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. - -************************************************************************************/ - - -#ifndef OVR_Util_SystemInfo_h -#define OVR_Util_SystemInfo_h - -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_Array.h" - -namespace OVR { namespace Util { - -const char * OSAsString(); -String OSVersionAsString(); -uint64_t GetGuidInt(); -String GetGuidString(); -const char * GetProcessInfo(); -String GetFileVersionString(String filePath); -String GetSystemFileVersionString(String filePath); -String GetDisplayDriverVersion(); -String GetCameraDriverVersion(); -void GetGraphicsCardList(OVR::Array< OVR::String > &gpus); -String GetProcessorInfo(int* numcores = NULL); - -} } // namespace OVR { namespace Util { - -#endif // OVR_Util_SystemInfo_h diff --git a/LibOVR/Src/Util/Util_SystemInfo_OSX.mm b/LibOVR/Src/Util/Util_SystemInfo_OSX.mm deleted file mode 100644 index 46799fb..0000000 --- a/LibOVR/Src/Util/Util_SystemInfo_OSX.mm +++ /dev/null @@ -1,106 +0,0 @@ - /************************************************************************************
-
- Filename : Util_SystemInfo_OSX.mm
- Content : Various operations to get information about the mac system
- Created : October 2, 2014
-
- Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
-
- Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2
-
- 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 "Util_SystemInfo.h"
-
-#include <Cocoa/Cocoa.h>
-
-#include <sys/sysctl.h>
-#include <sys/types.h>
-
-#include "../Kernel/OVR_String.h"
-#include "../Kernel/OVR_System.h"
-
-using namespace OVR;
-namespace OVR { namespace Util {
-
-//from http://opensource.apple.com/source/CF/CF-744/CFUtilities.c
-OVR::String OSVersionAsString(){
-
- NSDictionary *systemVersionDictionary =
- [NSDictionary dictionaryWithContentsOfFile:
- @"/System/Library/CoreServices/SystemVersion.plist"];
-
- NSString *systemVersion =
- [systemVersionDictionary objectForKey:@"ProductVersion"];
- return OVR::String([systemVersion UTF8String]);
-}
-
-
-//from http://www.starcoder.com/wordpress/2011/10/using-iokit-to-detect-graphics-hardware/
-void GetGraphicsCardList(Array< String > &gpus)
-{
- // Check the PCI devices for video cards.
- CFMutableDictionaryRef match_dictionary = IOServiceMatching("IOPCIDevice");
-
- // Create a iterator to go through the found devices.
- io_iterator_t entry_iterator;
-
- if (IOServiceGetMatchingServices(kIOMasterPortDefault,
- match_dictionary,
- &entry_iterator) == kIOReturnSuccess)
- {
- // Actually iterate through the found devices.
- io_registry_entry_t serviceObject;
- while ((serviceObject = IOIteratorNext(entry_iterator)))
- {
- // Put this services object into a dictionary object.
- CFMutableDictionaryRef serviceDictionary;
- if (IORegistryEntryCreateCFProperties(serviceObject,
- &serviceDictionary,
- kCFAllocatorDefault,
- kNilOptions) != kIOReturnSuccess)
- {
- // Failed to create a service dictionary, release and go on.
- IOObjectRelease(serviceObject);
- continue;
- }
-
- //
- // that points to a CFDataRef.
- const void *modelarr = CFDictionaryGetValue(serviceDictionary, CFSTR("model"));
- if (modelarr != nil) {
- if(CFGetTypeID(modelarr) == CFDataGetTypeID())
- {
- NSData *data = (__bridge NSData*)(CFDataRef)modelarr;
- NSString *s = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
- gpus.PushBack([s UTF8String]);
- }
- }
-
- // Release the dictionary created by IORegistryEntryCreateCFProperties.
- CFRelease(serviceDictionary);
-
- // Release the serviceObject returned by IOIteratorNext.
- IOObjectRelease(serviceObject);
- }
-
- // Release the entry_iterator created by IOServiceGetMatchingServices.
- IOObjectRelease(entry_iterator);
- }
-}
-
-} } // namespace OVR { namespace Util {
-
|