Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
5d020b9
Add integrations project
ryantrem Apr 30, 2026
286b40c
Handle mouse input
ryantrem Apr 30, 2026
3e4c4e2
Unified log/error callback
ryantrem Apr 30, 2026
722dadf
Use Integration layer in Playground win32
ryantrem Apr 30, 2026
23c8ec3
Add NativeXR support
ryantrem May 1, 2026
8c34363
Use WindowT
ryantrem May 1, 2026
1b1ae7d
Use WindowT
ryantrem May 1, 2026
c24d053
Use arcana task_completion_source
ryantrem May 1, 2026
0c32f8f
Use Integration layer in Playground Android
ryantrem May 4, 2026
bfb8dbc
Android simplification
ryantrem May 4, 2026
7655d65
Update plan for auto suspend/resume
ryantrem May 4, 2026
3c5d1d2
Android simplification
ryantrem May 4, 2026
e611bc3
Android simplification
ryantrem May 4, 2026
710d0ad
DPR improvements
ryantrem May 5, 2026
4c3593a
Remove ViewDescriptor
ryantrem May 5, 2026
a6cbe1f
Platform specific query window dimensions and coerce input coordinates
ryantrem May 5, 2026
baa9738
QueueScripts -> LoadScripts
ryantrem May 5, 2026
3add674
Port iOS Playground app (untested)
ryantrem May 5, 2026
5ce6913
Fix QuerySize for iOS
ryantrem May 5, 2026
8696c03
Auto delegate on iOS
ryantrem May 5, 2026
8d00baa
Expose default delegate
ryantrem May 5, 2026
799d403
Remove bad EnableRendering/DisableRendering
ryantrem May 8, 2026
f5c2bc8
Simplify JNI function names
ryantrem May 8, 2026
1b7a58e
Implicit View suspend/resume
ryantrem May 11, 2026
40912d2
Move RunFirstAttachInit to runtime
ryantrem May 11, 2026
af7015c
Throw errors from interop layers for features that weren't compiled in
ryantrem May 11, 2026
d22f40b
Add missed changes to md
ryantrem May 11, 2026
91e04d3
Merge remote-tracking branch 'ryantrem/integrations' into integrations
ryantrem May 11, 2026
659339d
Remove accidentally added file
ryantrem May 11, 2026
8777759
Merge remote-tracking branch 'origin/master' into integrations
ryantrem May 11, 2026
4c9e7d1
Add missing polyfills
ryantrem May 12, 2026
700b917
Merge remote-tracking branch 'ryantrem/integrations' into integrations
ryantrem May 12, 2026
12b60a2
Add missing cmake dep
ryantrem May 13, 2026
37cdac5
Fix dpr issues
ryantrem May 13, 2026
83a099e
Move ViewSize out of public API
ryantrem May 13, 2026
50655a4
Re-org sources
ryantrem May 15, 2026
51f9f88
Add infinity check
ryantrem May 15, 2026
0f64bae
Merge master
ryantrem May 15, 2026
93f2d3c
Add options object at platform interop layers
ryantrem May 15, 2026
31f2afd
Work around bgfx::init bug for Apple
ryantrem May 15, 2026
2f3f9d2
Add bug link
ryantrem May 15, 2026
b36c1db
Defer View init until first resize
ryantrem May 15, 2026
d9ebdee
Improve logging config and output for Apple
ryantrem May 15, 2026
f2273ef
Merge remote-tracking branch 'origin/master' into integrations
ryantrem May 15, 2026
3dfc1b0
Defer View init until resume (if needed)
ryantrem May 16, 2026
31524ab
Win32 initialization ordering
ryantrem May 16, 2026
6defe89
Comments cleanup
ryantrem May 18, 2026
6c29a18
Switch to regular constructed objects instead of factory functions
ryantrem May 19, 2026
3a01fc4
Add optional param for RunOnJsThread for ScriptLoader vs. AppRuntime …
ryantrem May 20, 2026
e71933b
Port UWP Playground
ryantrem May 20, 2026
8a00f5f
Port MacOS Playground
ryantrem May 20, 2026
bbdcb29
Initial resize in BNView
ryantrem May 21, 2026
dcac7ae
Initial resize in Android interop layer
ryantrem May 21, 2026
dfd9761
Port VisionOS Playground
ryantrem May 21, 2026
b877202
Port X11 Playground
ryantrem May 21, 2026
756d5f3
PR feedback
ryantrem May 21, 2026
21863ae
PR feedback
ryantrem May 21, 2026
47e9684
noexcept for destruction
ryantrem May 21, 2026
86f0b18
Delete plan
ryantrem May 21, 2026
27a535a
Add missing initial Resize for Win32 Playground app
ryantrem May 21, 2026
b33575a
Remove AppContext
ryantrem May 22, 2026
9eeef9b
Roll back to assert from destructor
ryantrem May 22, 2026
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
16 changes: 9 additions & 7 deletions .github/instructions/babylon-native-debugging.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ For pure RenderDoc CLI usage (any app, not BN-specific), see
|---|---|
| `Apps/Playground/Shared/CommandLine.{h,cpp}` | Argument parser. Single source of truth for supported flags. |
| `Apps/Playground/Shared/Diagnostics.{h,cpp}` | Crash handler, `DumpFailure`, finish-line, exit-code tracking. |
| `Apps/Playground/Shared/AppContext.cpp` | Wires `UnhandledExceptionHandler` + `console.error` into `DumpFailure`; injects `_playgroundOptions` into JS. |
| `Apps/Playground/Win32/App.cpp` (and the other per-host `App.*`) | Wires the `RuntimeOptions::log` callback into `DumpFailure` (`JS CONSOLE ERROR` for `LogLevel::Error`, `UNCAUGHT JS ERROR` for `LogLevel::Fatal`) and injects `_playgroundOptions` into JS via `Runtime::RunOnJsThread`. |
| `Apps/Playground/Scripts/validation_native.js` | Test runner. Reads `_playgroundOptions`, picks tests, calls `TestUtils.captureNextFrame()`. Reference-image load failures arrive via `BABYLON.Tools.LoadFile`'s `onLoadFileError` and are tagged with `MISSING_REFERENCE_IMAGE:`. |
| `Apps/Playground/Scripts/config.json` | Test catalog. Each entry has `title`, `playgroundId`/`scriptToRun`, `referenceImage`, optional `excludeFromAutomaticTesting`/`reason`/`onlyVisual`/`renderCount`/`capture`/`threshold`/`errorRatio`. |
| `Plugins/TestUtils/Source/TestUtils.cpp` | Native side of `TestUtils.captureNextFrame()` -- calls `m_deviceContext.RequestCaptureNextFrame()`. |
Expand Down Expand Up @@ -80,13 +80,15 @@ When you see `[Error] Error: Cannot load X` in stdout, **scroll up** --
short error line. The short line is kept so legacy log scrapers still match.

