Skip to content

Commit

Permalink
Performance indicated with different colors
Browse files Browse the repository at this point in the history
  • Loading branch information
gyorgys committed May 22, 2020
1 parent d11f99c commit d8316b2
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 19 deletions.
89 changes: 74 additions & 15 deletions OculusFPS/OculusFPS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "framework.h"
#include "OculusFPS.h"
#include <shellapi.h>
#include <stdlib.h>
#include <string>
#include <time.h>
Expand All @@ -21,15 +22,15 @@ const int CLIENT_HEIGHT = PADDING * 3 + TITLE_HEIGHT + DATA_HEIGHT;

const COLORREF WINDOW_BACKGROUND = RGB(64, 64, 64);
const COLORREF TITLE_COLOR = RGB(148, 148, 148);
const COLORREF DATA_COLOR = RGB(192, 192, 192);
const COLORREF AWS_DATA_COLOR = RGB(255, 220, 192);
const COLORREF DATA_COLOR[4] = { RGB(0, 255, 0), RGB(128, 204, 0), RGB(255, 128, 64), RGB(255, 0, 0) };
const COLORREF AWS_LABEL_COLOR = RGB(255, 128, 0);

const WCHAR STR_NO_INIT[] = L"Unable to initialize Oculus Library";
const WCHAR STR_NO_HMD[] = L"Headset Inactive";
const WCHAR STR_FPS_TITLE[] = L"FPS";
const WCHAR STR_AWS_IND[] = L"[AWS]";
const WCHAR STR_LATENCY_TITLE[] = L"Latency (ms)";
const WCHAR STR_DROPPED_FRAMES_TITLE[] = L"Dropped frames";
const WCHAR STR_AWS_ACTIVE[] = L"AWS";

// Global Variables:
HINSTANCE _hInst; // current instance
Expand All @@ -39,8 +40,11 @@ UINT_PTR _idTimer = 0;
HWND _hPerfInfoWnd;
OculusPerfInfo* _perfInfoClass;

// Command line args
bool _fTestMode;

// Perf data
bool _perfInfoInitialized;
bool _fPerfInfoInitialized;
opi_PerfInfo _perfInfo;

// Forward declarations of functions included in this code module:
Expand All @@ -58,11 +62,26 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
srand(time(NULL));
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: Place code here.

LPWSTR* szArglist;
int nArgs;

szArglist = CommandLineToArgvW(lpCmdLine, &nArgs);
if (NULL != szArglist) {
for (int i = 0; i < nArgs; i++) {
LPWSTR szArg = szArglist[i];
int nArgLen = wcslen(szArg);
if (nArgLen > 0) {
_wcslwr_s(szArg, nArgLen + 1);
if (0 == wcscmp(szArg, L"-d"))
{
_fTestMode = true;
}
}
}
LocalFree(szArglist);
}

// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, _szTitle, MAX_LOADSTRING);
Expand Down Expand Up @@ -93,8 +112,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
return (int) msg.wParam;
}



//
// FUNCTION: MyRegisterClass()
//
Expand All @@ -116,7 +133,7 @@ ATOM MyRegisterClass(HINSTANCE hInstance)
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = CreateSolidBrush(WINDOW_BACKGROUND);
wcex.lpszClassName = _szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_OCULUSFPS));

return RegisterClassExW(&wcex);
}
Expand Down Expand Up @@ -149,7 +166,13 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
_perfInfoClass = new OculusPerfInfo();
_perfInfoInitialized = _perfInfoClass->init();
if (!_fTestMode) {
_fPerfInfoInitialized = _perfInfoClass->init();
}
else {
_fPerfInfoInitialized = _perfInfoClass->initTestMode();
}

_perfInfoClass->setCallback(UpdatePerfData);
return TRUE;
}
Expand Down Expand Up @@ -248,7 +271,7 @@ void DisplayPerfData(HDC hdc)
SetTextColor(hdc, TITLE_COLOR);
SetBkColor(hdc, WINDOW_BACKGROUND);

