Skip to content

Commit d856156

Browse files
bghgaryCopilot
andcommitted
Tests.ExternalTexture.Msaa: migrate to synchronous CreateForJavaScript
With BabylonJS#1646's synchronous ExternalTexture::CreateForJavaScript and BabylonJS#1652's new threading model both in this branch, the original test pattern is both unnecessary and broken: - Unnecessary: AddToContextAsync's two-frame dance (queue in frame 1, wait for bgfx::frame() to resolve the promise, run startup in frame 2) exists only because the texture wrap was async. CreateForJavaScript is synchronous so the wrap, startup(), and renderFrame() all run in the same JS task inside a single frame. - Broken: under the new model, SubmitCommands synchronously acquires a FrameCompletionScope which blocks when no frame is in progress. The old between-frames startup() pattern deadlocks. Collapse to a single frame + single dispatch that wraps the texture, runs startup(), and chains renderFrame()'s promise resolution. The host app pattern host apps should follow with the new API. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5f0249d commit d856156

1 file changed

Lines changed: 11 additions & 37 deletions

File tree

Apps/UnitTests/Source/Tests.ExternalTexture.Msaa.cpp

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ namespace
3636
device.GetPlatformInfo().Device, TEX_SIZE, TEX_SIZE, 1, true, samples);
3737
Babylon::Plugins::ExternalTexture externalTexture{nativeTexture};
3838

39-
std::promise<void> startupDone;
40-
4139
Babylon::AppRuntime::Options options{};
4240
options.UnhandledExceptionHandler = [](const Napi::Error& error) {
4341
std::cerr << "[Uncaught Error] " << Napi::GetErrorString(error) << std::endl;
@@ -60,43 +58,19 @@ namespace
6058
loader.LoadScript("app:///Assets/babylon.max.js");
6159
loader.LoadScript("app:///Assets/tests.externalTexture.msaa.js");
6260

63-
// Queue AddToContextAsync inside the current bgfx frame and wire its .then to startup().
64-
std::promise<void> addToContextCalled;
65-
loader.Dispatch([&externalTexture, &addToContextCalled, &startupDone, samples](Napi::Env env) {
66-
auto jsPromise = externalTexture.AddToContextAsync(env);
67-
addToContextCalled.set_value();
68-
69-
auto jsOnFulfilled = Napi::Function::New(env, [&startupDone, samples](const Napi::CallbackInfo& info) {
70-
auto jsNativeTexture = info[0];
71-
info.Env().Global().Get("startup").As<Napi::Function>().Call({
72-
jsNativeTexture,
73-
Napi::Number::New(info.Env(), TEX_SIZE),
74-
Napi::Number::New(info.Env(), TEX_SIZE),
75-
Napi::Number::New(info.Env(), samples),
76-
});
77-
startupDone.set_value();
78-
});
79-
80-
auto jsOnRejected = Napi::Function::New(env, [&startupDone](const Napi::CallbackInfo& info) {
81-
startupDone.set_exception(std::make_exception_ptr(
82-
std::runtime_error{Napi::GetErrorString(info[0].As<Napi::Error>())}));
61+
// CreateForJavaScript is synchronous so startup() can run in the same JS task as the
62+
// texture wrap. renderFrame() submits draw commands which are flushed when the frame ends.
63+
std::promise<void> renderDone;
64+
loader.Dispatch([&externalTexture, &renderDone, samples](Napi::Env env) {
65+
auto jsNativeTexture = externalTexture.CreateForJavaScript(env);
66+
67+
env.Global().Get("startup").As<Napi::Function>().Call({
68+
jsNativeTexture,
69+
Napi::Number::New(env, TEX_SIZE),
70+
Napi::Number::New(env, TEX_SIZE),
71+
Napi::Number::New(env, samples),
8372
});
8473

85-
jsPromise.Get("then").As<Napi::Function>().Call(jsPromise, {jsOnFulfilled, jsOnRejected});
86-
});
87-
88-
// Ensure AddToContextAsync was queued in the current frame, then finish it so the promise resolves.
89-
addToContextCalled.get_future().wait();
90-
update.Finish();
91-
device.FinishRenderingCurrentFrame();
92-
startupDone.get_future().get();
93-
94-
// New frame: drive a single renderFrame() on the JS side.
95-
device.StartRenderingCurrentFrame();
96-
update.Start();
97-
98-
std::promise<void> renderDone;
99-
loader.Dispatch([&renderDone](Napi::Env env) {
10074
auto jsPromise = env.Global().Get("renderFrame").As<Napi::Function>().Call({}).As<Napi::Promise>();
10175

10276
auto jsOnFulfilled = Napi::Function::New(env, [&renderDone](const Napi::CallbackInfo&) {

0 commit comments

Comments
 (0)