Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android-cmake
2 changes: 1 addition & 1 deletion src/OSVR-Core
Submodule OSVR-Core updated 57 files
+11 −0 apps/osvr_print_tree.cpp
+9 −0 apps/sample-configs/osvr_server_config.skeleton.sample.json
+2 −1 examples/clients/CMakeLists.txt
+211 −0 examples/clients/Skeleton.c
+4 −2 examples/plugin/CMakeLists.txt
+152 −0 examples/plugin/com_osvr_example_Skeleton.cpp
+147 −0 examples/plugin/com_osvr_example_Skeleton.json
+3 −1 inc/osvr/Client/HandlerContainer.h
+72 −0 inc/osvr/Client/Skeleton.h
+255 −0 inc/osvr/Client/SkeletonConfig.h
+1 −0 inc/osvr/ClientKit/InterfaceCallbackC.h
+1 −0 inc/osvr/ClientKit/InterfaceStateC.h
+185 −0 inc/osvr/ClientKit/SkeletonC.h
+81 −0 inc/osvr/Common/ParseArticulation.h
+44 −1 inc/osvr/Common/PathElementTypes.h
+6 −3 inc/osvr/Common/PathElementTypes_fwd.h
+4 −1 inc/osvr/Common/PathTree.h
+52 −0 inc/osvr/Common/ProcessArticulationSpec.h
+17 −6 inc/osvr/Common/RegisteredStringMap.h
+2 −2 inc/osvr/Common/ReportTypes.h
+136 −0 inc/osvr/Common/SkeletonComponent.h
+43 −0 inc/osvr/Common/SkeletonComponentPtr.h
+121 −0 inc/osvr/PluginKit/SkeletonInterfaceC.h
+40 −6 inc/osvr/Util/ClientReportTypesC.h
+44 −0 inc/osvr/Util/SkeletonC.h
+8 −8 src/osvr/Client/AnalysisClientContext.cpp
+9 −8 src/osvr/Client/AnalysisClientContext.h
+6 −0 src/osvr/Client/CMakeLists.txt
+9 −9 src/osvr/Client/PureClientContext.cpp
+9 −9 src/osvr/Client/PureClientContext.h
+3 −1 src/osvr/Client/RemoteHandlerFactory.cpp
+91 −0 src/osvr/Client/Skeleton.cpp
+197 −0 src/osvr/Client/SkeletonConfig.cpp
+152 −0 src/osvr/Client/SkeletonRemoteFactory.cpp
+103 −0 src/osvr/Client/SkeletonRemoteFactory.h
+5 −1 src/osvr/ClientKit/CMakeLists.txt
+1 −0 src/osvr/ClientKit/InterfaceCallbackC.cpp
+1 −0 src/osvr/ClientKit/InterfaceStateC.cpp
+4 −0 src/osvr/ClientKit/ServerAutoStartC.cpp
+256 −0 src/osvr/ClientKit/SkeletonC.cpp
+7 −0 src/osvr/Common/CMakeLists.txt
+96 −0 src/osvr/Common/ParseArticulation.cpp
+9 −0 src/osvr/Common/PathElementSerializationDescriptions.h
+3 −2 src/osvr/Common/PathElementTools.cpp
+38 −3 src/osvr/Common/PathElementTypes.cpp
+40 −7 src/osvr/Common/PathTree.cpp
+143 −0 src/osvr/Common/ProcessArticulationSpec.cpp
+14 −13 src/osvr/Common/ProcessDeviceDescriptor.cpp
+21 −3 src/osvr/Common/RegisteredStringMap.cpp
+201 −0 src/osvr/Common/SkeletonComponent.cpp
+1 −0 src/osvr/GenerateForReportTypes.cmake
+9 −9 src/osvr/JointClientKit/JointClientContext.cpp
+9 −9 src/osvr/JointClientKit/JointClientContext.h
+4 −1 src/osvr/PluginKit/CMakeLists.txt
+87 −0 src/osvr/PluginKit/SkeletonInterfaceC.cpp
+1 −0 src/osvr/Util/CMakeLists.txt
+12 −12 tests/cplusplus/Common/RegStringMap.cpp
89 changes: 88 additions & 1 deletion src/OSVR-Unity-Rendering/OsvrRenderingPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ Sensics, Inc.
#include <GLES2/gl2ext.h>
#include <jni.h>

#if OSVR_ANDROID
#include <android/log.h>
#include <android/choreographer.h>
#include <android/looper.h>
#endif

// VARIABLES
static IUnityInterfaces *s_UnityInterfaces = nullptr;
static IUnityGraphics *s_Graphics = nullptr;
Expand Down Expand Up @@ -283,11 +289,60 @@ static void checkGlError(const char *op) {
}
}

#if OSVR_ANDROID
static long gPreviousFrameTimeNanos = 0;
static long gLastFrameTimeNanos = 0;
static std::mutex gFrameTimeMutex;

