public static void step(JNIEnv env, jobject obj, int width, int height)
 {
     if (g_renderer != null)
     {
         g_renderer.render();
     }
 }
        // ifelse does not look that good. lets keep two sets of signatures..
#if JNIEnv
        // JVM load the .so and calls this native function
        public static jstring stringFromJNI(JNIEnv env, jobject thiz)
        {
            // called by
            // X:\jsc.svn\examples\java\android\synergy\OVRVrCubeWorldSurfaceView\OVRVrCubeWorldSurfaceViewX\ApplicationActivity.cs

            // jstring Java_com_oculus_gles3jni_GLES3JNILib_stringFromJNI(JNIEnv* env, jobject thiz)
            // X:\jsc.svn\examples\c\Test\TestNamespaceFixup\TestNamespaceFixup\Class1.cs

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150607-1/vrcubeworld
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201505/20150525


            // look almost the same file!

            // OVR_VRAPI_EXPORT const char * vrapi_GetVersionString();

            // if we change our NDK code, will nuget packaing work on the background, and also upgrade running apps?
            var v = env.NewStringUTF(env,
                //"hey! XNDK!"

                VrApi.vrapi_GetVersionString()
            );

            //v = env.JNIEnv_NewStringUTF(VrApi.vrapi_GetVersionString());
            // the other option is to have a debugger send the updated MSIL via edit and continue, and we would have to patch the function on the fly.

            return v;
        }
 public static void resize(JNIEnv env, jobject obj, int width, int height)
 {
     if (g_renderer != null)
     {
         g_renderer.resize(width, height);
     }
 }
        // JVM load the .so and calls this native function
        static jstring Java_OVRVrCubeWorldSurfaceView_Activities_xMarshal_stringFromJNI(
            // what would we be able to do inspecting the runtime?
             JNIEnv env,
            jobject thiz)
        {
            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150607-1/vrcubeworld

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201505/20150525

            var n = env.NewStringUTF;

            // look almost the same file!

            // OVR_VRAPI_EXPORT const char * vrapi_GetVersionString();

            // if we change our NDK code, will nuget packaing work on the background, and also upgrade running apps?
            var v = n( env,
                //"from Java_OVRVrCubeWorldNative_xActivity_stringFromJNI. yay"

                VrApi_h.vrapi_GetVersionString()
                );

            return v;


            // ConfigurationCreateNuGetPackage.cs
        }
        // JVM load the .so and calls this native function
        static jstring Java_x360video_Activities_xMarshal_stringFromJNI(JNIEnv env, jobject thiz, jobject args)
        {
            ConsoleExtensions.trace("enter Java_x360video_Activities_xMarshal_stringFromJNI");



            if (args != null)
            {
                var loctype = env.GetObjectClass(env, args);
                var gtype = env.NewGlobalRef(env, loctype);

                //GlobalActivityClass = (jclass)jni->NewGlobalRef(jni->GetObjectClass(activity));

                // 
                var startMovieFromNative = env.GetMethodID(env, loctype, "startMovieFromNative", "(Ljava/lang/String;)V");

                ConsoleExtensions.tracei64("startMovieFromNative: ", (int)(object)startMovieFromNative);


            }

            // do we have a console yet?
            //Console.WriteLine("enter Java_AndroidBrowserVRNDK_Activities_xMarshal_stringFromJNI");


            var n = env.NewStringUTF;

            //// if we change our NDK code, will nuget packaing work on the background, and also upgrade running apps?
            var v = n(env, "hello from Java_x360video_Activities_xMarshal_stringFromJNI. yay");

            return v;
            // ConfigurationCreateNuGetPackage.cs
        }
