diff --git a/apps/example/ios/Podfile.lock b/apps/example/ios/Podfile.lock index bb33cc217..2aa612e25 100644 --- a/apps/example/ios/Podfile.lock +++ b/apps/example/ios/Podfile.lock @@ -1865,7 +1865,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - react-native-wgpu (0.3.0): + - react-native-wgpu (0.3.1): - boost - DoubleConversion - fast_float @@ -2903,7 +2903,7 @@ SPEC CHECKSUMS: React-microtasksnativemodule: 75b6604b667d297292345302cc5bfb6b6aeccc1b react-native-safe-area-context: c6e2edd1c1da07bdce287fa9d9e60c5f7b514616 react-native-skia: 5bf2b2107cd7f2d806fd364f5e16b1c7554ed3cd - react-native-wgpu: 6704c6ad8ef91fdbbad58543089ac50c0e6f3fa7 + react-native-wgpu: e35c1eb10f65d23f3cee907d44a3ca0a3d7ccbbd React-NativeModulesApple: 879fbdc5dcff7136abceb7880fe8a2022a1bd7c3 React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d React-perflogger: 5536d2df3d18fe0920263466f7b46a56351c0510 diff --git a/packages/webgpu/apple/MainThreadUtils.h b/packages/webgpu/apple/MainThreadUtils.h new file mode 100644 index 000000000..0afb28fbf --- /dev/null +++ b/packages/webgpu/apple/MainThreadUtils.h @@ -0,0 +1,35 @@ +#pragma once + +#ifdef __APPLE__ + +#include +#include +#include + +namespace rnwgpu { + +namespace detail { +inline void RunOnMainThreadSyncInvoke(void *context) { + auto *funcPtr = static_cast *>(context); + (*funcPtr)(); +} +} // namespace detail + +inline void RunOnMainThreadSync(const std::function &task) { + if (!task) { + return; + } + + if (pthread_main_np() != 0) { + task(); + return; + } + + auto callable = task; + dispatch_sync_f(dispatch_get_main_queue(), &callable, + detail::RunOnMainThreadSyncInvoke); +} + +} // namespace rnwgpu + +#endif diff --git a/packages/webgpu/cpp/rnwgpu/SurfaceRegistry.h b/packages/webgpu/cpp/rnwgpu/SurfaceRegistry.h index 110a45d44..b7ae3663f 100644 --- a/packages/webgpu/cpp/rnwgpu/SurfaceRegistry.h +++ b/packages/webgpu/cpp/rnwgpu/SurfaceRegistry.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -7,6 +8,10 @@ #include "webgpu/webgpu_cpp.h" +#ifdef __APPLE__ +#include "../../apple/MainThreadUtils.h" +#endif + namespace rnwgpu { struct NativeInfo { @@ -31,7 +36,7 @@ class SurfaceInfo { std::unique_lock lock(_mutex); config.width = newWidth; config.height = newHeight; - _configure(); + _invokeOnMainThread([this]() { _applyConfigurationLocked(); }); } void configure(wgpu::SurfaceConfiguration &newConfig) { @@ -40,7 +45,7 @@ class SurfaceInfo { config.width = width; config.height = height; config.presentMode = wgpu::PresentMode::Fifo; - _configure(); + _invokeOnMainThread([this]() { _applyConfigurationLocked(); }); } void unconfigure() { @@ -78,7 +83,7 @@ class SurfaceInfo { // surface if (texture != nullptr) { config.usage = config.usage | wgpu::TextureUsage::CopyDst; - _configure(); + _invokeOnMainThread([this]() { _applyConfigurationLocked(); }); // We flush the offscreen texture to the onscreen one // TODO: there is a faster way to do this without validation? wgpu::CommandEncoderDescriptor encoderDesc; @@ -102,7 +107,7 @@ class SurfaceInfo { wgpu::CommandBuffer commands = encoder.Finish(); wgpu::Queue queue = device.GetQueue(); queue.Submit(1, &commands); - surface.Present(); + _invokeOnMainThread([this]() { surface.Present(); }); texture = nullptr; } } @@ -116,7 +121,7 @@ class SurfaceInfo { void present() { std::unique_lock lock(_mutex); if (surface) { - surface.Present(); + _invokeOnMainThread([this]() { surface.Present(); }); } } @@ -152,7 +157,15 @@ class SurfaceInfo { } private: - void _configure() { + void _invokeOnMainThread(const std::function &task) { +#ifdef __APPLE__ + RunOnMainThreadSync(task); +#else + task(); +#endif + } + + void _applyConfigurationLocked() { if (surface) { surface.Configure(&config); } else { diff --git a/packages/webgpu/package.json b/packages/webgpu/package.json index f302b6df0..3a688afe2 100644 --- a/packages/webgpu/package.json +++ b/packages/webgpu/package.json @@ -1,6 +1,6 @@ { "name": "react-native-wgpu", - "version": "0.3.1", + "version": "0.3.2", "description": "React Native WebGPU", "main": "lib/commonjs/index", "module": "lib/module/index",