static void frameCallbackImpl(long frameTimeNanos, void *data) {
std::lock_guard<std::mutex> lockGuard(gFrameTimeMutex);
gPreviousFrameTimeNanos = gLastFrameTimeNanos;
gLastFrameTimeNanos = frameTimeNanos;
//LOGI("frameTimeNanos: %d", frameTimeNanos);
//LOGI("diff: %d", frameTimeNanos - gPreviousFrameTimeNanos);
AChoreographer* choreographer = AChoreographer_getInstance();
if(!choreographer) {
LOGE("Couldn't get the choreographer from the frame callback");
}
AChoreographer_postFrameCallback(choreographer, frameCallbackImpl, nullptr);
}

static void choreographerThreadRun() {
ALooper* looper = ALooper_forThread();
if(!looper) {
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
if(!looper) {
LOGE("Couldn't prepare an ALooper for the choreographer thread");
return;
}
}

AChoreographer* choreographer = AChoreographer_getInstance();
if(!choreographer) {
LOGE("Could not get choreographer.");
return;
}

AChoreographer_postFrameCallback(choreographer, frameCallbackImpl, nullptr);

while(true) {
int fd_unused = 0;
int outEvents_unused = 0;
void *outData_unused = nullptr;
int rc = ALooper_pollAll(100, &fd_unused, &outEvents_unused, &outData_unused);
}
}
#endif

class PassThroughOpenGLContextImpl {
OSVR_OpenGLToolkitFunctions toolkit;
int mWidth;
int mHeight;

#if OSVR_ANDROID
std::thread mChoreographerThread;
#endif

static void createImpl(void* data) {
}
static void destroyImpl(void* data) {
Expand Down Expand Up @@ -317,10 +372,16 @@ class PassThroughOpenGLContextImpl {
static OSVR_CBool getDisplaySizeOverrideImpl(void* data, size_t display, int* width, int* height) {
return ((PassThroughOpenGLContextImpl*)data)->getDisplaySizeOverride(display, width, height);
}

static OSVR_CBool getRenderTimingInfoImpl(void* data, size_t display, size_t whichEye, OSVR_RenderTimingInfo* renderTimingInfoOut) {
return ((PassThroughOpenGLContextImpl*)data)->getRenderTimingInfo(display, whichEye, renderTimingInfoOut);
}

public:
#if OSVR_ANDROID
PassThroughOpenGLContextImpl() : mChoreographerThread(choreographerThreadRun) {
#else
PassThroughOpenGLContextImpl() {
#endif
memset(&toolkit, 0, sizeof(toolkit));
toolkit.size = sizeof(toolkit);
toolkit.data = this;
Expand All @@ -335,6 +396,7 @@ class PassThroughOpenGLContextImpl {
toolkit.handleEvents = handleEventsImpl;
toolkit.getDisplaySizeOverride = getDisplaySizeOverrideImpl;
toolkit.getDisplayFrameBuffer = getDisplayFrameBufferImpl;
toolkit.getRenderTimingInfo = getRenderTimingInfoImpl;
}

~PassThroughOpenGLContextImpl() {
Expand Down Expand Up @@ -375,6 +437,31 @@ class PassThroughOpenGLContextImpl {
*height = gHeight;
return false;
}

bool getRenderTimingInfo(size_t display, size_t whichEye, OSVR_RenderTimingInfo* renderTimingInfoOut) {
#if OSVR_ANDROID
timespec tp;
int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
if(!rv) {
std::lock_guard<std::mutex> lockGuard(gFrameTimeMutex);
//uint64_t presentationDeadline = 17683333L; // Shouldn't this bee at least less than 16,666,666? (1 billion / 60)
// that's 1,016,666 nanoseconds greater than the hardware interval
//uint64_t hardwareDisplayIntervalNanos = 11111111L; // 90Hz hard coded, TODO measure this or get it from the API?
uint64_t hardwareDisplayIntervalNanos = gLastFrameTimeNanos - gPreviousFrameTimeNanos;
uint64_t nowNanos = ((tp.tv_sec * 1000000000L) + tp.tv_nsec);
uint64_t timeFromLastNanos = nowNanos >= gLastFrameTimeNanos ? nowNanos - gLastFrameTimeNanos : 0; // just being safe
uint64_t nextNanos = gLastFrameTimeNanos + hardwareDisplayIntervalNanos;
uint64_t timeUntilNextNanos = nextNanos >= nowNanos ? nextNanos - nowNanos : 0; // 0 here means we missed a vsync

nanoSecondsToTimeValue(timeFromLastNanos, &renderTimingInfoOut->timeSincelastVerticalRetrace);
nanoSecondsToTimeValue(timeUntilNextNanos, &renderTimingInfoOut->timeUntilNextPresentRequired);
nanoSecondsToTimeValue(hardwareDisplayIntervalNanos, &renderTimingInfoOut->hardwareDisplayInterval);
return true;
}
LOGI("clock_gettime call failed.");
#endif
return false;
}
};

static GLuint loadShader(GLenum shaderType, const char *pSource) {
Expand Down