@@ -55,28 +55,20 @@ jsi::Value GPUCanvasContext::getCurrentTexture(jsi::Runtime &runtime,
5555 surfaceInfo->present ();
5656 return jsi::Value::undefined ();
5757 };
58- auto makeFn = [&]() {
59- return jsi::Function::createFromHostFunction (
60- runtime, jsi::PropNameID::forAscii (runtime, " WebGPUPresent" ), 0 ,
61- presentCb);
62- };
63- // Try queueMicrotask first (Hermes JS thread). If the runtime disables
64- // microtasks (e.g. Worklets), fall back to setImmediate, then setTimeout —
65- // both have end-of-current-task semantics with no display latency.
66- try {
67- runtime.queueMicrotask (makeFn ());
68- return JSIConverter<std::shared_ptr<GPUTexture>>::toJSI (
69- runtime, std::make_shared<GPUTexture>(texture, " " , false ));
70- } catch (...) {
71- // fall through
72- }
73- auto global = runtime.global ();
74- if (global.hasProperty (runtime, " setImmediate" )) {
75- auto setImmediate = global.getPropertyAsFunction (runtime, " setImmediate" );
76- setImmediate.call (runtime, makeFn ());
77- } else if (global.hasProperty (runtime, " setTimeout" )) {
78- auto setTimeout = global.getPropertyAsFunction (runtime, " setTimeout" );
79- setTimeout.call (runtime, makeFn (), jsi::Value (0 ));
58+ auto fn = jsi::Function::createFromHostFunction (
59+ runtime, jsi::PropNameID::forAscii (runtime, " WebGPUPresent" ), 0 ,
60+ presentCb);
61+
62+ // On the main JS runtime (Hermes), schedule the present as a microtask —
63+ // it runs at end of current task with no display latency.
64+ // On other runtimes (Worklets), microtasks are disabled, so use
65+ // setTimeout(fn, 0) which gives the same end-of-task semantics.
66+ if (&runtime == RNWebGPUManager::getMainJSRuntime ()) {
67+ runtime.queueMicrotask (std::move (fn));
68+ } else {
69+ auto setTimeout =
70+ runtime.global ().getPropertyAsFunction (runtime, " setTimeout" );
71+ setTimeout.call (runtime, fn, jsi::Value (0 ));
8072 }
8173
8274 // Pass reportsMemoryPressure=false to avoid triggering spurious Hermes GC
0 commit comments