I'm trying to make BabylonReactNative to work on macOS

It seems to be not.
I added several std::cout << "Testing" << std::endl; in initialization process of shared/BabylonNative.cpp, but none of them has shown.

Acutally, I cannot find which code in javascript calls files in shared folder.
it seems to be isolated from other parts…

Probably the easiest way to figure out where the initialization needs to happen is to debug the Android/iOS implementation and put breakpoints. If that still doesn’t help, maybe @ryantrem can help explain how everything is hooked up.

I found that when getObject(_env->rt) in 761st line of napi-inl.h is called third time, _value.kind_ becomes UndefinedKind(which should be ObjectKind) and it is sent to getObject and crashes.
Thus it seems to prohibits initialization.

I couldn’t put breakpoint on exact same line on iOS side thus I only used package from npm(only has binaries for that) for mobile side.
but I was able to put breakpoint at BabylonNativeInterop.mm of both side, so I put a breakpoint at BabylonNative::Initialize on 39th line of it.
Yes, macOS side crashed after exactly three times, but iOS side launched flawlessly.

So it can be assumed that 761st line of napi-inl.h is a procedure of initialization invoked by BabylonNative::Initialize, so on iOS side, since BabylonNative::Initialize didn’t crashed, therefore I guess getObject didn’t asserted. am I right?


ping @ryantrem , as suggested

+
I found another case that broke in same line: await BabylonNative.initializationPromise in ReactNativeEngine.ts.
according to that thread, his (or maybe her) case was caused by OpenGL settings, but macOS does not uses OpenGL anymore - it uses Metal.
then maybe my problem is related to Metal API settings?

I would recommend building from source to debug. Using packages is not going to tell you how things work underneath.

A few comments here:

  1. @bghgary said above “There is no JS object called BabylonNative,” but to be clear, there actually is in the context of Babylon React Native, and it is part of the code linked to earlier: BabylonReactNative/BabylonNative.cpp at master · jihoobyeon/BabylonReactNative (github.com)
  2. From discussion above, it sounds like UpdateGraphicsConfiguration is not being called when you run your app. This is called from UpdateView and RenderView, both of which are called from the MacOS specific EngineViewManager.mm that you added in your fork. So I would verify whether that code is getting hit, which presumably it is not. This is just a regular React Native view, so if that isn’t even working, then it would seem like something in the way the native view is plumbed in your fork isn’t working correctly.
  3. As @bghgary mentioned, if you are trying to compare behavior, then it seems like building/running the Playground for iOS alongside MacOS in your repo would be best so you can set breakpoints and compare. Is there any reason you are using the precompiled packages instead?
1 Like

I stand corrected :slight_smile:

Oh, I had made a mistake. I omitted await before BabylonNative.initializationPromise; before and forgot to readd it. sorry for that.
Now everything is called, no error appears but still nothing shows up except FPS info:

Yes, returned to April’s situation…

You can try using Xcode metal debugger to see if things look weird or debug the frame rendering code.

Okay, it seems to EngineView has made properly, but with no content on it.


Strangely, FPS info in Xcode indicates 0, but FPS info in app indicates around 60.
so I think the engine has initialized properly, but failed attach to React Native…
also I tried console.log everything, and all has made properly. no null or undefineds.

Can you tell me which code is responsible for attaching to React Native?
it may be caused from React Native side, so I’m going to test attaching code to figure out which side has problem.

@ryantrem probably knows this better than me.

I’m not sure what you mean by “attaching to React Native,” but here are some important steps in the initialization of Babylon React Native:

  1. useEngine begins the initialization, including the initial calls to the native side to start setting up Babylon Native (EngineHook.ts)
  2. EngineView creates a native view and provides a pointer to the rendering surface to Babylon Native, which allows the initialization started in the previous step to complete (EngineView.tsx)
  3. EngineView will start the render loop automatically when a camera is provided (EngineView.tsx)
  4. The native EngineView is responsible for telling Babylon Native when to render via a call to RenderView (BabylonNative.cpp)
  5. The call to RenderView eventually leads to a call to DeviceImpl::Frame (DeviceImpl.cpp).

Can you verify all these things are happening? If all this is happening, then it should result in a call to bgfx::frame in which case I would not expect to see 0 fps in Xcode when looking at gpu info.

2 Likes

I found that a while loop in DeviceImpl.cpp is not working. checked everything else is fine.

I guess maybe the engine had created successfully and running, but not linked to React Native properly, thus just not showing graphic animations even it have made - since FPS indicator in RN app is changing by time.

That while loop shouldn’t matter for your scenario, it is effectively just responding to requests for screenshots. If the bgfx::frame call is happening, but nothing renders and you see 0 fps for the GPU, then it seems like something deeper in Babylon Native is not working. @bghgary any additional thoughts here? It sounds like the actual RN integration is setup correctly.

1 Like

I guess the next step is to verify that NativeEngine.cpp is actually trying to draw something. Try putting a breakpoint in DrawInternal and see if it hits.

BabylonNative/NativeEngine.cpp at 60961a663961002aa0971bcee21fe3a1cdd81520 · BabylonJS/BabylonNative (github.com)

OK, I tested NativeEngine::DrawInternal and I found that fillMode is always 0. does this is expected?
and also boundFrameBuffer.HasDepth() exists, so line 1921 never runs.

All other lines hits, so it seems trying to draw.

This is reasonable, yes.

Then do you have any other suspects? how about you, @ryantrem ?

It’s may be time to start debugging the Babylon::Graphics::DeviceImpl code and eventually into bgfx starting from bgfx::frame. Since you are on macOS, the relevant file in bgfx is renderer_mtl.mm. Put a breakpoint in the submit function to see what bgfx is trying to do. If the metal frame debugger is accurate, you may not be hitting this breakpoint at all and if so, we need to figure out why.

1 Like

You were right! I found that RendererContextMtl::submit does not hits any breakpoints or logs couts I’ve added. so it isn’t invoked certainly.

1 Like

I found that m_renderCtx->submit is calling RendererContextNOOP::submit instead of RendererContextMtl::submit.
what is noop and why it is called instead of Metal?