if (!_perfInfoInitialized) {
if (!_fPerfInfoInitialized) {
int x = CLIENT_WIDTH / 2;
int y = (CLIENT_HEIGHT - TITLE_HEIGHT) / 2;
TextOut(hdc, x, y, STR_NO_INIT, wcslen(STR_NO_INIT));
Expand All @@ -263,7 +286,32 @@ void DisplayPerfData(HDC hdc)
std::wstring strFps = std::to_wstring(_perfInfo.nAppFps);
std::wstring strLatency = std::to_wstring(_perfInfo.nLatencyMs);
std::wstring strDroppedFrames = std::to_wstring(_perfInfo.nDroppedFrames);


int nOkFps = _perfInfo.fAwsActive ? 30 : 60;
int nBadFps = _perfInfo.nMaxAppFps / 2;

int iFpsColor = 0, iLatencyColor = 0, iDroppedFramesColor = 0;
if (_perfInfo.nAppFps < nBadFps) {
iFpsColor = 3;
}
else if (_perfInfo.nAppFps < nOkFps) {
iFpsColor = 2;
}
else if (_perfInfo.nAppFps < _perfInfo.nMaxAppFps) {
iFpsColor = 1;
}

if (_perfInfo.nLatencyMs > 30) {
iLatencyColor = 2;
}
else if (_perfInfo.nLatencyMs > 60) {
iLatencyColor = 3;
}

if (_perfInfo.nDroppedFrames > 0) {
iDroppedFramesColor = 2;
}

int y = PADDING;
int x = PADDING + CELL_WIDTH / 2;

Expand All @@ -272,12 +320,23 @@ void DisplayPerfData(HDC hdc)
TextOut(hdc, x + CELL_WIDTH, y, STR_LATENCY_TITLE, wcslen(STR_LATENCY_TITLE));
TextOut(hdc, x + CELL_WIDTH * 2, y, STR_DROPPED_FRAMES_TITLE, wcslen(STR_DROPPED_FRAMES_TITLE));

SetTextColor(hdc, _perfInfo.fAwsActive ? AWS_DATA_COLOR : DATA_COLOR);

y += TITLE_HEIGHT;
SelectObject(hdc, hDataFont);
SetTextColor(hdc, DATA_COLOR[iFpsColor]);
TextOut(hdc, x, y, strFps.c_str(), strFps.length());
SetTextColor(hdc, DATA_COLOR[iLatencyColor]);
TextOut(hdc, x + CELL_WIDTH, y, strLatency.c_str(), strLatency.length());
SetTextColor(hdc, DATA_COLOR[iDroppedFramesColor]);
TextOut(hdc, x + CELL_WIDTH * 2, y, strDroppedFrames.c_str(), strDroppedFrames.length());

if (_perfInfo.fAwsActive) {
SetTextAlign(hdc, TA_TOP | TA_LEFT);
SelectObject(hdc, hTitleFont);
SetTextColor(hdc, WINDOW_BACKGROUND);
SetBkColor(hdc, AWS_LABEL_COLOR);
TextOut(hdc, PADDING, PADDING, STR_AWS_IND, wcslen(STR_AWS_IND));
}
}
// Restore the original font.
SelectObject(hdc, hOldFont);
Expand Down
Binary file modified OculusFPS/OculusFPS.rc
Binary file not shown.
1 change: 1 addition & 0 deletions OculusFPS/OculusFPS.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
<ResourceCompile Include="OculusFPS.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="icon1.ico" />
<Image Include="OculusFPS.ico" />
<Image Include="small.ico" />
</ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions OculusFPS/OculusFPS.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@
<Image Include="OculusFPS.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="icon1.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>
71 changes: 71 additions & 0 deletions OculusFPS/OculusPerfInfo.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include "OculusPerfInfo.h"
#include <assert.h>
#include <time.h>

int rand_int(int n) {
return rand() / ((RAND_MAX + 1u) / n);
}

OculusPerfInfo::OculusPerfInfo()
{
Expand All @@ -19,6 +24,16 @@ bool OculusPerfInfo::init()
return true;
}

bool OculusPerfInfo::initTestMode()
{
srand((UINT)time(NULL));
this->m_fInitialized = true;
this->m_fHmdRefreshRate = 90.0;
this->m_thread = std::thread(&OculusPerfInfo::collectTestPerfData, this);

return true;
}

void OculusPerfInfo::setCallback(void(*callback)(opi_PerfInfo&))
{
this->m_pfCallback = callback;
Expand Down Expand Up @@ -168,3 +183,59 @@ void OculusPerfInfo::collectPerfData()
ovr_Shutdown();
}

void OculusPerfInfo::collectTestPerfData()
{
auto sleepTime = std::chrono::milliseconds((int)(1000 / m_fHmdRefreshRate * 15));
bool fAws = true;
int nMaxFps = (int)round(this->m_fHmdRefreshRate);
int nMaxAwsFps = (int)round(this->m_fHmdRefreshRate / 2.0);
int nPerfDropCount = 0;

while (!this->m_fStop) {

int nFpsDrop = 0;
bool fDropFrames = false;

if (nPerfDropCount > 0) {
// continue simulated perf drop
nPerfDropCount--;
nFpsDrop = rand_int((int)(round(fAws ? nMaxAwsFps * 0.7 : nMaxFps * 0.7)));
fDropFrames = rand_int(3) > 1;
}
else {
// figure out next event to simulate
int nRnd = rand_int(300);

// Do random stuff
if (nRnd < 15) {
// slight fps drop
nFpsDrop = nRnd;
}
else if (nRnd < 20) {
// long, sever perf drop
nPerfDropCount = (nRnd - 15) * 25;
}
else if (nRnd < 30) {
// mode switch
fAws = !fAws;
}
else {
// do nothing
}
}
this->m_pfiLastPerfInfo.fHeadsetActive = true;
this->m_pfiLastPerfInfo.nAppFps = (fAws ? nMaxAwsFps : nMaxFps) - nFpsDrop;
this->m_pfiLastPerfInfo.nMaxAppFps = (fAws ? nMaxAwsFps : nMaxFps);
this->m_pfiLastPerfInfo.nCompFps = 90;
this->m_pfiLastPerfInfo.nLatencyMs = 24;
this->m_pfiLastPerfInfo.fAwsActive = fAws;
this->m_pfiLastPerfInfo.nDroppedFrames = fDropFrames ? 1 : 0;

if (this->m_pfCallback != NULL) {
this->m_pfCallback(this->m_pfiLastPerfInfo);
}

std::this_thread::sleep_for(sleepTime);
}
}

5 changes: 4 additions & 1 deletion OculusFPS/OculusPerfInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
struct opi_PerfInfo {
bool fHeadsetActive;
int nAppFps;
int nMaxAppFps;
int nCompFps;
int nLatencyMs;
int nDroppedFrames;
Expand All @@ -29,12 +30,14 @@ class OculusPerfInfo
OculusPerfInfo();
~OculusPerfInfo();
bool init();
void collectPerfData();
bool initTestMode();
void setCallback(void(*pfCallback)(opi_PerfInfo&));
opi_PerfInfo getPerfInfo();

protected:
bool createOvrSession();
void destroyOvrSession();
void collectPerfData();
void collectTestPerfData();
};

Binary file added OculusFPS/icon1.ico
Binary file not shown.
5 changes: 2 additions & 3 deletions OculusFPS/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 103
#define IDM_ABOUT 104
#define IDI_OCULUSFPS 107
#define IDI_SMALL 108
#define IDC_OCULUSFPS 109
#define IDI_OCULUSFPS 109
#define IDR_MAINFRAME 128
#define IDC_STATIC -1

Expand All @@ -18,7 +17,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
Expand Down

0 comments on commit d8316b2

Please sign in to comment.