From 1366b09abe2fca62783326694fe430d5b0cd91f0 Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Thu, 19 Nov 2020 17:28:09 -0800 Subject: [PATCH 1/8] Reset graphics when NativeEngine is disposed to release bgfx mem --- Modules/@babylonjs/react-native/BabylonModule.ts | 6 ++++-- Modules/@babylonjs/react-native/EngineHook.ts | 1 + Modules/@babylonjs/react-native/ios/BabylonModule.mm | 4 ++++ Modules/@babylonjs/react-native/ios/BabylonNative.cpp | 6 ++++++ Modules/@babylonjs/react-native/ios/BabylonNative.h | 1 + Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h | 1 + .../@babylonjs/react-native/ios/BabylonNativeInterop.mm | 7 +++++++ Modules/@babylonjs/react-native/submodules/BabylonNative | 2 +- 8 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Modules/@babylonjs/react-native/BabylonModule.ts b/Modules/@babylonjs/react-native/BabylonModule.ts index 1803f11c1..9c03716d0 100644 --- a/Modules/@babylonjs/react-native/BabylonModule.ts +++ b/Modules/@babylonjs/react-native/BabylonModule.ts @@ -3,25 +3,27 @@ import { NativeEngine } from '@babylonjs/core'; // This global object is part of Babylon Native. declare const _native: { - graphicsInitializationPromise: Promise; + whenGraphicsReady: () => Promise; engineInstance: NativeEngine; } const NativeBabylonModule: { initialize(): Promise; whenInitialized(): Promise; + reset(): Promise; } = NativeModules.BabylonModule; export const BabylonModule = { initialize: async () => { const initialized = await NativeBabylonModule.initialize(); if (initialized) { - await _native.graphicsInitializationPromise; + await _native.whenGraphicsReady(); } return initialized; }, whenInitialized: NativeBabylonModule.whenInitialized, + reset: NativeBabylonModule.reset, createEngine: () => { const engine = new NativeEngine(); diff --git a/Modules/@babylonjs/react-native/EngineHook.ts b/Modules/@babylonjs/react-native/EngineHook.ts index 3491e3849..4ba0536eb 100644 --- a/Modules/@babylonjs/react-native/EngineHook.ts +++ b/Modules/@babylonjs/react-native/EngineHook.ts @@ -83,6 +83,7 @@ export function useEngine(): Engine | undefined { if (engine) { DisposeEngine(engine); } + BabylonModule.reset(); setEngine(undefined); }; }, []); diff --git a/Modules/@babylonjs/react-native/ios/BabylonModule.mm b/Modules/@babylonjs/react-native/ios/BabylonModule.mm index 71f8b1669..f2d1dfba0 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonModule.mm +++ b/Modules/@babylonjs/react-native/ios/BabylonModule.mm @@ -21,4 +21,8 @@ @implementation BabylonModule [BabylonNativeInterop whenInitialized:self.bridge resolve:resolve]; } +RCT_EXPORT_METHOD(reset:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { + [BabylonNativeInterop reset:self.bridge resolve:resolve]; +} + @end diff --git a/Modules/@babylonjs/react-native/ios/BabylonNative.cpp b/Modules/@babylonjs/react-native/ios/BabylonNative.cpp index 01cd49d06..541c63d6c 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNative.cpp +++ b/Modules/@babylonjs/react-native/ios/BabylonNative.cpp @@ -87,6 +87,7 @@ namespace Babylon { m_impl->graphics->UpdateWindow(windowPtr); m_impl->graphics->UpdateSize(width, height); + m_impl->graphics->EnableRendering(); } void Native::Resize(size_t width, size_t height) @@ -94,6 +95,11 @@ namespace Babylon m_impl->graphics->UpdateSize(width, height); } + void Native::Reset() + { + m_impl->graphics->DisableRendering(); + } + void Native::SetPointerButtonState(uint32_t pointerId, uint32_t buttonId, bool isDown, uint32_t x, uint32_t y) { if (isDown) diff --git a/Modules/@babylonjs/react-native/ios/BabylonNative.h b/Modules/@babylonjs/react-native/ios/BabylonNative.h index f021f7246..d7ce8fa97 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNative.h +++ b/Modules/@babylonjs/react-native/ios/BabylonNative.h @@ -13,6 +13,7 @@ namespace Babylon ~Native(); void Refresh(void* windowPtr, size_t width, size_t height); void Resize(size_t width, size_t height); + void Reset(); void SetPointerButtonState(uint32_t pointerId, uint32_t buttonId, bool isDown, uint32_t x, uint32_t y); void SetPointerPosition(uint32_t pointerId, uint32_t x, uint32_t y); diff --git a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h index e829ec41b..27ec5d110 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h +++ b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h @@ -7,4 +7,5 @@ + (void)setView:(RCTBridge*)bridge jsRunLoop:(NSRunLoop*)jsRunLoop mktView:(MTKView*)mtkView; + (void)reportTouchEvent:(NSSet*)touches withEvent:(UIEvent*)event; + (void)whenInitialized:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resolve; ++ (void)reset:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resolve; @end diff --git a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm index a7e3d8793..91af5fbca 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm +++ b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm @@ -115,6 +115,13 @@ + (void)whenInitialized:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resol } } ++ (void)reset:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resolve { + if (currentNativeInstance) { + currentNativeInstance->Reset(); + } + resolve([NSNull null]); +} + + (void)setCurrentView:(MTKView*)mtkView { currentView = mtkView; activeTouches = [NSMutableArray new]; diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index d9042b8ff..4fd739d92 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit d9042b8ff52fad2c9bcbc27f4999ba944c68d57d +Subproject commit 4fd739d922ddfee139f03d24e72a524898b56d48 From 5cf70c4a2330f2f625a0046667c3010050ac37be Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Thu, 19 Nov 2020 17:37:36 -0800 Subject: [PATCH 2/8] Remove unused params --- Modules/@babylonjs/react-native/ios/BabylonModule.mm | 3 ++- Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h | 2 +- Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/@babylonjs/react-native/ios/BabylonModule.mm b/Modules/@babylonjs/react-native/ios/BabylonModule.mm index f2d1dfba0..5f7a6e8b1 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonModule.mm +++ b/Modules/@babylonjs/react-native/ios/BabylonModule.mm @@ -22,7 +22,8 @@ @implementation BabylonModule } RCT_EXPORT_METHOD(reset:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - [BabylonNativeInterop reset:self.bridge resolve:resolve]; + [BabylonNativeInterop reset]; + resolve([NSNull null]); } @end diff --git a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h index 27ec5d110..2ecca3399 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h +++ b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.h @@ -7,5 +7,5 @@ + (void)setView:(RCTBridge*)bridge jsRunLoop:(NSRunLoop*)jsRunLoop mktView:(MTKView*)mtkView; + (void)reportTouchEvent:(NSSet*)touches withEvent:(UIEvent*)event; + (void)whenInitialized:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resolve; -+ (void)reset:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resolve; ++ (void)reset; @end diff --git a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm index 91af5fbca..857b45ee1 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm +++ b/Modules/@babylonjs/react-native/ios/BabylonNativeInterop.mm @@ -115,11 +115,10 @@ + (void)whenInitialized:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resol } } -+ (void)reset:(RCTBridge*)bridge resolve:(RCTPromiseResolveBlock)resolve { ++ (void)reset { if (currentNativeInstance) { currentNativeInstance->Reset(); } - resolve([NSNull null]); } + (void)setCurrentView:(MTKView*)mtkView { From 682a8eb34922efc43e0ca6fff62f2738c444dd20 Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Fri, 20 Nov 2020 12:04:39 -0800 Subject: [PATCH 3/8] Shutdown on JS thread (since this is the render thread currently) --- Modules/@babylonjs/react-native/ios/BabylonModule.mm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Modules/@babylonjs/react-native/ios/BabylonModule.mm b/Modules/@babylonjs/react-native/ios/BabylonModule.mm index 5f7a6e8b1..05af48afc 100644 --- a/Modules/@babylonjs/react-native/ios/BabylonModule.mm +++ b/Modules/@babylonjs/react-native/ios/BabylonModule.mm @@ -1,9 +1,14 @@ #import "BabylonNativeInterop.h" #import +#import #import +@interface RCTBridge (RCTTurboModule) +- (std::shared_ptr)jsCallInvoker; +@end + @interface BabylonModule : NSObject @end @@ -22,8 +27,10 @@ @implementation BabylonModule } RCT_EXPORT_METHOD(reset:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - [BabylonNativeInterop reset]; - resolve([NSNull null]); + self.bridge.jsCallInvoker->invokeAsync([resolve]() { + [BabylonNativeInterop reset]; + resolve([NSNull null]); + }); } @end From 2ea7e7b408d0bfb51cd365ab2bf04fed4681272d Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Fri, 20 Nov 2020 12:05:16 -0800 Subject: [PATCH 4/8] Add reset function to Android --- .../android/src/main/cpp/BabylonNativeInterop.cpp | 12 ++++++++++++ .../java/com/babylonreactnative/BabylonModule.java | 8 ++++++++ .../com/babylonreactnative/BabylonNativeInterop.java | 12 ++++++++++++ 3 files changed, 32 insertions(+) diff --git a/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp b/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp index ec36efc46..a69bd1b82 100644 --- a/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp +++ b/Modules/@babylonjs/react-native/android/src/main/cpp/BabylonNativeInterop.cpp @@ -85,6 +85,12 @@ namespace Babylon auto height = static_cast(ANativeWindow_getHeight(windowPtr)); m_graphics->UpdateWindow(windowPtr); m_graphics->UpdateSize(width, height); + m_graphics->EnableRendering(); + } + + void Reset() + { + m_graphics->DisableRendering(); } void SetPointerButtonState(uint32_t pointerId, uint32_t buttonId, bool isDown, uint32_t x, uint32_t y) @@ -166,6 +172,12 @@ extern "C" JNIEXPORT void JNICALL Java_com_babylonreactnative_BabylonNativeInter native->SetPointerPosition(static_cast(pointerId), static_cast(x), static_cast(y)); } +extern "C" JNIEXPORT void JNICALL Java_com_babylonreactnative_BabylonNativeInterop_reset(JNIEnv* env, jclass obj, jlong instanceRef) +{ + auto native = reinterpret_cast(instanceRef); + native->Reset(); +} + extern "C" JNIEXPORT void JNICALL Java_com_babylonreactnative_BabylonNativeInterop_destroy(JNIEnv* env, jclass obj, jlong instanceRef) { auto native = reinterpret_cast(instanceRef); diff --git a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java index 1fb1fcbcc..573bc0e76 100644 --- a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java +++ b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonModule.java @@ -39,4 +39,12 @@ public void initialize(Promise promise) { public void whenInitialized(Promise promise) { BabylonNativeInterop.whenInitialized(this.getReactApplicationContext()).thenAccept(instanceRef -> promise.resolve(instanceRef != 0)); } + + @ReactMethod + public void reset(Promise promise) { + this.getReactApplicationContext().runOnJSQueueThread(() -> { + BabylonNativeInterop.reset(this.getReactApplicationContext()); + promise.resolve(null); + }); + } } diff --git a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java index ee0ff9d6e..fa4d8231f 100644 --- a/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java +++ b/Modules/@babylonjs/react-native/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java @@ -35,6 +35,7 @@ final class BabylonNativeInterop { private static native void refresh(long instanceRef, Surface surface); private static native void setPointerButtonState(long instanceRef, int pointerId, int buttonId, boolean isDown, int x, int y); private static native void setPointerPosition(long instanceRef, int pointerId, int x, int y); + private static native void reset(long instanceRef); private static native void destroy(long instanceRef); // Must be called from the Android UI thread @@ -137,6 +138,17 @@ static void deinitialize() { BabylonNativeInterop.destroyOldNativeInstances(null); } + static void reset(ReactContext reactContext) { + JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder(); + CompletableFuture instanceRefFuture = BabylonNativeInterop.nativeInstances.get(jsContext); + if (instanceRefFuture != null) { + Long instanceRef = instanceRefFuture.getNow(null); + if (instanceRef != null) { + BabylonNativeInterop.reset(instanceRef); + } + } + } + private static CompletableFuture getOrCreateFuture(ReactContext reactContext) { JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder(); CompletableFuture instanceRefFuture = BabylonNativeInterop.nativeInstances.get(jsContext); From 09091299c9e189df8f1b48360254caf1f33f9829 Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Fri, 20 Nov 2020 14:58:32 -0800 Subject: [PATCH 5/8] Update Babylon Native --- Modules/@babylonjs/react-native/submodules/BabylonNative | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index 4fd739d92..eeb16da60 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit 4fd739d922ddfee139f03d24e72a524898b56d48 +Subproject commit eeb16da606c9f33d1ddd63b1445360f5fa33fa39 From 3e2ad2e0551435f9dc7417fc43babceba7a681fd Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Fri, 20 Nov 2020 16:01:33 -0800 Subject: [PATCH 6/8] Update Babylon Native --- Modules/@babylonjs/react-native/submodules/BabylonNative | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index eeb16da60..517de6139 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit eeb16da606c9f33d1ddd63b1445360f5fa33fa39 +Subproject commit 517de613912b19da56b87731ea1b0949d9d7fea2 From 3e3a3b19a950c8e6f07b93d00e391a118e14e29c Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Wed, 25 Nov 2020 17:38:37 -0800 Subject: [PATCH 7/8] Merge Babylon Native master --- Modules/@babylonjs/react-native/submodules/BabylonNative | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index 517de6139..9e67c7aa3 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit 517de613912b19da56b87731ea1b0949d9d7fea2 +Subproject commit 9e67c7aa34ae34f525fdb8134dfb8f9669f002a5 From 7ad27201ea70252cec2bb80aa4d5ddb5c143828e Mon Sep 17 00:00:00 2001 From: Ryan Tremblay Date: Mon, 30 Nov 2020 12:21:56 -0800 Subject: [PATCH 8/8] Update to Babylon Native master --- Modules/@babylonjs/react-native/submodules/BabylonNative | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/@babylonjs/react-native/submodules/BabylonNative b/Modules/@babylonjs/react-native/submodules/BabylonNative index 9e67c7aa3..26c4b2d0a 160000 --- a/Modules/@babylonjs/react-native/submodules/BabylonNative +++ b/Modules/@babylonjs/react-native/submodules/BabylonNative @@ -1 +1 @@ -Subproject commit 9e67c7aa34ae34f525fdb8134dfb8f9669f002a5 +Subproject commit 26c4b2d0a573c61e46695ff449b05c24ec40aa6f