//        E/AndroidRuntime( 1880): java.lang.UnsatisfiedLinkError: No implementation found for void HybridGLES3JNIActivity.NDK.GLES3JNILib.init() (tried
//E/AndroidRuntime( 1880):        at HybridGLES3JNIActivity.NDK.GLES3JNILib.init(Native Method)
//E/AndroidRuntime( 1880):        at HybridGLES3JNIActivity.Activities.GLES3JNIView_Renderer.onSurfaceCreated(GLES3JNIView_Renderer.java:39)
//E/AndroidRuntime( 1880):        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1539)
//E/AndroidRuntime( 1880):        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1278)

     

        static void init(JNIEnv env, jobject obj)
        {
            ConsoleExtensions.tracei("enter init, call createES3Renderer");

            g_renderer = RendererES3.createES3Renderer();
            // here we are storing a pointer in native heap. why is oculus sending it back to java world??

            //resize =
        }
        // named pointers! typedefs!
        static ovrAppThreadPointer onCreate(JNIEnv env, jobject obj, jobject activity)
        {
            // 1937
            ConsoleExtensions.trace("enter onCreate, then ovrAppThread, then ovrMessageQueue_Enable");

            var appThread = new VrCubeWorld.ovrAppThread(env, activity);

            // set property?
            appThread.MessageQueue.ovrMessageQueue_Enable(true);

            var message = default(VrCubeWorld.ovrMessage);
            message.ovrMessage_Init(VrCubeWorld.MESSAGE.MESSAGE_ON_CREATE, VrCubeWorld.ovrMQWait.MQ_WAIT_PROCESSED);
            appThread.MessageQueue.ovrMessageQueue_PostMessage(ref message);

            return appThread;
        }
