@@ -572,7 +572,7 @@ std::string VROPlatformDownloadURLToFile(std::string url, bool *temp, bool *succ
572572 JNIEnv *env = VROPlatformGetJNIEnv ();
573573 VRO_STRING jurl = VRO_NEW_STRING (url.c_str ());
574574
575- jclass cls = env->FindClass ( " com/viro/core/internal/PlatformUtil " );
575+ jclass cls = env->GetObjectClass ( sPlatformUtil );
576576 jmethodID jmethod = env->GetMethodID (cls, " downloadURLToTempFile" , " (Ljava/lang/String;)Ljava/lang/String;" );
577577 VRO_STRING jpath = (VRO_STRING) env->CallObjectMethod (sPlatformUtil , jmethod, jurl);
578578
@@ -1069,14 +1069,42 @@ void VROPlatformDispatchAsyncBackground(std::function<void()> fcn) {
10691069 JNIEnv *env;
10701070 getJNIEnv (&env);
10711071
1072- jclass cls = env->FindClass (" com/viro/core/internal/PlatformUtil" );
1072+ // GetObjectClass works on any thread (no class-loader dependency).
1073+ // FindClass("com/viro/core/...") fails on pure-native threads that only
1074+ // have the bootstrap class loader (e.g. the OpenXR render thread).
1075+ jclass cls = env->GetObjectClass (sPlatformUtil );
10731076 jmethodID jmethod = env->GetMethodID (cls, " dispatchAsyncBackground" , " (I)V" );
10741077 env->CallVoidMethod (sPlatformUtil , jmethod, task);
10751078
10761079 env->DeleteLocalRef (cls);
10771080}
10781081
1082+ // ── Direct renderer queue (for OpenXR / renderers without GLSurfaceView) ──────
1083+ static std::atomic<bool > sUseDirectRendererQueue { false };
1084+ static std::mutex sDirectRendererQueueMutex ;
1085+ static std::vector<std::function<void ()>> sDirectRendererQueue;
1086+
1087+ void VROPlatformSetUseDirectRendererQueue (bool use) {
1088+ sUseDirectRendererQueue .store (use);
1089+ }
1090+
1091+ void VROPlatformDrainRendererQueue () {
1092+ std::vector<std::function<void ()>> tasks;
1093+ {
1094+ std::lock_guard<std::mutex> guard (sDirectRendererQueueMutex );
1095+ tasks.swap (sDirectRendererQueue );
1096+ }
1097+ for (auto &task : tasks) {
1098+ task ();
1099+ }
1100+ }
1101+
10791102void VROPlatformDispatchAsyncRenderer (std::function<void ()> fcn) {
1103+ if (sUseDirectRendererQueue .load ()) {
1104+ std::lock_guard<std::mutex> guard (sDirectRendererQueueMutex );
1105+ sDirectRendererQueue .push_back (std::move (fcn));
1106+ return ;
1107+ }
10801108 int task = VROPlatformGenerateTask (fcn);
10811109 if (!sPlatformUtil ) {
10821110 std::lock_guard<std::mutex> guard (sRendererQueueMutex );
@@ -1105,7 +1133,7 @@ void VROPlatformFlushTaskQueues() {
11051133 JNIEnv *env;
11061134 getJNIEnv (&env);
11071135
1108- jclass cls = env->FindClass ( " com/viro/core/internal/PlatformUtil " );
1136+ jclass cls = env->GetObjectClass ( sPlatformUtil );
11091137 jmethodID jmethod = env->GetMethodID (cls, " dispatchAsyncBackground" , " (I)V" );
11101138 env->CallVoidMethod (sPlatformUtil , jmethod, task);
11111139
@@ -1299,7 +1327,7 @@ std::string VROPlatformGetCacheDirectory() {
12991327 JNIEnv *env;
13001328 getJNIEnv (&env);
13011329
1302- jclass cls = env->FindClass ( " com/viro/core/internal/PlatformUtil " );
1330+ jclass cls = env->GetObjectClass ( sPlatformUtil );
13031331 jmethodID jmethod = env->GetMethodID (cls, " getCacheDirectory" , " ()Ljava/lang/String;" );
13041332 VRO_STRING jpath = (VRO_STRING) env->CallObjectMethod (sPlatformUtil , jmethod);
13051333
0 commit comments