react-native-wgpu 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/README.md +155 -69
  2. package/android/CMakeLists.txt +4 -5
  3. package/android/build.gradle +7 -18
  4. package/android/src/main/java/com/webgpu/WebGPUViewPackage.java +34 -10
  5. package/apple/MetalView.mm +0 -19
  6. package/apple/WebGPUModule.h +1 -9
  7. package/apple/WebGPUModule.mm +0 -3
  8. package/apple/WebGPUView.h +0 -3
  9. package/apple/WebGPUView.mm +0 -2
  10. package/cpp/WGPULogger.h +10 -0
  11. package/cpp/dawn/dawn_proc_table.h +1 -1
  12. package/cpp/dawn/webgpu.h +4855 -0
  13. package/cpp/dawn/webgpu_cpp.h +10168 -0
  14. package/cpp/dawn/wire/client/webgpu.h +354 -0
  15. package/cpp/dawn/wire/client/webgpu_cpp.h +10343 -0
  16. package/cpp/dawn/wire/client/webgpu_cpp_print.h +2715 -0
  17. package/cpp/jsi/RNFJSIConverter.h +17 -59
  18. package/cpp/rnwgpu/RNWebGPUManager.cpp +1 -9
  19. package/cpp/rnwgpu/api/GPU.cpp +51 -26
  20. package/cpp/rnwgpu/api/GPU.h +5 -18
  21. package/cpp/rnwgpu/api/GPUAdapter.cpp +75 -54
  22. package/cpp/rnwgpu/api/GPUAdapter.h +6 -6
  23. package/cpp/rnwgpu/api/GPUAdapterInfo.h +0 -1
  24. package/cpp/rnwgpu/api/GPUBindGroup.h +1 -3
  25. package/cpp/rnwgpu/api/GPUBindGroupLayout.h +1 -3
  26. package/cpp/rnwgpu/api/GPUBuffer.cpp +35 -32
  27. package/cpp/rnwgpu/api/GPUBuffer.h +9 -7
  28. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +5 -1
  29. package/cpp/rnwgpu/api/GPUCanvasContext.h +0 -2
  30. package/cpp/rnwgpu/api/GPUCommandBuffer.h +1 -3
  31. package/cpp/rnwgpu/api/GPUCommandEncoder.h +1 -3
  32. package/cpp/rnwgpu/api/GPUCompilationInfo.h +0 -2
  33. package/cpp/rnwgpu/api/GPUCompilationMessage.h +1 -3
  34. package/cpp/rnwgpu/api/GPUComputePassEncoder.h +1 -3
  35. package/cpp/rnwgpu/api/GPUComputePipeline.h +1 -3
  36. package/cpp/rnwgpu/api/GPUDevice.cpp +183 -128
  37. package/cpp/rnwgpu/api/GPUDevice.h +22 -21
  38. package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +1 -3
  39. package/cpp/rnwgpu/api/GPUExternalTexture.h +1 -3
  40. package/cpp/rnwgpu/api/GPUPipelineLayout.h +1 -3
  41. package/cpp/rnwgpu/api/GPUQuerySet.h +1 -3
  42. package/cpp/rnwgpu/api/GPUQueue.cpp +19 -8
  43. package/cpp/rnwgpu/api/GPUQueue.h +7 -6
  44. package/cpp/rnwgpu/api/GPURenderBundle.h +1 -3
  45. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -3
  46. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -3
  47. package/cpp/rnwgpu/api/GPURenderPipeline.h +1 -3
  48. package/cpp/rnwgpu/api/GPUSampler.h +1 -3
  49. package/cpp/rnwgpu/api/GPUShaderModule.cpp +42 -28
  50. package/cpp/rnwgpu/api/GPUShaderModule.h +6 -6
  51. package/cpp/rnwgpu/api/GPUSupportedLimits.h +1 -3
  52. package/cpp/rnwgpu/api/GPUTexture.h +1 -3
  53. package/cpp/rnwgpu/api/GPUTextureView.h +1 -3
  54. package/cpp/rnwgpu/api/RNWebGPU.h +1 -7
  55. package/cpp/rnwgpu/async/AsyncDispatcher.h +28 -0
  56. package/cpp/rnwgpu/async/AsyncRunner.cpp +215 -0
  57. package/cpp/rnwgpu/async/AsyncRunner.h +53 -0
  58. package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +181 -0
  59. package/cpp/rnwgpu/async/AsyncTaskHandle.h +55 -0
  60. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.cpp +23 -0
  61. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.h +22 -0
  62. package/cpp/webgpu/webgpu.h +5 -4827
  63. package/cpp/webgpu/webgpu_cpp.h +5 -10140
  64. package/cpp/{dawn/native/WebGPUBackend.h → webgpu/webgpu_cpp_print.h} +4 -20
  65. package/lib/commonjs/Canvas.js +6 -66
  66. package/lib/commonjs/Canvas.js.map +1 -1
  67. package/lib/commonjs/hooks.js +6 -42
  68. package/lib/commonjs/hooks.js.map +1 -1
  69. package/lib/module/Canvas.js +7 -67
  70. package/lib/module/Canvas.js.map +1 -1
  71. package/lib/module/hooks.js +5 -40
  72. package/lib/module/hooks.js.map +1 -1
  73. package/lib/typescript/lib/commonjs/hooks.d.ts +1 -5
  74. package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -1
  75. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  76. package/lib/typescript/lib/module/hooks.d.ts +1 -5
  77. package/lib/typescript/lib/module/hooks.d.ts.map +1 -1
  78. package/lib/typescript/src/Canvas.d.ts +0 -1
  79. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  80. package/lib/typescript/src/hooks.d.ts +2 -7
  81. package/lib/typescript/src/hooks.d.ts.map +1 -1
  82. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  83. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  84. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  85. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  86. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +5 -35
  87. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  88. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  89. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  90. package/package.json +4 -3
  91. package/react-native-wgpu.podspec +12 -16
  92. package/src/Canvas.tsx +8 -69
  93. package/src/hooks.tsx +14 -48
  94. package/android/cpp/platform/ThreadUtils.cpp +0 -41
  95. package/android/src/oldarch/com/webgpu/NativeWebGPUModuleSpec.java +0 -23
  96. package/android/src/oldarch/com/webgpu/WebGPUViewManagerSpec.java +0 -12
  97. package/apple/WebGPUViewManager.mm +0 -24
  98. package/apple/platform/ThreadUtils.cpp +0 -34
  99. package/cpp/dawn/dawn_proc.h +0 -50
  100. package/cpp/dawn/dawn_thread_dispatch_proc.h +0 -47
  101. package/cpp/dawn/native/D3D11Backend.h +0 -77
  102. package/cpp/dawn/native/D3D12Backend.h +0 -68
  103. package/cpp/dawn/native/D3DBackend.h +0 -56
  104. package/cpp/dawn/native/MetalBackend.h +0 -56
  105. package/cpp/dawn/platform/DawnPlatform.h +0 -167
  106. package/cpp/dawn/platform/dawn_platform_export.h +0 -49
  107. package/cpp/platform/ThreadUtils.h +0 -30
  108. package/cpp/rnwgpu/api/AsyncRunner.h +0 -30
  109. package/cpp/threading/CallInvokerDispatcher.h +0 -37
  110. package/cpp/threading/Dispatcher.cpp +0 -55
  111. package/cpp/threading/Dispatcher.h +0 -93
  112. package/cpp/threading/ThreadPool.cpp +0 -88
  113. package/cpp/threading/ThreadPool.h +0 -53
  114. package/cpp/webgpu/webgpu_glfw.h +0 -88
  115. package/lib/typescript/src/__tests__/Alpha.spec.d.ts +0 -2
  116. package/lib/typescript/src/__tests__/Alpha.spec.d.ts.map +0 -1
  117. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +0 -2
  118. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +0 -1
  119. package/lib/typescript/src/__tests__/Buffer.spec.d.ts +0 -2
  120. package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +0 -1
  121. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +0 -2
  122. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +0 -1
  123. package/lib/typescript/src/__tests__/Constants.spec.d.ts +0 -2
  124. package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +0 -1
  125. package/lib/typescript/src/__tests__/Device.spec.d.ts +0 -2
  126. package/lib/typescript/src/__tests__/Device.spec.d.ts.map +0 -1
  127. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts +0 -2
  128. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts.map +0 -1
  129. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +0 -2
  130. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +0 -1
  131. package/lib/typescript/src/__tests__/GPU.spec.d.ts +0 -2
  132. package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +0 -1
  133. package/lib/typescript/src/__tests__/ImageData.spec.d.ts +0 -2
  134. package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +0 -1
  135. package/lib/typescript/src/__tests__/Shaders.spec.d.ts +0 -2
  136. package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +0 -1
  137. package/lib/typescript/src/__tests__/Texture.spec.d.ts +0 -2
  138. package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +0 -1
  139. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +0 -3
  140. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +0 -1
  141. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +0 -29
  142. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +0 -1
  143. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +0 -5
  144. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +0 -1
  145. package/lib/typescript/src/__tests__/components/cube.d.ts +0 -7
  146. package/lib/typescript/src/__tests__/components/cube.d.ts.map +0 -1
  147. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +0 -22
  148. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +0 -1
  149. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +0 -12
  150. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +0 -1
  151. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +0 -7
  152. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +0 -1
  153. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +0 -6
  154. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +0 -1
  155. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +0 -6
  156. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +0 -1
  157. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +0 -10
  158. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +0 -1
  159. package/lib/typescript/src/__tests__/components/triangle.d.ts +0 -3
  160. package/lib/typescript/src/__tests__/components/triangle.d.ts.map +0 -1
  161. package/lib/typescript/src/__tests__/config.d.ts +0 -3
  162. package/lib/typescript/src/__tests__/config.d.ts.map +0 -1
  163. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +0 -2
  164. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +0 -1
  165. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +0 -2
  166. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +0 -1
  167. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +0 -2
  168. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +0 -1
  169. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +0 -2
  170. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +0 -1
  171. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +0 -2
  172. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +0 -1
  173. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +0 -2
  174. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +0 -1
  175. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +0 -2
  176. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +0 -1
  177. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +0 -2
  178. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +0 -1
  179. package/lib/typescript/src/__tests__/globalSetup.d.ts +0 -3
  180. package/lib/typescript/src/__tests__/globalSetup.d.ts.map +0 -1
  181. package/lib/typescript/src/__tests__/globalTeardown.d.ts +0 -3
  182. package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +0 -1
  183. package/lib/typescript/src/__tests__/setup.d.ts +0 -63
  184. package/lib/typescript/src/__tests__/setup.d.ts.map +0 -1
  185. package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
  186. package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  187. package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
  188. package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  189. package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
  190. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
  191. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
  192. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  193. package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  194. package/libs/dawn.json +0 -4670
  195. package/src/__tests__/Alpha.spec.ts +0 -28
  196. package/src/__tests__/ArrayBuffer.spec.ts +0 -76
  197. package/src/__tests__/Buffer.spec.ts +0 -357
  198. package/src/__tests__/ComputeShader.spec.ts +0 -375
  199. package/src/__tests__/Constants.spec.ts +0 -89
  200. package/src/__tests__/Device.spec.ts +0 -84
  201. package/src/__tests__/ErrorScope.spec.ts +0 -92
  202. package/src/__tests__/ExternalTexture.spec.ts +0 -284
  203. package/src/__tests__/GPU.spec.ts +0 -272
  204. package/src/__tests__/ImageData.spec.ts +0 -26
  205. package/src/__tests__/Shaders.spec.ts +0 -232
  206. package/src/__tests__/Texture.spec.ts +0 -197
  207. package/src/__tests__/assets/Di-3d.png +0 -0
  208. package/src/__tests__/components/Wireframe/Shaders.ts +0 -138
  209. package/src/__tests__/components/Wireframe/models.ts +0 -113
  210. package/src/__tests__/components/Wireframe/utils.ts +0 -22
  211. package/src/__tests__/components/cube.ts +0 -51
  212. package/src/__tests__/components/meshes/mesh.ts +0 -96
  213. package/src/__tests__/components/meshes/sphere.ts +0 -103
  214. package/src/__tests__/components/meshes/stanfordDragon.ts +0 -44
  215. package/src/__tests__/components/meshes/stanfordDragonData.ts +0 -5
  216. package/src/__tests__/components/meshes/teapot.ts +0 -13
  217. package/src/__tests__/components/meshes/utils.ts +0 -235
  218. package/src/__tests__/components/triangle.ts +0 -17
  219. package/src/__tests__/config.ts +0 -2
  220. package/src/__tests__/demos/ABuffer.spec.ts +0 -890
  221. package/src/__tests__/demos/Blur.spec.ts +0 -398
  222. package/src/__tests__/demos/Cube.spec.ts +0 -929
  223. package/src/__tests__/demos/FractalCube.spec.ts +0 -240
  224. package/src/__tests__/demos/OcclusionQuery.spec.ts +0 -376
  225. package/src/__tests__/demos/RenderBundles.spec.ts +0 -580
  226. package/src/__tests__/demos/Triangle.spec.ts +0 -266
  227. package/src/__tests__/demos/Wireframe.spec.ts +0 -188
  228. package/src/__tests__/globalSetup.ts +0 -45
  229. package/src/__tests__/globalTeardown.ts +0 -11
  230. package/src/__tests__/setup.ts +0 -423
  231. package/src/__tests__/snapshots/abuffer.png +0 -0
  232. package/src/__tests__/snapshots/asteroid.png +0 -0
  233. package/src/__tests__/snapshots/blur.png +0 -0
  234. package/src/__tests__/snapshots/buffer.png +0 -0
  235. package/src/__tests__/snapshots/constant-triangle.png +0 -0
  236. package/src/__tests__/snapshots/cube.png +0 -0
  237. package/src/__tests__/snapshots/f.png +0 -0
  238. package/src/__tests__/snapshots/f2.png +0 -0
  239. package/src/__tests__/snapshots/fractal-cubes.png +0 -0
  240. package/src/__tests__/snapshots/instanced-cubes.png +0 -0
  241. package/src/__tests__/snapshots/occlusion-query.png +0 -0
  242. package/src/__tests__/snapshots/ref.png +0 -0
  243. package/src/__tests__/snapshots/semi-opaque-cyan.png +0 -0
  244. package/src/__tests__/snapshots/texture.png +0 -0
  245. package/src/__tests__/snapshots/textured-cube.png +0 -0
  246. package/src/__tests__/snapshots/triangle-msaa.png +0 -0
  247. package/src/__tests__/snapshots/triangle.png +0 -0
  248. package/src/__tests__/snapshots/two-cube.png +0 -0