Example #8
0
        // JVM load the .so and calls this native function
        static jstring Java_TestNDKAsAsset_xActivity_stringFromJNI(
            // what would we be able to do inspecting the runtime?
            ref JNIEnv env,
            jobject thiz)
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201505/20150525

            var n = env.NewStringUTF;

            // look almost the same file!

            // if we change our NDK code, will nuget packaing work on the background, and also upgrade running apps?
            var v = n(ref env, "from Java_TestHybridOVR_OVRJVM_ApplicationActivity_stringFromJNI. yay");

            return v;


            // ConfigurationCreateNuGetPackage.cs
        }
        // JVM load the .so and calls this native function
        static jstring Java_AndroidBrowserVR_Activities_xMarshal_stringFromJNI(
            // what would we be able to do inspecting the runtime?
             JNIEnv env,
            jobject thiz,
            jobject args
            )
        {
            ConsoleExtensions.trace("enter Java_AndroidBrowserVR_Activities_xMarshal_stringFromJNI");

            // do we have a console yet?
            //Console.WriteLine("enter Java_AndroidBrowserVRNDK_Activities_xMarshal_stringFromJNI");


            var n = env.NewStringUTF;

            //// if we change our NDK code, will nuget packaing work on the background, and also upgrade running apps?
            var v = n(env, "hello from Java_AndroidBrowserVR_Activities_xMarshal_stringFromJNI. yay");

            return v;
            // ConfigurationCreateNuGetPackage.cs
        }
 public static void onKeyEvent(JNIEnv env, jobject obj, int keyCode, int action)
 {
     // 2094
     var message = default(VrCubeWorld.ovrMessage);
     message.ovrMessage_Init(MESSAGE.MESSAGE_ON_KEY_EVENT, VrCubeWorld.ovrMQWait.MQ_WAIT_NONE);
     message[0] = keyCode;
     message[1] = action;
     // ovrApp_HandleKeyEvent
     appThread.MessageQueue.ovrMessageQueue_PostMessage(ref message);
 }
 public static void onTouchEvent(JNIEnv env, jobject obj, int action, float x, float y)
 {
     // 2108
     var message = default(VrCubeWorld.ovrMessage);
     message.ovrMessage_Init(MESSAGE.MESSAGE_ON_TOUCH_EVENT, VrCubeWorld.ovrMQWait.MQ_WAIT_NONE);
     message[0] = action;
     message[1] = x;
     message[2] = y;
     // ovrApp_HandleTouchEvent
     appThread.MessageQueue.ovrMessageQueue_PostMessage(ref message);
 }
        static void onSurfaceChanged(JNIEnv env, jobject obj, jobject surface)
        {
            // 2032
            //var appThread = (VrCubeWorld.ovrAppThread)handle;

            var newNativeWindow = native_window_jni.ANativeWindow_fromSurface(env, surface);

            if (native_window.ANativeWindow_getWidth(newNativeWindow) < native_window.ANativeWindow_getHeight(newNativeWindow))
            {
                // An app that is relaunched after pressing the home button gets an initial surface with
                // the wrong orientation even though android:screenOrientation="landscape" is set in the
                // manifest. The choreographer callback will also never be called for this surface because
                // the surface is immediately replaced with a new surface with the correct orientation.
                //ALOGE("        Surface not in landscape mode!");
            }

            if (newNativeWindow != appThread.NativeWindow)
            {
                if (appThread.NativeWindow != null)
                {
                    appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_SURFACE_DESTROYED);

                    native_window.ANativeWindow_release(appThread.NativeWindow);
                    appThread.NativeWindow = default(native_window.ANativeWindow);

                }
                if (newNativeWindow != null)
                {
                    appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_SURFACE_CREATED);

                    native_window.ANativeWindow_release(appThread.NativeWindow);
                    appThread.NativeWindow = default(native_window.ANativeWindow);

                }
            }
            else if (newNativeWindow != null)
            {
                native_window.ANativeWindow_release(newNativeWindow);
            }
        }
        static void onSurfaceDestroyed(JNIEnv env, jobject obj)
        {
            // 2074

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704

            appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_SURFACE_DESTROYED);

            native_window.ANativeWindow_release(appThread.NativeWindow);
            appThread.NativeWindow = default(native_window.ANativeWindow);

            ConsoleExtensions.trace("exit onSurfaceDestroyed, are we in the menu?");

            //      HWC | 7f8912c2b0 | 0000 | 0000 | 00 | 0100 | RGBA_8888   |    0.0,    0.0, 1440.0, 2560.0 |    0,    0, 1440, 2560 |    0,    0, 1440, 2560 | Mono background window
            //      HWC | 7f8912c1d0 | 0000 | 0000 | 04 | 0105 | RGBA_8888   |    0.0,    0.0, 2560.0, 1440.0 |    0,    0, 1440, 2560 |    0,    0, 2560, 1440 | OVRMyCubeWorld.Activities/OVRMyCubeWorld.Activities.ApplicationActivity
            //FB TARGET | 7f96525080 | 0000 | 0000 | 00 | 0105 | RGBA_8888   |    0.0,    0.0, 1440.0, 2560.0 |    0,    0, 1440, 2560 |    0,    0,    0,    0 | HWC_FRAMEBUFFER_TARGET

        }
        // JVM load the .so and calls this native function
        static jlong Java_HybridOculusVrActivity_OVRJVM_ApplicationActivity_nativeSetAppInterface(
            ref JNIEnv env,
            jclass clazz,
            jobject activity,

            jstring fromPackageNameString, jstring commandString, jstring uriString
            )
        {
            log.__android_log_print(log.android_LogPriority.ANDROID_LOG_INFO, "xNativeActivity", "enter Java_HybridOculusVrActivity_OVRJVM_ApplicationActivity_nativeSetAppInterface");

            //jni/HybridOculusVrActivity.dll.c: In function 'Java_HybridOculusVrActivity_OVRJVM_ApplicationActivity_nativeSetAppInterface':
            //jni/HybridOculusVrActivity.dll.c:64:5: error: format not a string literal and no format arguments [-Werror=format-security]

            //android_native_app_glue.app_dummy();
            //var x = OvrApp.cxxGetString();

            //android_native_app_glue.app_dummy();
            //log.__android_log_print(log.android_LogPriority.ANDROID_LOG_INFO, "xNativeActivity", x);

            //      return (new OvrApp())->SetActivity( jni, clazz, activity );


            //I/System.Console(13696): enter  HybridOculusVrActivity.OVRJVM ApplicationActivity onCreate
            //I/xNativeActivity(13696): enter Java_HybridOculusVrActivity_OVRJVM_ApplicationActivity_stringFromJNI
            //I/xNativeActivity(13696): enter Java_HybridOculusVrActivity_OVRJVM_ApplicationActivity_nativeSetAppInterface

            // http://stackoverflow.com/questions/7281441/elegantly-call-c-from-c

            //long u = 0;

            return OvrApp.cxxSetAppInterface(
                ref env,
                clazz,
                activity,


                // added by oculus050
                fromPackageNameString, commandString, uriString
           );
        }
        static void onSurfaceCreated(JNIEnv env, jobject obj, jobject surface)
        {
            // 2009
            ConsoleExtensions.trace("enter onSurfaceCreated");

            //var appThread = (VrCubeWorld.ovrAppThread)handle;

            var newNativeWindow = native_window_jni.ANativeWindow_fromSurface(env, surface);

            if (native_window.ANativeWindow_getWidth(newNativeWindow) < native_window.ANativeWindow_getHeight(newNativeWindow))
            {
                // An app that is relaunched after pressing the home button gets an initial surface with
                // the wrong orientation even though android:screenOrientation="landscape" is set in the
                // manifest. The choreographer callback will also never be called for this surface because
                // the surface is immediately replaced with a new surface with the correct orientation.
                //ALOGE("        Surface not in landscape mode!");
            }

            appThread.NativeWindow = newNativeWindow;

            var message = default(VrCubeWorld.ovrMessage);
            message.ovrMessage_Init(MESSAGE.MESSAGE_ON_SURFACE_CREATED, VrCubeWorld.ovrMQWait.MQ_WAIT_PROCESSED);
            message.ovrMessage_SetPointerParm(0, appThread.NativeWindow);
            //ConsoleExtensions.tracei("onSurfaceCreated, post MESSAGE_ON_SURFACE_CREATED");
            appThread.MessageQueue.ovrMessageQueue_PostMessage(ref message);

            //ConsoleExtensions.tracei("exit onSurfaceCreated");
        }
        static void onPause(ref JNIEnv env, jobject obj)
        {
            // 1970
            appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_PAUSE);

            ConsoleExtensions.trace("exit onPause");
        }
        // defined at
        // X:\opensource\ovr_mobile_sdk_0.6.0.1\VrSamples\Native\Oculus360PhotosSDK\jni\Oculus360Photos.cpp
        // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150721/ovroculus360photoshud
        //public static object AtStartBackgroundPanoLoad;


        public static long Java_com_oculus_oculus360photossdk_MainActivity_nativeSetAppInterface(JNIEnv env,
            jclass clazz,
            jobject activity,

            jstring fromPackageNameString,
            jstring commandString,
            jstring uriString,

            object arg_AtStartBackgroundPanoLoad
         ) { return 0; }
            //I/xNativeActivity(21471): \VrCubeWorld.AppThread.cs:71 mallinfo  total allocated space:  2 027 243 344
            //I/xNativeActivity(21471): \VrCubeWorld.AppThread.cs:72 mallinfo  total free  space:  70 957 232
            //I/xNativeActivity(21471): \VrApi.ovrMatrix4f.cs:343 out of heap? errno: 12 Out of memory
            //I/xNativeActivity(21471): \VrCubeWorld.AppThread.cs:71 mallinfo  total allocated space:  -2 080 212 552
            //I/xNativeActivity(21471): \VrCubeWorld.AppThread.cs:72 mallinfo  total free  space:  74 286 664


            //I/xNativeActivity(15462): \VrCubeWorld.AppThread.cs:90 mallinfo  total allocated space:  5 512 048
            //I/xNativeActivity(15462): \VrCubeWorld.AppThread.cs:91 mallinfo  total free  space:  13 362 320

            //I/xNativeActivity(18481): \VrCubeWorld.AppThread.cs:71 mallinfo  total allocated space:  -2083023504
            //I/xNativeActivity(18481): \VrCubeWorld.AppThread.cs:72 mallinfo  total free  space:  76 049 040

            // https://groups.google.com/forum/#!topic/android-ndk/lcnwzszrESo
            // http://stackoverflow.com/questions/30480007/is-using-largeheap-in-android-manifest-a-good-practice
            // https://developer.android.com/reference/android/app/ActivityManager.html#getLargeMemoryClass()
            // http://dwij.co.in/increase-heap-size-of-android-application/
            // http://stackoverflow.com/questions/16957805/android-how-to-increase-application-memory-using-ndk


            // called by onCreate
            public ovrAppThread(JNIEnv env, jobject activityObject)
            {
                // 1907
                ConsoleExtensions.trace("enter ovrAppThread, call pthread_create");

                // why keep it?
                env.GetJavaVM(env, out this.JavaVm);
                this.ActivityObject = env.NewGlobalRef(env, activityObject);


                this.Thread = new System.Threading.Thread(
                    delegate()
                    {
                        // can we do closures?
                        ConsoleExtensions.trace("enter thread for vrapi_SubmitFrame");


                        //malloc_h.malloc_stats();

                        //xmallinfo();

                        //ConsoleExtensions.trace("adding memory pressure...");

                        //var mb = 8 * 1024 * 1024;
                        //var pressure = new byte[mb];

                        ////System.Threading.Thread.Sleep(1000);

                        //xmallinfo();


                        ////ConsoleExtensions.trace("adding memory pressure... store...");

                        ////for (int i = 0; i < mb; i++)
                        ////{
                        ////    pressure[i] = (byte)(0xcc ^ i);
                        ////}

                        ////xmallinfo();

                        //// GC. would jsc static analysis know it means we can free that memory?

                        //stdlib_h.free(pressure);

                        ////pressure = null;

                        ////System.Threading.Thread.Sleep(1000);
                        //xmallinfo();


                        // would our chrome app be able to switch over to ndk over udp?
                        this.AppThreadFunction();
                    }
                );
                this.Thread.Start();
            }