### 3. JS stack on every `console.error`
`AppContext.cpp`'s `Console::Initialize` callback calls
The Integrations layer's `Console::Initialize` callback calls
`Babylon::Polyfills::Console::CaptureCurrentJsStack(env)` on every
`LogLevel::Error` message and appends the captured stack to the
`DumpFailure` banner body. The capture is best-effort -- if the JS engine
can't produce a stack (no JS context active, etc.) the helper returns an
empty string and the banner just shows the message.
Do not add per-callsite stack capture -- it's automatic.
`LogLevel::Error` message and appends the captured stack to the message
body that the host's `RuntimeOptions::log` callback receives (which the
Playground hosts then route into the `DumpFailure` banner). The capture is
best-effort — if the JS engine can't produce a stack (no JS context active,
unsupported engine, etc.) the helper returns an empty string and the host
just gets the bare message.
Do not add per-callsite stack capture — it's automatic.

### 4. Colored finish line
`Playground: Finished in <time>. (exit <code>)` is printed once at every exit
Expand Down
53 changes: 21 additions & 32 deletions Apps/Playground/Android/BabylonNative/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,30 @@ project(BabylonNative)
get_filename_component(PLAYGROUND_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
get_filename_component(REPO_ROOT_DIR "${PLAYGROUND_DIR}/../.." ABSOLUTE)

# Build the cross-platform Integrations facade *and* the Android JNI
# interop layer (`libBabylonNativeIntegrations.so`). The Playground
# Android app loads that library directly via `BabylonNative.java`
# (in the `com.babylonjs.integrations` package).
set(BABYLON_NATIVE_INTEGRATIONS ON CACHE BOOL "" FORCE)
set(BABYLON_NATIVE_INTEGRATIONS_ANDROID ON CACHE BOOL "" FORCE)

add_subdirectory(${REPO_ROOT_DIR} "${CMAKE_CURRENT_BINARY_DIR}/BabylonNative")

add_library(BabylonNativeJNI SHARED
src/main/cpp/BabylonNativeJNI.cpp
${PLAYGROUND_DIR}/Shared/AppContext.cpp
${PLAYGROUND_DIR}/Shared/Diagnostics.cpp)
# Append a Playground-specific JNI helper to the generic
# BabylonNativeIntegrations target so the bootstrap script list can stay
# in Apps/Playground/Shared/PlaygroundScripts.{h,cpp} (shared with the
# Win32 / iOS / macOS hosts) instead of being duplicated on the Java
# side. Compiling these into the same .so keeps the Integrations layer
# as a single in-process instance — handles produced by one entry point
# can be safely consumed by another.
target_sources(BabylonNativeIntegrations
PRIVATE src/main/cpp/PlaygroundJNI.cpp
${PLAYGROUND_DIR}/Shared/Diagnostics.cpp
${PLAYGROUND_DIR}/Shared/PlaygroundScripts.cpp)

target_include_directories(BabylonNativeJNI
target_include_directories(BabylonNativeIntegrations
PRIVATE ${PLAYGROUND_DIR})

target_link_libraries(BabylonNativeJNI
PRIVATE GLESv3
PRIVATE android
target_link_libraries(BabylonNativeIntegrations
PRIVATE bx
PRIVATE EGL
PRIVATE log
PRIVATE -lz
PRIVATE AndroidExtensions
PRIVATE AppRuntime
PRIVATE Blob
PRIVATE Canvas
PRIVATE Console
PRIVATE GraphicsDevice
PRIVATE NativeCamera
PRIVATE NativeCapture
PRIVATE NativeEncoding
PRIVATE NativeEngine
PRIVATE NativeInput
PRIVATE NativeOptimizations
PRIVATE NativeTracing
PRIVATE NativeXr
PRIVATE Performance
PRIVATE ScriptLoader
PRIVATE ShaderCache
PRIVATE TestUtils
PRIVATE TextDecoder
PRIVATE Window
PRIVATE XMLHttpRequest)
PRIVATE Foundation) # for <Babylon/PerfTrace.h> in PlaygroundScripts.cpp
2 changes: 2 additions & 0 deletions Apps/Playground/Android/BabylonNative/consumer-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-keep class com.babylonjs.integrations.BabylonNative { *; }
-keep class com.babylonjs.integrations.BabylonNative$RuntimeOptions { *; }

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Playground-specific JNI helper. Built into the same .so as the generic
// Integrations/Android JNI (added via target_sources in the Playground
// CMakeLists), so there's a single copy of Babylon::Integrations across
// the process — avoids cross-library handle-passing UB.
//
// Sole purpose: surface Apps/Playground/Shared/PlaygroundScripts.{h,cpp}
// to Java so the bootstrap script list stays in one place, shared with
// the other Playground hosts.

#include <Babylon/Integrations/Runtime.h>
#include <Babylon/Integrations/Android/RuntimeHandle.h>

#include <Shared/PlaygroundScripts.h>

#include <jni.h>

extern "C"
{

JNIEXPORT void JNICALL
Java_com_android_babylonnative_playground_PlaygroundActivity_loadBootstrapScripts(
JNIEnv*, jclass, jlong runtimeHandle)
{
auto* runtime = Babylon::Integrations::Android::RuntimeFromHandle(runtimeHandle);
if (runtime == nullptr)
{
return;
}

// Idempotent process-wide setup (PerfTrace level, etc.).
Playground::Initialize();

// Queue bootstrap scripts; they run after the first View attach
// completes engine init on the JS thread.
Playground::LoadBootstrapScripts(*runtime);
}

} // extern "C"

Loading
Loading