@@ -24,11 +24,10 @@
24
24
  #include "RNFPromise.h"
25
25
  #include "RNFWorkletRuntimeRegistry.h"
26
26
 
27
- #include "Dispatcher.h"
28
- #include "ThreadPool.h"
29
-
30
27
  #include "Unions.h"
31
28
 
29
+ #include "rnwgpu/async/AsyncTaskHandle.h"
30
+
32
31
  // This number is the maximum integer that can be represented exactly as a double
33
32
  #define MAX_SAFE_INTEGER static_cast<uint64_t>(9007199254740991)
34
33
 
@@ -207,62 +206,21 @@ template <typename TEnum> struct JSIConverter<TEnum, std::enable_if_t<std::is_en
207
206
  }
208
207
  };
209
208
 
210
- // std::future<T> <> Promise<T>
211
- template <typename TResult> struct JSIConverter<std::future<TResult>> {
212
- static std::future<TResult> fromJSI(jsi::Runtime&, const jsi::Value&, bool outOfBound) {
213
- throw std::runtime_error("Promise cannot be converted to a native type - it needs to be awaited first!");
214
- }
215
- static jsi::Value toJSI(jsi::Runtime& runtime, std::future<TResult>&& arg) {
216
- auto sharedFuture = std::make_shared<std::future<TResult>>(std::move(arg));
217
- std::shared_ptr<Dispatcher> strongDispatcher = Dispatcher::getRuntimeGlobalDispatcher(runtime);
218
- std::weak_ptr<Dispatcher> weakDispatcher = strongDispatcher;
219
-
220
- return Promise::createPromise(runtime, [sharedFuture = std::move(sharedFuture), weakDispatcher](jsi::Runtime& runtime,
221
- std::shared_ptr<Promise> promise) {
222
- // Spawn new async thread to synchronously wait for the `future<T>` to complete
223
- std::shared_ptr<ThreadPool> pool = ThreadPool::getSharedPool();
224
- pool->run([promise, &runtime, weakDispatcher, sharedFuture]() {
225
- // synchronously wait until the `future<T>` completes. we are running on a background task here.
226
- sharedFuture->wait();
227
-
228
- std::shared_ptr<Dispatcher> dispatcher = weakDispatcher.lock();
229
- if (!dispatcher) {
230
- throw std::runtime_error("Tried resolving Promise on JS Thread, but the `Dispatcher` has already been destroyed!");
231
- return;
232
- }
233
-
234
- dispatcher->runAsync([&runtime, promise, sharedFuture]() mutable {
235
- try {
236
- if constexpr (std::is_same_v<TResult, void>) {
237
- // it's returning void, just return undefined to JS
238
- sharedFuture->get();
239
- promise->resolve(jsi::Value::undefined());
240
- } else {
241
- // it's returning a custom type, convert it to a jsi::Value
242
- TResult result = sharedFuture->get();
243
- jsi::Value jsResult = JSIConverter<TResult>::toJSI(runtime, result);
244
- promise->resolve(std::move(jsResult));
245
- }
246
- } catch (const std::exception& exception) {
247
- // the async function threw an error, reject the promise
248
- std::string what = exception.what();
249
- promise->reject(what);
250
- } catch (...) {
251
- // the async function threw a non-std error, try getting it
252
- #if __has_include(<cxxabi.h>)
253
- std::string name = __cxxabiv1::__cxa_current_exception_type()->name();
254
- #else
255
- std::string name = "<unknown>";
256
- #endif
257
- promise->reject("Unknown non-std exception: " + name);
258
- }
259
-
260
- // This lambda owns the promise shared pointer, and we need to call its
261
- // destructor correctly here - otherwise it might be called
262
- // from the threadPool thread.
263
- promise = nullptr;
264
- });
265
- });
209
+ // AsyncTaskHandle <> Promise
210
+ template <> struct JSIConverter<rnwgpu::async::AsyncTaskHandle> {
211
+ static rnwgpu::async::AsyncTaskHandle fromJSI(jsi::Runtime&, const jsi::Value&, bool) {
212
+ throw std::runtime_error("Cannot convert a Promise to AsyncTaskHandle on the native side.");
213
+ }
214
+
215
+ static jsi::Value toJSI(jsi::Runtime& runtime, rnwgpu::async::AsyncTaskHandle&& handle) {
216
+ return Promise::createPromise(runtime, [handle = std::move(handle)](jsi::Runtime& runtime,
217
+ std::shared_ptr<Promise> promise) mutable {
218
+ if (!handle.valid()) {
219
+ promise->resolve(jsi::Value::undefined());
220
+ return;
221
+ }
222
+
223
+ handle.attachPromise(promise);
266
224
  });
267
225
  }
268
226
  };
@@ -1,7 +1,5 @@
1
1
  #include "RNWebGPUManager.h"
2
2
 
3
- #include "CallInvokerDispatcher.h"
4
- #include "Dispatcher.h"
5
3
  #include "GPU.h"
6
4
  #include "RNWebGPU.h"
7
5
 
@@ -24,13 +22,7 @@ RNWebGPUManager::RNWebGPUManager(
24
22
  : _jsRuntime(jsRuntime), _jsCallInvoker(jsCallInvoker),
25
23
  _platformContext(platformContext) {
26
24
 
27
- // Installs the global Dispatcher mechanism into this Runtime.
28
- // This allows creating Promises and calling back to JS.
29
- auto dispatcher =
30
- std::make_shared<margelo::CallInvokerDispatcher>(_jsCallInvoker);
31
- margelo::Dispatcher::installRuntimeGlobalDispatcher(*_jsRuntime, dispatcher);
32
-
33
- auto gpu = std::make_shared<GPU>();
25
+ auto gpu = std::make_shared<GPU>(*_jsRuntime);
34
26
  auto rnWebGPU = std::make_shared<RNWebGPU>(gpu, _platformContext);
35
27
  _gpu = gpu->get();
36
28
  _jsRuntime->global().setProperty(
@@ -8,16 +8,26 @@
8
8
  #include <vector>
9
9
 
10
10
  #include "Convertors.h"
11
+ #include "RNFJSIConverter.h"
12
+ #include "rnwgpu/async/JSIMicrotaskDispatcher.h"
11
13
 
12
14
  namespace rnwgpu {
13
15
 
14
- std::future<std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>>>
15
- GPU::requestAdapter(
16
- std::optional<std::shared_ptr<GPURequestAdapterOptions>> options) {
17
- std::promise<std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>>>
18
- promise;
19
- auto future = promise.get_future();
16
+ GPU::GPU(jsi::Runtime &runtime) : HybridObject("GPU") {
17
+ static const auto kTimedWaitAny = wgpu::InstanceFeatureName::TimedWaitAny;
18
+ wgpu::InstanceDescriptor instanceDesc{.requiredFeatureCount = 1,
19
+ .requiredFeatures = &kTimedWaitAny};
20
+
21
+ wgpu::InstanceLimits limits{.timedWaitAnyMaxCount = 64};
22
+ instanceDesc.requiredLimits = &limits;
23
+ _instance = wgpu::CreateInstance(&instanceDesc);
24
+
25
+ auto dispatcher = std::make_shared<async::JSIMicrotaskDispatcher>(runtime);
26
+ _async = async::AsyncRunner::getOrCreate(runtime, _instance, dispatcher);
27
+ }
20
28
 
29
+ async::AsyncTaskHandle GPU::requestAdapter(
30
+ std::optional<std::shared_ptr<GPURequestAdapterOptions>> options) {
21
31
  wgpu::RequestAdapterOptions aOptions;
22
32
  Convertor conv;
23
33
  if (!conv(aOptions, options)) {
@@ -29,26 +39,41 @@ GPU::requestAdapter(
29
39
  constexpr auto kDefaultBackendType = wgpu::BackendType::Vulkan;
30
40
  #endif
31
41
  aOptions.backendType = kDefaultBackendType;
32
- wgpu::Adapter adapter = nullptr;
33
- _instance.RequestAdapter(
34
- &aOptions, wgpu::CallbackMode::AllowSpontaneous,
35
- [](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter,
36
- wgpu::StringView message, wgpu::Adapter *userdata) {
37
- if (message.length) {
38
- fprintf(stderr, "%s", message.data);
39
- return;
40
- }
41
- if (status == wgpu::RequestAdapterStatus::Success) {
42
- *userdata = std::move(adapter);
43
- }
44
- },
45
- &adapter);
46
- if (!adapter) {
47
- promise.set_value(nullptr);
48
- } else {
49
- promise.set_value(std::make_shared<GPUAdapter>(std::move(adapter), _async));
50
- }
51
- return future;
42
+ return _async->postTask(
43
+ [this, aOptions](const async::AsyncTaskHandle::ResolveFunction &resolve,
44
+ const async::AsyncTaskHandle::RejectFunction &reject) {
45
+ _instance.RequestAdapter(
46
+ &aOptions, wgpu::CallbackMode::AllowProcessEvents,
47
+ [asyncRunner = _async, resolve,
48
+ reject](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter,
49
+ wgpu::StringView message) {
50
+ if (message.length) {
51
+ fprintf(stderr, "%s", message.data);
52
+ }
53
+
54
+ if (status == wgpu::RequestAdapterStatus::Success && adapter) {
55
+ auto adapterHost = std::make_shared<GPUAdapter>(
56
+ std::move(adapter), asyncRunner);
57
+ auto result =
58
+ std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>>(
59
+ adapterHost);
60
+ resolve([result =
61
+ std::move(result)](jsi::Runtime &runtime) mutable {
62
+ return margelo::JSIConverter<decltype(result)>::toJSI(runtime,
63
+ result);
64
+ });
65
+ } else {
66
+ auto result =
67
+ std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>>(
68
+ nullptr);
69
+ resolve([result =
70
+ std::move(result)](jsi::Runtime &runtime) mutable {
71
+ return margelo::JSIConverter<decltype(result)>::toJSI(runtime,
72
+ result);
73
+ });
74
+ }
75
+ });
76
+ });
52
77
  }
53
78
 
54
79
  std::unordered_set<std::string> GPU::getWgslLanguageFeatures() {
@@ -1,6 +1,5 @@
1
1
  #pragma once
2
2
 
3
- #include <future>
4
3
  #include <memory>
5
4
  #include <string>
6
5
  #include <unordered_set>
@@ -10,9 +9,9 @@
10
9
 
11
10
  #include "RNFHybridObject.h"
12
11
 
13
- #include "AsyncRunner.h"
12
+ #include "rnwgpu/async/AsyncRunner.h"
13
+ #include "rnwgpu/async/AsyncTaskHandle.h"
14
14
 
15
- #include "dawn/dawn_proc.h"
16
15
  #include "dawn/native/DawnNative.h"
17
16
  #include "webgpu/webgpu_cpp.h"
18
17
 
@@ -27,24 +26,12 @@ namespace m = margelo;
27
26
 
28
27
  class GPU : public m::HybridObject {
29
28
  public:
30
- GPU() : HybridObject("GPU") {
31
- static const auto kTimedWaitAny = wgpu::InstanceFeatureName::TimedWaitAny;
32
- wgpu::InstanceDescriptor instanceDesc{.requiredFeatureCount = 1,
33
- .requiredFeatures = &kTimedWaitAny};
34
-
35
- // For limits:
36
- wgpu::InstanceLimits limits{.timedWaitAnyMaxCount = 64};
37
- instanceDesc.requiredLimits = &limits;
38
- _instance = wgpu::CreateInstance(&instanceDesc);
39
- auto instance = &_instance;
40
- _async = std::make_shared<AsyncRunner>(instance);
41
- }
29
+ explicit GPU(jsi::Runtime &runtime);
42
30
 
43
31
  public:
44
32
  std::string getBrand() { return _name; }
45
33
 
46
- std::future<std::variant<std::nullptr_t, std::shared_ptr<GPUAdapter>>>
47
- requestAdapter(
34
+ async::AsyncTaskHandle requestAdapter(
48
35
  std::optional<std::shared_ptr<GPURequestAdapterOptions>> options);
49
36
  wgpu::TextureFormat getPreferredCanvasFormat();
50
37
 
@@ -63,7 +50,7 @@ public:
63
50
 
64
51
  private:
65
52
  wgpu::Instance _instance;
66
- std::shared_ptr<AsyncRunner> _async;
53
+ std::shared_ptr<async::AsyncRunner> _async;
67
54
  };
68
55
 
69
56
  } // namespace rnwgpu
@@ -10,25 +10,25 @@
10
10
  #include "Convertors.h"
11
11
 
12
12
  #include "GPUFeatures.h"
13
+ #include "RNFJSIConverter.h"
13
14
  #include "WGPULogger.h"
14
15
 
15
16
  namespace rnwgpu {
16
17
 
17
- std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
18
+ async::AsyncTaskHandle GPUAdapter::requestDevice(
18
19
  std::optional<std::shared_ptr<GPUDeviceDescriptor>> descriptor) {
19
- std::promise<std::shared_ptr<GPUDevice>> promise;
20
- auto future = promise.get_future();
21
- wgpu::Device device = nullptr;
22
20
  wgpu::DeviceDescriptor aDescriptor;
23
21
  Convertor conv;
24
22
  if (!conv(aDescriptor, descriptor)) {
25
23
  throw std::runtime_error("Failed to convert GPUDeviceDescriptor");
26
24
  }
25
+ auto deviceLostBinding = std::make_shared<std::weak_ptr<GPUDevice>>();
27
26
  // Set device lost callback using new template API
28
27
  aDescriptor.SetDeviceLostCallback(
29
28
  wgpu::CallbackMode::AllowSpontaneous,
30
- [](const wgpu::Device &device, wgpu::DeviceLostReason reason,
31
- wgpu::StringView message) {
29
+ [deviceLostBinding](const wgpu::Device & /*device*/,
30
+ wgpu::DeviceLostReason reason,
31
+ wgpu::StringView message) {
32
32
  const char *lostReason = "";
33
33
  switch (reason) {
34
34
  case wgpu::DeviceLostReason::Destroyed:
@@ -40,8 +40,13 @@ std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
40
40
  default:
41
41
  lostReason = "Unknown";
42
42
  }
43
+ std::string msg =
44
+ message.length ? std::string(message.data, message.length) : "";
43
45
  Logger::logToConsole("GPU Device Lost (%s): %s", lostReason,
44
- message.data);
46
+ msg.c_str());
47
+ if (auto deviceHost = deviceLostBinding->lock()) {
48
+ deviceHost->notifyDeviceLost(reason, std::move(msg));
49
+ }
45
50
  });
46
51
 
47
52
  // Set uncaptured error callback using new template API
@@ -71,55 +76,71 @@ std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
71
76
  : "no message";
72
77
  fprintf(stderr, "%s", fullMessage.c_str());
73
78
  });
74
- _instance.RequestDevice(
75
- &aDescriptor, wgpu::CallbackMode::AllowSpontaneous,
76
- [](wgpu::RequestDeviceStatus status, wgpu::Device device,
77
- wgpu::StringView message, wgpu::Device *userdata) {
78
- if (message.length) {
79
- fprintf(stderr, "%s", message.data);
80
- return;
81
- }
82
- if (status == wgpu::RequestDeviceStatus::Success) {
83
- *userdata = std::move(device);
84
- }
85
- },
86
- &device);
87
-
88
- if (!device) {
89
- throw std::runtime_error("Failed to request device");
90
- }
91
- device.SetLoggingCallback(
92
- [creationRuntime = _creationRuntime](wgpu::LoggingType type,
93
- wgpu::StringView message) {
94
- const char *logLevel = "";
95
- switch (type) {
96
- case wgpu::LoggingType::Warning:
97
- logLevel = "Warning";
98
- Logger::warnToJavascriptConsole(
99
- *creationRuntime, std::string(message.data, message.length));
100
- break;
101
- case wgpu::LoggingType::Error:
102
- logLevel = "Error";
103
- Logger::errorToJavascriptConsole(
104
- *creationRuntime, std::string(message.data, message.length));
105
- break;
106
- case wgpu::LoggingType::Verbose:
107
- logLevel = "Verbose";
108
- break;
109
- case wgpu::LoggingType::Info:
110
- logLevel = "Info";
111
- break;
112
- default:
113
- logLevel = "Unknown";
114
- Logger::logToConsole("%s: %.*s", logLevel,
115
- static_cast<int>(message.length), message.data);
116
- }
117
- });
118
79
  std::string label =
119
80
  descriptor.has_value() ? descriptor.value()->label.value_or("") : "";
120
- promise.set_value(
121
- std::make_shared<GPUDevice>(std::move(device), _async, label));
122
- return future;
81
+
82
+ return _async->postTask(
83
+ [this, aDescriptor, descriptor, label = std::move(label),
84
+ deviceLostBinding](
85
+ const async::AsyncTaskHandle::ResolveFunction &resolve,
86
+ const async::AsyncTaskHandle::RejectFunction &reject) {
87
+ (void)descriptor;
88
+ _instance.RequestDevice(
89
+ &aDescriptor, wgpu::CallbackMode::AllowProcessEvents,
90
+ [asyncRunner = _async, resolve, reject, label,
91
+ creationRuntime = _creationRuntime, deviceLostBinding](
92
+ wgpu::RequestDeviceStatus status, wgpu::Device device,
93
+ wgpu::StringView message) mutable {
94
+ if (message.length) {
95
+ fprintf(stderr, "%s", message.data);
96
+ }
97
+
98
+ if (status != wgpu::RequestDeviceStatus::Success || !device) {
99
+ std::string error =
100
+ message.length ? std::string(message.data, message.length)
101
+ : "Failed to request device";
102
+ reject(std::move(error));
103
+ return;
104
+ }
105
+
106
+ device.SetLoggingCallback([creationRuntime](
107
+ wgpu::LoggingType type,
108
+ wgpu::StringView msg) {
109
+ const char *logLevel = "";
110
+ switch (type) {
111
+ case wgpu::LoggingType::Warning:
112
+ logLevel = "Warning";
113
+ Logger::warnToJavascriptConsole(
114
+ *creationRuntime, std::string(msg.data, msg.length));
115
+ break;
116
+ case wgpu::LoggingType::Error:
117
+ logLevel = "Error";
118
+ Logger::errorToJavascriptConsole(
119
+ *creationRuntime, std::string(msg.data, msg.length));
120
+ break;
121
+ case wgpu::LoggingType::Verbose:
122
+ logLevel = "Verbose";
123
+ break;
124
+ case wgpu::LoggingType::Info:
125
+ logLevel = "Info";
126
+ break;
127
+ default:
128
+ logLevel = "Unknown";
129
+ Logger::logToConsole("%s: %.*s", logLevel,
130
+ static_cast<int>(msg.length), msg.data);
131
+ }
132
+ });
133
+
134
+ auto deviceHost = std::make_shared<GPUDevice>(std::move(device),
135
+ asyncRunner, label);
136
+ *deviceLostBinding = deviceHost;
137
+ resolve([deviceHost = std::move(deviceHost)](
138
+ jsi::Runtime &runtime) mutable {
139
+ return margelo::JSIConverter<std::shared_ptr<GPUDevice>>::toJSI(
140
+ runtime, deviceHost);
141
+ });
142
+ });
143
+ });
123
144
  }
124
145
 
125
146
  std::unordered_set<std::string> GPUAdapter::getFeatures() {
@@ -1,6 +1,5 @@
1
1
  #pragma once
2
2
 
3
- #include <future>
4
3
  #include <memory>
5
4
  #include <string>
6
5
  #include <unordered_set>
@@ -9,7 +8,8 @@
9
8
 
10
9
  #include "RNFHybridObject.h"
11
10
 
12
- #include "AsyncRunner.h"
11
+ #include "rnwgpu/async/AsyncRunner.h"
12
+ #include "rnwgpu/async/AsyncTaskHandle.h"
13
13
 
14
14
  #include "webgpu/webgpu_cpp.h"
15
15
 
@@ -25,13 +25,13 @@ namespace m = margelo;
25
25
  class GPUAdapter : public m::HybridObject {
26
26
  public:
27
27
  explicit GPUAdapter(wgpu::Adapter instance,
28
- std::shared_ptr<AsyncRunner> async)
28
+ std::shared_ptr<async::AsyncRunner> async)
29
29
  : HybridObject("GPUAdapter"), _instance(instance), _async(async) {}
30
30
 
31
31
  public:
32
32
  std::string getBrand() { return _name; }
33
33
 
34
- std::future<std::shared_ptr<GPUDevice>>
34
+ async::AsyncTaskHandle
35
35
  requestDevice(std::optional<std::shared_ptr<GPUDeviceDescriptor>> descriptor);
36
36
 
37
37
  std::unordered_set<std::string> getFeatures();
@@ -50,7 +50,7 @@ public:
50
50
 
51
51
  private:
52
52
  wgpu::Adapter _instance;
53
- std::shared_ptr<AsyncRunner> _async;
53
+ std::shared_ptr<async::AsyncRunner> _async;
54
54
  };
55
55
 
56
- } // namespace rnwgpu
56
+ } // namespace rnwgpu
@@ -7,7 +7,6 @@
7
7
 
8
8
  #include "RNFHybridObject.h"
9
9
 
10
- #include "AsyncRunner.h"
11
10
  #include "Convertors.h"
12
11
 
13
12
  #include "webgpu/webgpu_cpp.h"
@@ -6,8 +6,6 @@
6
6
 
7
7
  #include "RNFHybridObject.h"
8
8
 
9
- #include "AsyncRunner.h"
10
-
11
9
  #include "webgpu/webgpu_cpp.h"
12
10
 
13
11
  namespace rnwgpu {
@@ -49,4 +47,4 @@ private:
49
47
  std::string _label;
50
48
  };
51
49
 
52
- } // namespace rnwgpu
50
+ } // namespace rnwgpu
@@ -6,8 +6,6 @@
6
6
 
7
7
  #include "RNFHybridObject.h"
8
8
 
9
- #include "AsyncRunner.h"
10
-
11
9
  #include "webgpu/webgpu_cpp.h"
12
10
 
13
11
  namespace rnwgpu {
@@ -50,4 +48,4 @@ private:
50
48
  std::string _label;
51
49
  };
52
50
 
53
- } // namespace rnwgpu
51
+ } // namespace rnwgpu
@@ -37,9 +37,9 @@ GPUBuffer::getMappedRange(std::optional<size_t> o, std::optional<size_t> size) {
37
37
 
38
38
  void GPUBuffer::destroy() { _instance.Destroy(); }
39
39
 
40
- std::future<void> GPUBuffer::mapAsync(uint64_t modeIn,
41
- std::optional<uint64_t> offset,
42
- std::optional<uint64_t> size) {
40
+ async::AsyncTaskHandle GPUBuffer::mapAsync(uint64_t modeIn,
41
+ std::optional<uint64_t> offset,
42
+ std::optional<uint64_t> size) {
43
43
  Convertor conv;
44
44
  wgpu::MapMode mode;
45
45
  if (!conv(mode, modeIn)) {
@@ -48,35 +48,38 @@ std::future<void> GPUBuffer::mapAsync(uint64_t modeIn,
48
48
  uint64_t rangeSize = size.has_value()
49
49
  ? size.value()
50
50
  : (_instance.GetSize() - offset.value_or(0));
51
- return _async->runAsync([=] {
52
- // for (auto& mapping : mappings) {
53
- // if (mapping.Intersects(start, end)) {
54
- // promise.set_exception(std::make_exception_ptr(std::runtime_error("Buffer
55
- // is already mapped"))); return future;
56
- // }
57
- // }
58
- return _instance.MapAsync(
59
- mode, offset.value_or(0), rangeSize, wgpu::CallbackMode::WaitAnyOnly,
60
- [](wgpu::MapAsyncStatus status, wgpu::StringView message) {
61
- switch (status) {
62
- case wgpu::MapAsyncStatus::Success:
63
- break;
64
- case wgpu::MapAsyncStatus::CallbackCancelled:
65
- throw std::runtime_error("MapAsyncStatus::CallbackCancelled");
66
- break;
67
- case wgpu::MapAsyncStatus::Error:
68
- throw std::runtime_error("MapAsyncStatus::Error");
69
- break;
70
- case wgpu::MapAsyncStatus::Aborted:
71
- throw std::runtime_error("MapAsyncStatus::Aborted");
72
- break;
73
- default:
74
- throw std::runtime_error("MapAsyncStatus: " +
75
- std::to_string(static_cast<int>(status)));
76
- break;
77
- }
78
- });
79
- });
51
+ auto bufferHandle = _instance;
52
+ uint64_t resolvedOffset = offset.value_or(0);
53
+
54
+ return _async->postTask(
55
+ [bufferHandle, mode, resolvedOffset,
56
+ rangeSize](const async::AsyncTaskHandle::ResolveFunction &resolve,
57
+ const async::AsyncTaskHandle::RejectFunction &reject) {
58
+ bufferHandle.MapAsync(mode, resolvedOffset, rangeSize,
59
+ wgpu::CallbackMode::AllowProcessEvents,
60
+ [resolve, reject](wgpu::MapAsyncStatus status,
61
+ wgpu::StringView message) {
62
+ switch (status) {
63
+ case wgpu::MapAsyncStatus::Success:
64
+ resolve(nullptr);
65
+ break;
66
+ case wgpu::MapAsyncStatus::CallbackCancelled:
67
+ reject("MapAsyncStatus::CallbackCancelled");
68
+ break;
69
+ case wgpu::MapAsyncStatus::Error:
70
+ reject("MapAsyncStatus::Error");
71
+ break;
72
+ case wgpu::MapAsyncStatus::Aborted:
73
+ reject("MapAsyncStatus::Aborted");
74
+ break;
75
+ default:
76
+ reject(
77
+ "MapAsyncStatus: " +
78
+ std::to_string(static_cast<int>(status)));
79
+ break;
80
+ }
81
+ });
82
+ });
80
83
  }
81
84
 
82
85
  void GPUBuffer::unmap() { _instance.Unmap(); }
@@ -1,6 +1,5 @@
1
1
  #pragma once
2
2
 
3
- #include <future>
4
3
  #include <memory>
5
4
  #include <optional>
6
5
  #include <string>
@@ -10,7 +9,8 @@
10
9
 
11
10
  #include "RNFHybridObject.h"
12
11
 
13
- #include "AsyncRunner.h"
12
+ #include "rnwgpu/async/AsyncRunner.h"
13
+ #include "rnwgpu/async/AsyncTaskHandle.h"
14
14
 
15
15
  #include "webgpu/webgpu_cpp.h"
16
16
 
@@ -22,7 +22,8 @@ namespace m = margelo;
22
22
 
23
23
  class GPUBuffer : public m::HybridObject {
24
24
  public:
25
- explicit GPUBuffer(wgpu::Buffer instance, std::shared_ptr<AsyncRunner> async,
25
+ explicit GPUBuffer(wgpu::Buffer instance,
26
+ std::shared_ptr<async::AsyncRunner> async,
26
27
  std::string label)
27
28
  : HybridObject("GPUBuffer"), _instance(instance), _async(async),
28
29
  _label(label) {}
@@ -30,8 +31,9 @@ public:
30
31
  public:
31
32
  std::string getBrand() { return _name; }
32
33
 
33
- std::future<void> mapAsync(uint64_t modeIn, std::optional<uint64_t> offset,
34
- std::optional<uint64_t> size);
34
+ async::AsyncTaskHandle mapAsync(uint64_t modeIn,
35
+ std::optional<uint64_t> offset,
36
+ std::optional<uint64_t> size);
35
37
  std::shared_ptr<ArrayBuffer> getMappedRange(std::optional<size_t> offset,
36
38
  std::optional<size_t> size);
37
39
  void unmap();
@@ -66,7 +68,7 @@ public:
66
68
 
67
69
  private:
68
70
  wgpu::Buffer _instance;
69
- std::shared_ptr<AsyncRunner> _async;
71
+ std::shared_ptr<async::AsyncRunner> _async;
70
72
  std::string _label;
71
73
  struct Mapping {
72
74
  uint64_t start;
@@ -79,4 +81,4 @@ private:
79
81
  std::vector<Mapping> mappings;
80
82
  };
81
83
 
82
- } // namespace rnwgpu
84
+ } // namespace rnwgpu
@@ -4,7 +4,11 @@
4
4
  #include <memory>
5
5
 
6
6
  #ifdef __APPLE__
7
- #include "dawn/native/MetalBackend.h"
7
+ namespace dawn::native::metal {
8
+
9
+ void WaitForCommandsToBeScheduled(WGPUDevice device);
10
+
11
+ }
8
12
  #endif
9
13
 
10
14
  namespace rnwgpu {