Example #19
0
        // JVM load the .so and calls this native function
        static unsafe long Java_TestNDKAsAsset_xActivity_recvmsg_fd(
                ref JNIEnv env,
                jobject thiz,
                int sock,
                int length)
        {
            // X:\jsc.svn\core\ScriptCoreLibAndroidNDK\ScriptCoreLibAndroidNDK\SystemHeaders\sys\socket.cs
            // "X:\opensource\github\libancillary\fd_recv.c"

            byte payload = 0xFF;

            //socket_h.iovec payload_io = { &payload, 1 };
            socket_h.iovec payload_iov;


            payload_iov.iov_base = &payload;
            payload_iov.iov_len = 1;


            __msg_control_cmsghdr_int buffer;


            socket_h.msghdr msghdr;

            //msghdr.msg_name = default(void*);
            msghdr.msg_namelen = 0;
            msghdr.msg_iov = &payload_iov;
            msghdr.msg_iovlen = 1;
            msghdr.msg_flags = 0;
            msghdr.msg_control = &buffer;

            // Severity	Code	Description	Project	File	Line
            //Error CS0266  Cannot implicitly convert type 'int' to 'ulong'.An explicit conversion exists (are you missing a cast?)    TestNDKAsAsset X:\jsc.svn\examples\c\android\Test\TestNDKAsAsset\TestNDKAsAsset\Program.cs	179

            msghdr.msg_controllen = (ulong)sizeof(__msg_control_cmsghdr_int);

            // http://linux.about.com/library/cmd/blcmdl3_CMSG_FIRSTHDR.htm

            buffer.cmsg.cmsg_len = msghdr.msg_controllen;
            buffer.cmsg.cmsg_level = socket_h.SOL_SOCKET;

            // http://man7.org/tlpi/code/online/dist/sockets/scm_rights_send.c.html
            // http://www.lst.de/~okir/blackhats/node121.html
            // http://man7.org/tlpi/code/online/dist/sockets/scm_rights.h.html
            buffer.cmsg.cmsg_type = socket_h.SCM_RIGHTS;

            buffer.data0 = -1;


            // http://linux.die.net/man/2/recvmsg
            var recvfrom_status = socket_h.recvmsg((SOCKET)sock, &msghdr, 0);
            if (recvfrom_status < 0)
                return -1;


            return buffer.data0;
        }
        // named pointers! typedefs!
        static ovrAppThreadPointer onCreate(JNIEnv env, jobject obj, jobject activity)
        {
            // 1937
            ConsoleExtensions.trace("enter onCreate");


            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# 0.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -4482497940269729854931310573780992.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -112522782313195449178724042276864.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -112561990195377190832118112976896.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# 0.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -112309334370484290251637919842304.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -112521273573772570121514008969216.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -112522782313195449178724042276864.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# 0.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -112561990195377190832118112976896.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# 0.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -4419917904888785132619678770790400.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# 0.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -4442953183654797667429932949569536.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# -112522134328956135737486399766528.000000
            //I/xNativeActivity(24015): \GLES3JNILib.cs:322 alloca# nan

            //var alloca = stackalloc float[16];

            //for (int i = 0; i < 16; i++)
            //{
            //    ConsoleExtensions.tracef("alloca#", alloca[i]);

            //    alloca[i] = i;

            //    ConsoleExtensions.tracef("alloca0", alloca[i]);
            //}


            appThread = new VrCubeWorld.ovrAppThread(env, activity);

            // set property?
            appThread.MessageQueue.ovrMessageQueue_Enable(true);
            appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_CREATE);

            return appThread;
        }
        // JVM load the .so and calls this native function
        public static jstring stringFromJNI(JNIEnv env, jobject thiz, jobject fields)
        {
            //ConsoleExtensions.trace("enter stringFromJNI");

            // what about jobject dynamic?

            //dynamic locfields = fields;
            //locfields.foo = "foo";

            // pickerwengs.blogspot.com/2011/12/android-programming-objects-between.html

            //System.NullReferenceException: Object reference not set to an instance of an object.
            //   at jsc.Languages.C.CCompiler.WriteDecoratedMethodName(MethodBase z) in x:\jsc.internal.git\compiler\jsc\Languages\C\CCompiler.WriteDecoratedMethodName.cs:line 60
            //   at jsc.Languages.C.CCompiler.WriteDecoratedMethodName(MethodBase z, Boolean q) in x:\jsc.internal.git\compiler\jsc\Languages\C\CCompiler.WriteDecoratedMethodName.cs:line 31

            // journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/field.html



            // generic / per field variables?

            // do we need our own GC?

            if (aI64 == null)
            {
                aByteArray = new argsByteArray { env = env, fields = fields };
                aI64 = new argsI64 { env = env, fields = fields };
                aI = new argsI { env = env, fields = fields };
                aF = new argsF { env = env, fields = fields };
            }


            var m = malloc_h.mallinfo();
            var total = VrCubeWorld.ovrAppThread.__uordblks(m);

            aI64["total_allocated_space"] = total;

            if (total > GLES3JNILib.safemodeMemoryLimitMB * 1024 * 1024)
            {
                //ConsoleExtensions.trace("HUD safe mode...");

                //System.Threading.Thread.Sleep(1000);

                //GC.Collect(

                // should jsc call the finalizer too?
                //stdlib_h.free(aI64);
                //aI64 = null;

                return null;
            }



            GLES3JNILib.fields_xvalue = aI["x"];
            GLES3JNILib.fields_yvalue = aI["y"];

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150703/mousex
            GLES3JNILib.fields_mousex = aI["mousex"];
            GLES3JNILib.fields_mousey = aI["mousey"];

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150704
            GLES3JNILib.fields_ad = aI["ad"];
            GLES3JNILib.fields_ws = aI["ws"];
            GLES3JNILib.fields_c = aI["c"];
            GLES3JNILib.fields_mousewheel = aI["mousewheel"];

            if (appThread == null)
                return null;
            if (appThread.appState == null)
                return null;

            GLES3JNILib.fields_px = aF["px"];
            GLES3JNILib.fields_py = aF["py"];
            GLES3JNILib.fields_pz = aF["pz"];


            //ConsoleExtensions.trace("get fields_vertexTransform");

            GLES3JNILib.fields_vertexTransform = aByteArray["vertexTransform"];

            appThread.appState.Scene.Update();


            aF["tracking_HeadPose_Pose_Orientation_x"] = appThread.tracking.HeadPose.Pose.Orientation.x;
            aF["tracking_HeadPose_Pose_Orientation_y"] = appThread.tracking.HeadPose.Pose.Orientation.y;
            aF["tracking_HeadPose_Pose_Orientation_z"] = appThread.tracking.HeadPose.Pose.Orientation.z;
            aF["tracking_HeadPose_Pose_Orientation_w"] = appThread.tracking.HeadPose.Pose.Orientation.w;



            //void ScriptCoreLibNative_BCLImplementation_System___Action_2_Invoke(LPScriptCoreLibNative_BCLImplementation_System___Action_2, void*, void*);


            // can we do lambdas?
            //Action<string, float> set = (fname, f) =>
            //ActionStringFloat set = (fname, f) =>
            //{

            //};

            //set("tracking_HeadPose_Pose_Orientation_x", appThread.tracking.HeadPose.Pose.Orientation.x);

            //var fields_tracking_HeadPose_Pose_Orientation_x = env.GetFieldID(env, fields_GetType, "tracking_HeadPose_Pose_Orientation_x", "F");

            //env.SetFloatField(env, fields, fields_tracking_HeadPose_Pose_Orientation_x,
            //    appThread.tracking.HeadPose.Pose.Orientation.x
            //);


            // what about sending back a variable_

            //appThread.tracking.HeadPose.Pose.Orientation.x;


            // GetIntField
            // if we add a field how can we inspect it?

            // called by
            // X:\jsc.svn\examples\java\android\synergy\OVRVrCubeWorldSurfaceView\OVRVrCubeWorldSurfaceViewX\ApplicationActivity.cs

            // jstring Java_com_oculus_gles3jni_GLES3JNILib_stringFromJNI(JNIEnv* env, jobject thiz)
            // X:\jsc.svn\examples\c\Test\TestNamespaceFixup\TestNamespaceFixup\Class1.cs

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150607-1/vrcubeworld
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201505/20150525


            // look almost the same file!

            // OVR_VRAPI_EXPORT const char * vrapi_GetVersionString();

            //if (fields == null)
            //{
            //    return env.NewStringUTF(env, "dynamic fields null?");

            //}

            //// if we change our NDK code, will nuget packaing work on the background, and also upgrade running apps?
            //var v = env.NewStringUTF(env,
            //    //"hey! XNDK!"

            //    VrApi.vrapi_GetVersionString()
            //);

            //v = env.JNIEnv_NewStringUTF(VrApi.vrapi_GetVersionString());
            // the other option is to have a debugger send the updated MSIL via edit and continue, and we would have to patch the function on the fly.

            //ConsoleExtensions.trace("exit stringFromJNI");
            return null;
        }
        // JVM load the .so and calls this native function
        static jstring Java_HybridOculusVrActivity_OVRJVM_ApplicationActivity_stringFromJNI(
            ref JNIEnv env,
            jobject thiz)
        {
            log.__android_log_print(
                log.android_LogPriority.ANDROID_LOG_INFO, "xNativeActivity", "enter Java_HybridOculusVrActivity_OVRJVM_ApplicationActivity_stringFromJNI"
            );

            var n = env.NewStringUTF;

            // look almost the same file!

            var x = OvrApp.cxxGetString();

            //var v = n(ref env, "from Java_TestHybridOVR_OVRJVM_ApplicationActivity_stringFromJNI");
            var v = n(ref env, x);

            return v;
        }
        // JVM load the .so and calls this native function
        static jstring Java_OVROculus360Photos_Activities_xMarshal_stringFromJNI(
            // what would we be able to do inspecting the runtime?
             JNIEnv env,
            jobject thiz,
            jobject args
            )
        {
            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150607-1/vrcubeworld

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201505/20150525

            var x = default(jstring);

            if (yield != null)
                x = yield(env, thiz, args);

            return x;

            ////var n = env.NewStringUTF;

            ////Type.GetType(

            //// look almost the same file!

            //// OVR_VRAPI_EXPORT const char * vrapi_GetVersionString();

            //// if we change our NDK code, will nuget packaing work on the background, and also upgrade running apps?
            //var v = n(env, "from Java_OVROculus360PhotosNDK_Activities_xMarshal_stringFromJNI. yay");

            //return v;


            // ConfigurationCreateNuGetPackage.cs
        }
 static void onStop(ref JNIEnv env, jobject obj)
 {
     // 1980
     appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_STOP);
 }
        // JVM load the .so and calls this native function
        static long Java_OVROculus360Photos_Activities_xMarshal_nativeSetAppInterface(
             JNIEnv env,
            jclass clazz,


            // ApplicationActivity : com.oculus.vrappframework.VrActivity
            jobject activity,

            jstring fromPackageNameString,
            jstring commandString,
            jstring uriString
            )
        {
            // can we do typeof() yet and have our env from there?

            // Error	3	No overload for method '__android_log_print' takes 3 arguments	X:\jsc.svn\examples\java\android\synergy\OVROculus360PhotosNDK\OVROculus360PhotosNDK\xNativeActivity.cs	39	13	OVROculus360PhotosNDK

            // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20150721/ovroculus360photoshud
            ScriptCoreLibAndroidNDK.Library.ConsoleExtensions.trace("enter Java_OVROculus360Photos_Activities_xMarshal_nativeSetAppInterface");


            //Oculus360Photos_h.AtStartBackgroundPanoLoad = new object();
            xNativeAtStartBackgroundPanoLoad = xNativeAtStartBackgroundPanoLoadInvoke;

            //xNativeAtStartBackgroundPanoLoad("not yet loaded", null);


            var loctype = env.GetObjectClass(env, activity);
            var gtype = (jclass)env.NewGlobalRef(env, loctype);
            //var gtype = (jclass)env.NewGlobalRef<jclass>(env, loctype);

            var typeof_this = new __Type { arg0_env = env, arg1_type = gtype };

            //var setDefaultLocale = typeof_this.GetMethodID("setDefaultLocale", "()V");
            var setDefaultLocale = typeof_this.GetMethod("setDefaultLocale", "()V");

            //var setDefaultLocale = env.GetMethodID(env, loctype, "setDefaultLocale", "()V");

            //Type.GetMethod();



            ConsoleExtensions.tracei64("setDefaultLocale: ", (int)(object)setDefaultLocale);


            //            I/xNativeActivity(24350): [3194400] \xNativeActivity.cs:202 enter Java_OVROculus360Photos_Activities_xMarshal_nativeSetAppInterface
            //I/xNativeActivity(24350): [3194400] \xNativeActivity.cs:222 setDefaultLocale:  -2012160456

            //  public virtual void setDefaultLocale()
            //env.NewStringUTF(env, "en");


            //  error: undefined reference to '__new_jvalue'
            // env.CallVoidMethodA(env, activity, setDefaultLocale, args: default(jvalue[]));

            setDefaultLocale.Invoke(activity);

            return Oculus360Photos_h.Java_com_oculus_oculus360photossdk_MainActivity_nativeSetAppInterface(
                 env,
                //clazz,
                gtype,
                activity,
                fromPackageNameString,
                commandString,
                uriString,


                arg_AtStartBackgroundPanoLoad: xNativeAtStartBackgroundPanoLoad
            );
        }
        static void onDestroy(JNIEnv env, jobject obj)
        {
            // 1988
            appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_DESTROY);

            appThread.MessageQueue.ovrMessageQueue_Enable(false);

            appThread.ovrAppThread_Destroy(env);
            stdlib_h.free(appThread);
            appThread = null;

            ConsoleExtensions.trace("exit onDestroy");
        }
 static void onStart(ref JNIEnv env, jobject obj)
 {
     // 1952
     appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_START);
 }
 //jlong cxxSetAppInterface(JNIEnv* jni, jclass clazz, jobject activity);
 public static jlong cxxSetAppInterface(ref JNIEnv jni, jclass c, jobject activity,
     jstring fromPackageNameString, jstring commandString, jstring uriString)
 { return (jlong)(object)0; }
            // called by onDestroy, then free
            // Dispose
            public void ovrAppThread_Destroy(JNIEnv env)
            {
                //1922
                this.Thread.Join();

                env.DeleteGlobalRef(env, this.ActivityObject);
                this.MessageQueue.ovrMessageQueue_Destroy();
            }
        static void onResume(ref JNIEnv env, jobject obj)
        {
            // 1961

            ConsoleExtensions.trace("enter onResume, did we come back from the menu?");

            appThread.MessageQueue.ovrMessageQueue_PostMessageThenWait(MESSAGE.MESSAGE_ON_RESUME);
        }