react-native-wgpu 0.2.10 → 0.3.1

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 (258) hide show
  1. package/README.md +155 -69
  2. package/android/CMakeLists.txt +5 -7
  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/RNFHybridObject.cpp +8 -4
  18. package/cpp/jsi/RNFHybridObject.h +7 -2
  19. package/cpp/jsi/RNFJSIConverter.h +13 -102
  20. package/cpp/jsi/RNFJSIHelper.h +5 -3
  21. package/cpp/jsi/RNFRuntimeState.cpp +18 -0
  22. package/cpp/jsi/RNFRuntimeState.h +106 -0
  23. package/cpp/rnwgpu/RNWebGPUManager.cpp +1 -9
  24. package/cpp/rnwgpu/api/GPU.cpp +51 -26
  25. package/cpp/rnwgpu/api/GPU.h +5 -18
  26. package/cpp/rnwgpu/api/GPUAdapter.cpp +79 -54
  27. package/cpp/rnwgpu/api/GPUAdapter.h +6 -6
  28. package/cpp/rnwgpu/api/GPUAdapterInfo.h +0 -1
  29. package/cpp/rnwgpu/api/GPUBindGroup.h +1 -3
  30. package/cpp/rnwgpu/api/GPUBindGroupLayout.h +1 -3
  31. package/cpp/rnwgpu/api/GPUBuffer.cpp +35 -32
  32. package/cpp/rnwgpu/api/GPUBuffer.h +9 -7
  33. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +5 -1
  34. package/cpp/rnwgpu/api/GPUCanvasContext.h +0 -2
  35. package/cpp/rnwgpu/api/GPUCommandBuffer.h +1 -3
  36. package/cpp/rnwgpu/api/GPUCommandEncoder.h +1 -3
  37. package/cpp/rnwgpu/api/GPUCompilationInfo.h +0 -2
  38. package/cpp/rnwgpu/api/GPUCompilationMessage.h +1 -3
  39. package/cpp/rnwgpu/api/GPUComputePassEncoder.h +1 -3
  40. package/cpp/rnwgpu/api/GPUComputePipeline.h +1 -3
  41. package/cpp/rnwgpu/api/GPUDevice.cpp +183 -128
  42. package/cpp/rnwgpu/api/GPUDevice.h +22 -21
  43. package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +1 -3
  44. package/cpp/rnwgpu/api/GPUExternalTexture.h +1 -3
  45. package/cpp/rnwgpu/api/GPUPipelineLayout.h +1 -3
  46. package/cpp/rnwgpu/api/GPUQuerySet.h +1 -3
  47. package/cpp/rnwgpu/api/GPUQueue.cpp +19 -8
  48. package/cpp/rnwgpu/api/GPUQueue.h +7 -6
  49. package/cpp/rnwgpu/api/GPURenderBundle.h +1 -3
  50. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -3
  51. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -3
  52. package/cpp/rnwgpu/api/GPURenderPipeline.h +1 -3
  53. package/cpp/rnwgpu/api/GPUSampler.h +1 -3
  54. package/cpp/rnwgpu/api/GPUShaderModule.cpp +42 -28
  55. package/cpp/rnwgpu/api/GPUShaderModule.h +6 -6
  56. package/cpp/rnwgpu/api/GPUSupportedLimits.h +1 -3
  57. package/cpp/rnwgpu/api/GPUTexture.h +1 -3
  58. package/cpp/rnwgpu/api/GPUTextureView.h +1 -3
  59. package/cpp/rnwgpu/api/RNWebGPU.h +1 -7
  60. package/cpp/rnwgpu/async/AsyncDispatcher.h +28 -0
  61. package/cpp/rnwgpu/async/AsyncRunner.cpp +215 -0
  62. package/cpp/rnwgpu/async/AsyncRunner.h +53 -0
  63. package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +181 -0
  64. package/cpp/rnwgpu/async/AsyncTaskHandle.h +55 -0
  65. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.cpp +23 -0
  66. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.h +22 -0
  67. package/cpp/webgpu/webgpu.h +5 -4827
  68. package/cpp/webgpu/webgpu_cpp.h +5 -10140
  69. package/cpp/{dawn/native/WebGPUBackend.h → webgpu/webgpu_cpp_print.h} +4 -20
  70. package/lib/commonjs/Canvas.js +6 -66
  71. package/lib/commonjs/Canvas.js.map +1 -1
  72. package/lib/commonjs/hooks.js +6 -42
  73. package/lib/commonjs/hooks.js.map +1 -1
  74. package/lib/module/Canvas.js +7 -67
  75. package/lib/module/Canvas.js.map +1 -1
  76. package/lib/module/hooks.js +5 -40
  77. package/lib/module/hooks.js.map +1 -1
  78. package/lib/typescript/lib/commonjs/hooks.d.ts +1 -5
  79. package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -1
  80. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  81. package/lib/typescript/lib/module/hooks.d.ts +1 -5
  82. package/lib/typescript/lib/module/hooks.d.ts.map +1 -1
  83. package/lib/typescript/src/Canvas.d.ts +0 -1
  84. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  85. package/lib/typescript/src/hooks.d.ts +2 -7
  86. package/lib/typescript/src/hooks.d.ts.map +1 -1
  87. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  88. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  89. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  90. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  91. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +5 -35
  92. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  93. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  94. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  95. package/package.json +4 -3
  96. package/react-native-wgpu.podspec +12 -16
  97. package/src/Canvas.tsx +8 -69
  98. package/src/hooks.tsx +14 -48
  99. package/android/cpp/platform/ThreadUtils.cpp +0 -41
  100. package/android/src/oldarch/com/webgpu/NativeWebGPUModuleSpec.java +0 -23
  101. package/android/src/oldarch/com/webgpu/WebGPUViewManagerSpec.java +0 -12
  102. package/apple/WebGPUViewManager.mm +0 -24
  103. package/apple/platform/ThreadUtils.cpp +0 -34
  104. package/cpp/dawn/dawn_proc.h +0 -50
  105. package/cpp/dawn/dawn_thread_dispatch_proc.h +0 -47
  106. package/cpp/dawn/native/D3D11Backend.h +0 -77
  107. package/cpp/dawn/native/D3D12Backend.h +0 -68
  108. package/cpp/dawn/native/D3DBackend.h +0 -56
  109. package/cpp/dawn/native/MetalBackend.h +0 -56
  110. package/cpp/dawn/platform/DawnPlatform.h +0 -167
  111. package/cpp/dawn/platform/dawn_platform_export.h +0 -49
  112. package/cpp/jsi/RNFRuntimeCache.cpp +0 -57
  113. package/cpp/jsi/RNFRuntimeCache.h +0 -79
  114. package/cpp/jsi/RNFWorkletRuntimeCollector.h +0 -43
  115. package/cpp/jsi/RNFWorkletRuntimeRegistry.cpp +0 -12
  116. package/cpp/jsi/RNFWorkletRuntimeRegistry.h +0 -44
  117. package/cpp/platform/ThreadUtils.h +0 -30
  118. package/cpp/rnwgpu/api/AsyncRunner.h +0 -30
  119. package/cpp/threading/CallInvokerDispatcher.h +0 -37
  120. package/cpp/threading/Dispatcher.cpp +0 -55
  121. package/cpp/threading/Dispatcher.h +0 -93
  122. package/cpp/threading/ThreadPool.cpp +0 -88
  123. package/cpp/threading/ThreadPool.h +0 -53
  124. package/cpp/webgpu/webgpu_glfw.h +0 -88
  125. package/lib/typescript/src/__tests__/Alpha.spec.d.ts +0 -2
  126. package/lib/typescript/src/__tests__/Alpha.spec.d.ts.map +0 -1
  127. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +0 -2
  128. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +0 -1
  129. package/lib/typescript/src/__tests__/Buffer.spec.d.ts +0 -2
  130. package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +0 -1
  131. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +0 -2
  132. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +0 -1
  133. package/lib/typescript/src/__tests__/Constants.spec.d.ts +0 -2
  134. package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +0 -1
  135. package/lib/typescript/src/__tests__/Device.spec.d.ts +0 -2
  136. package/lib/typescript/src/__tests__/Device.spec.d.ts.map +0 -1
  137. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts +0 -2
  138. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts.map +0 -1
  139. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +0 -2
  140. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +0 -1
  141. package/lib/typescript/src/__tests__/GPU.spec.d.ts +0 -2
  142. package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +0 -1
  143. package/lib/typescript/src/__tests__/ImageData.spec.d.ts +0 -2
  144. package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +0 -1
  145. package/lib/typescript/src/__tests__/Shaders.spec.d.ts +0 -2
  146. package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +0 -1
  147. package/lib/typescript/src/__tests__/Texture.spec.d.ts +0 -2
  148. package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +0 -1
  149. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +0 -3
  150. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +0 -1
  151. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +0 -29
  152. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +0 -1
  153. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +0 -5
  154. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +0 -1
  155. package/lib/typescript/src/__tests__/components/cube.d.ts +0 -7
  156. package/lib/typescript/src/__tests__/components/cube.d.ts.map +0 -1
  157. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +0 -22
  158. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +0 -1
  159. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +0 -12
  160. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +0 -1
  161. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +0 -7
  162. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +0 -1
  163. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +0 -6
  164. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +0 -1
  165. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +0 -6
  166. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +0 -1
  167. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +0 -10
  168. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +0 -1
  169. package/lib/typescript/src/__tests__/components/triangle.d.ts +0 -3
  170. package/lib/typescript/src/__tests__/components/triangle.d.ts.map +0 -1
  171. package/lib/typescript/src/__tests__/config.d.ts +0 -3
  172. package/lib/typescript/src/__tests__/config.d.ts.map +0 -1
  173. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +0 -2
  174. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +0 -1
  175. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +0 -2
  176. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +0 -1
  177. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +0 -2
  178. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +0 -1
  179. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +0 -2
  180. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +0 -1
  181. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +0 -2
  182. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +0 -1
  183. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +0 -2
  184. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +0 -1
  185. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +0 -2
  186. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +0 -1
  187. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +0 -2
  188. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +0 -1
  189. package/lib/typescript/src/__tests__/globalSetup.d.ts +0 -3
  190. package/lib/typescript/src/__tests__/globalSetup.d.ts.map +0 -1
  191. package/lib/typescript/src/__tests__/globalTeardown.d.ts +0 -3
  192. package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +0 -1
  193. package/lib/typescript/src/__tests__/setup.d.ts +0 -63
  194. package/lib/typescript/src/__tests__/setup.d.ts.map +0 -1
  195. package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
  196. package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  197. package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
  198. package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  199. package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
  200. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
  201. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
  202. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  203. package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  204. package/libs/dawn.json +0 -4670
  205. package/src/__tests__/Alpha.spec.ts +0 -28
  206. package/src/__tests__/ArrayBuffer.spec.ts +0 -76
  207. package/src/__tests__/Buffer.spec.ts +0 -357
  208. package/src/__tests__/ComputeShader.spec.ts +0 -375
  209. package/src/__tests__/Constants.spec.ts +0 -89
  210. package/src/__tests__/Device.spec.ts +0 -84
  211. package/src/__tests__/ErrorScope.spec.ts +0 -92
  212. package/src/__tests__/ExternalTexture.spec.ts +0 -284
  213. package/src/__tests__/GPU.spec.ts +0 -272
  214. package/src/__tests__/ImageData.spec.ts +0 -26
  215. package/src/__tests__/Shaders.spec.ts +0 -232
  216. package/src/__tests__/Texture.spec.ts +0 -197
  217. package/src/__tests__/assets/Di-3d.png +0 -0
  218. package/src/__tests__/components/Wireframe/Shaders.ts +0 -138
  219. package/src/__tests__/components/Wireframe/models.ts +0 -113
  220. package/src/__tests__/components/Wireframe/utils.ts +0 -22
  221. package/src/__tests__/components/cube.ts +0 -51
  222. package/src/__tests__/components/meshes/mesh.ts +0 -96
  223. package/src/__tests__/components/meshes/sphere.ts +0 -103
  224. package/src/__tests__/components/meshes/stanfordDragon.ts +0 -44
  225. package/src/__tests__/components/meshes/stanfordDragonData.ts +0 -5
  226. package/src/__tests__/components/meshes/teapot.ts +0 -13
  227. package/src/__tests__/components/meshes/utils.ts +0 -235
  228. package/src/__tests__/components/triangle.ts +0 -17
  229. package/src/__tests__/config.ts +0 -2
  230. package/src/__tests__/demos/ABuffer.spec.ts +0 -890
  231. package/src/__tests__/demos/Blur.spec.ts +0 -398
  232. package/src/__tests__/demos/Cube.spec.ts +0 -929
  233. package/src/__tests__/demos/FractalCube.spec.ts +0 -240
  234. package/src/__tests__/demos/OcclusionQuery.spec.ts +0 -376
  235. package/src/__tests__/demos/RenderBundles.spec.ts +0 -580
  236. package/src/__tests__/demos/Triangle.spec.ts +0 -266
  237. package/src/__tests__/demos/Wireframe.spec.ts +0 -188
  238. package/src/__tests__/globalSetup.ts +0 -45
  239. package/src/__tests__/globalTeardown.ts +0 -11
  240. package/src/__tests__/setup.ts +0 -423
  241. package/src/__tests__/snapshots/abuffer.png +0 -0
  242. package/src/__tests__/snapshots/asteroid.png +0 -0
  243. package/src/__tests__/snapshots/blur.png +0 -0
  244. package/src/__tests__/snapshots/buffer.png +0 -0
  245. package/src/__tests__/snapshots/constant-triangle.png +0 -0
  246. package/src/__tests__/snapshots/cube.png +0 -0
  247. package/src/__tests__/snapshots/f.png +0 -0
  248. package/src/__tests__/snapshots/f2.png +0 -0
  249. package/src/__tests__/snapshots/fractal-cubes.png +0 -0
  250. package/src/__tests__/snapshots/instanced-cubes.png +0 -0
  251. package/src/__tests__/snapshots/occlusion-query.png +0 -0
  252. package/src/__tests__/snapshots/ref.png +0 -0
  253. package/src/__tests__/snapshots/semi-opaque-cyan.png +0 -0
  254. package/src/__tests__/snapshots/texture.png +0 -0
  255. package/src/__tests__/snapshots/textured-cube.png +0 -0
  256. package/src/__tests__/snapshots/triangle-msaa.png +0 -0
  257. package/src/__tests__/snapshots/triangle.png +0 -0
  258. package/src/__tests__/snapshots/two-cube.png +0 -0
@@ -129,6 +129,7 @@ void HybridObject::ensureInitialized(facebook::jsi::Runtime& runtime) {
129
129
  if (!_didLoadMethods) {
130
130
  [[unlikely]];
131
131
  _creationRuntime = &runtime;
132
+ _runtimeState = rnwgpu::RNFRuntimeState::get(runtime);
132
133
  // lazy-load all exposed methods
133
134
  loadHybridMethods();
134
135
  _didLoadMethods = true;
@@ -136,11 +137,14 @@ void HybridObject::ensureInitialized(facebook::jsi::Runtime& runtime) {
136
137
  }
137
138
 
138
139
  bool HybridObject::isRuntimeAlive() {
139
- if (_creationRuntime == nullptr) {
140
- [[unlikely]];
141
- return false;
140
+ return !_runtimeState.expired();
141
+ }
142
+
143
+ facebook::jsi::Runtime* HybridObject::getCreationRuntime() const {
144
+ if (_runtimeState.expired()) {
145
+ return nullptr;
142
146
  }
143
- return RNFWorkletRuntimeRegistry::isRuntimeAlive(_creationRuntime);
147
+ return _creationRuntime;
144
148
  }
145
149
 
146
150
  } // namespace margelo
@@ -5,7 +5,7 @@
5
5
  #pragma once
6
6
 
7
7
  #include "WGPULogger.h"
8
- #include "RNFWorkletRuntimeRegistry.h"
8
+ #include "RNFRuntimeState.h"
9
9
  #include <functional>
10
10
  #include <jsi/jsi.h>
11
11
  #include <memory>
@@ -91,8 +91,9 @@ private:
91
91
 
92
92
  protected:
93
93
  const char* _name = TAG;
94
- // Store a pointer to the runtime. Needed for checking if the runtime is still active, see WorkletRuntimeRegistry.
94
+ // Store a pointer to the runtime for convenience; ensure it is only used while the runtime state is alive.
95
95
  jsi::Runtime* _creationRuntime = nullptr;
96
+ std::weak_ptr<rnwgpu::RNFRuntimeState> _runtimeState;
96
97
 
97
98
  private:
98
99
  inline void ensureInitialized(facebook::jsi::Runtime& runtime);
@@ -128,6 +129,10 @@ private:
128
129
  };
129
130
  }
130
131
 
132
+ protected:
133
+ facebook::jsi::Runtime* getCreationRuntime() const;
134
+ std::weak_ptr<rnwgpu::RNFRuntimeState> getRuntimeStateWeak() const { return _runtimeState; }
135
+
131
136
  protected:
132
137
  template <typename Derived, typename ReturnType, typename... Args>
133
138
  void registerHybridMethod(std::string name, ReturnType (Derived::*method)(Args...), Derived* derivedInstance, bool override = false) {
@@ -22,13 +22,11 @@
22
22
  #include "RNFEnumMapper.h"
23
23
  #include "RNFJSIHelper.h"
24
24
  #include "RNFPromise.h"
25
- #include "RNFWorkletRuntimeRegistry.h"
26
-
27
- #include "Dispatcher.h"
28
- #include "ThreadPool.h"
29
25
 
30
26
  #include "Unions.h"
31
27
 
28
+ #include "rnwgpu/async/AsyncTaskHandle.h"
29
+
32
30
  // This number is the maximum integer that can be represented exactly as a double
33
31
  #define MAX_SAFE_INTEGER static_cast<uint64_t>(9007199254740991)
34
32
 
@@ -207,109 +205,22 @@ template <typename TEnum> struct JSIConverter<TEnum, std::enable_if_t<std::is_en
207
205
  }
208
206
  };
209
207
 
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
- });
266
- });
208
+ // AsyncTaskHandle <> Promise
209
+ template <> struct JSIConverter<rnwgpu::async::AsyncTaskHandle> {
210
+ static rnwgpu::async::AsyncTaskHandle fromJSI(jsi::Runtime&, const jsi::Value&, bool) {
211
+ throw std::runtime_error("Cannot convert a Promise to AsyncTaskHandle on the native side.");
267
212
  }
268
- };
269
213
 
270
-
271
- // [](Args...) -> T {} <> (Args...) => T
272
- template <typename ReturnType, typename... Args> struct JSIConverter<std::function<ReturnType(Args...)>> {
273
- static std::function<ReturnType(Args...)> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg, bool outOfBound) {
274
- jsi::Function function = arg.asObject(runtime).asFunction(runtime);
275
-
276
- std::shared_ptr<jsi::Function> sharedFunction = JSIHelper::createSharedJsiFunction(runtime, std::move(function));
277
- return [&runtime, sharedFunction, outOfBound](Args... args) -> ReturnType {
278
- jsi::Value result = sharedFunction->call(runtime, JSIConverter<std::decay_t<Args>>::toJSI(runtime, args)...);
279
- if constexpr (std::is_same_v<ReturnType, void>) {
280
- // it is a void function (returns undefined)
214
+ static jsi::Value toJSI(jsi::Runtime& runtime, rnwgpu::async::AsyncTaskHandle&& handle) {
215
+ return Promise::createPromise(runtime, [handle = std::move(handle)](jsi::Runtime& runtime,
216
+ std::shared_ptr<Promise> promise) mutable {
217
+ if (!handle.valid()) {
218
+ promise->resolve(jsi::Value::undefined());
281
219
  return;
282
- } else {
283
- // it returns a custom type, parse it from the JSI value.
284
- return JSIConverter<ReturnType>::fromJSI(runtime, std::move(result), outOfBound);
285
220
  }
286
- };
287
- }
288
221
 
289
- template <size_t... Is>
290
- static jsi::Value callHybridFunction(const std::function<ReturnType(Args...)>& function, jsi::Runtime& runtime, const jsi::Value* args,
291
- std::index_sequence<Is...>, size_t count) {
292
- if constexpr (std::is_same_v<ReturnType, void>) {
293
- // it is a void function (will return undefined in JS)
294
- function(JSIConverter<std::decay_t<Args>>::fromJSI(runtime, args[Is], Is >= count)...);
295
- return jsi::Value::undefined();
296
- } else {
297
- // it is a custom type, parse it to a JS value
298
- ReturnType result = function(JSIConverter<std::decay_t<Args>>::fromJSI(runtime, args[Is], Is >= count)...);
299
- return JSIConverter<ReturnType>::toJSI(runtime, result);
300
- }
301
- }
302
- static jsi::Value toJSI(jsi::Runtime& runtime, const std::function<ReturnType(Args...)>& function) {
303
- jsi::HostFunctionType jsFunction = [function = std::move(function)](jsi::Runtime& runtime, const jsi::Value& thisValue,
304
- const jsi::Value* args, size_t count) -> jsi::Value {
305
- if (count != sizeof...(Args)) {
306
- [[unlikely]];
307
- throw jsi::JSError(runtime, "Function expected " + std::to_string(sizeof...(Args)) + " arguments, but received " +
308
- std::to_string(count) + "!");
309
- }
310
- return callHybridFunction(function, runtime, args, std::index_sequence_for<Args...>{}, count);
311
- };
312
- return jsi::Function::createFromHostFunction(runtime, jsi::PropNameID::forUtf8(runtime, "hostFunction"), sizeof...(Args), jsFunction);
222
+ handle.attachPromise(promise);
223
+ });
313
224
  }
314
225
  };
315
226
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  #pragma once
6
6
 
7
- #include "RNFWorkletRuntimeRegistry.h"
7
+ #include "RNFRuntimeState.h"
8
8
  #include <jsi/jsi.h>
9
9
  #include <memory>
10
10
  #include <utility>
@@ -20,8 +20,10 @@ public:
20
20
  * Every jsi::Function you intend to share or hold should be wrapped using this function.
21
21
  */
22
22
  static std::shared_ptr<jsi::Function> createSharedJsiFunction(jsi::Runtime& runtime, jsi::Function&& function) {
23
- std::shared_ptr<jsi::Function> sharedFunction(new jsi::Function(std::move(function)), [&runtime](jsi::Function* ptr) {
24
- if (RNFWorkletRuntimeRegistry::isRuntimeAlive(&runtime)) {
23
+ auto runtimeState = rnwgpu::RNFRuntimeState::get(runtime);
24
+ std::weak_ptr<rnwgpu::RNFRuntimeState> runtimeStateWeak = runtimeState;
25
+ std::shared_ptr<jsi::Function> sharedFunction(new jsi::Function(std::move(function)), [runtimeStateWeak](jsi::Function* ptr) {
26
+ if (!runtimeStateWeak.expired()) {
25
27
  // Only delete the jsi::Function when the runtime it created is still alive.
26
28
  // Otherwise leak memory. We do this on purpose, as sometimes we would keep
27
29
  // references to JSI objects past the lifetime of its runtime (e.g.,
@@ -0,0 +1,18 @@
1
+ #include "RNFRuntimeState.h"
2
+
3
+ namespace rnwgpu {
4
+
5
+ const facebook::jsi::UUID RNFRuntimeState::kRuntimeStateKey = facebook::jsi::UUID();
6
+
7
+ std::shared_ptr<RNFRuntimeState> RNFRuntimeState::get(facebook::jsi::Runtime& runtime) {
8
+ auto existing = runtime.getRuntimeData(kRuntimeStateKey);
9
+ if (existing) {
10
+ return std::static_pointer_cast<RNFRuntimeState>(existing);
11
+ }
12
+
13
+ auto state = std::shared_ptr<RNFRuntimeState>(new RNFRuntimeState());
14
+ runtime.setRuntimeData(kRuntimeStateKey, state);
15
+ return state;
16
+ }
17
+
18
+ } // namespace rnwgpu
@@ -0,0 +1,106 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+
5
+ #include <memory>
6
+ #include <mutex>
7
+ #include <unordered_map>
8
+ #include <unordered_set>
9
+
10
+ namespace rnwgpu {
11
+
12
+ namespace jsi = facebook::jsi;
13
+
14
+ /**
15
+ * Runtime state management using Hermes' runtime.setRuntimeData API.
16
+ * This replaces the old RuntimeLifecycleMonitor/RuntimeAwareCache system.
17
+ */
18
+ class RNFRuntimeState {
19
+ public:
20
+ // UUID key for storing our runtime state
21
+ static const jsi::UUID kRuntimeStateKey;
22
+
23
+ /**
24
+ * Get or create the runtime state for the given runtime
25
+ */
26
+ static std::shared_ptr<RNFRuntimeState> get(jsi::Runtime& runtime);
27
+
28
+ /**
29
+ * Template cache that can store any type T per object pointer
30
+ */
31
+ template <typename T>
32
+ class ObjectCache {
33
+ public:
34
+ std::shared_ptr<T> getOrCreate(void* object) {
35
+ std::lock_guard<std::mutex> lock(mutex_);
36
+ auto it = cache_.find(object);
37
+ if (it != cache_.end()) {
38
+ return it->second;
39
+ }
40
+
41
+ auto value = std::make_shared<T>();
42
+ cache_[object] = value;
43
+ return value;
44
+ }
45
+
46
+ void remove(void* object) {
47
+ std::lock_guard<std::mutex> lock(mutex_);
48
+ cache_.erase(object);
49
+ }
50
+
51
+ void clear() {
52
+ std::lock_guard<std::mutex> lock(mutex_);
53
+ cache_.clear();
54
+ }
55
+
56
+ private:
57
+ std::mutex mutex_;
58
+ std::unordered_map<void*, std::shared_ptr<T>> cache_;
59
+ };
60
+
61
+ /**
62
+ * Get or create a cache for a specific type T
63
+ */
64
+ template <typename T>
65
+ std::shared_ptr<ObjectCache<T>> getCache() {
66
+ std::lock_guard<std::mutex> lock(mutex_);
67
+
68
+ // Use type_info as key for the cache type
69
+ const std::type_info& typeId = typeid(T);
70
+ auto it = typeCaches_.find(&typeId);
71
+
72
+ if (it != typeCaches_.end()) {
73
+ return std::static_pointer_cast<ObjectCache<T>>(it->second);
74
+ }
75
+
76
+ auto cache = std::make_shared<ObjectCache<T>>();
77
+ typeCaches_[&typeId] = cache;
78
+ return cache;
79
+ }
80
+
81
+ private:
82
+ RNFRuntimeState() = default;
83
+
84
+ std::mutex mutex_;
85
+ // Map from type_info to cache instance
86
+ std::unordered_map<const std::type_info*, std::shared_ptr<void>> typeCaches_;
87
+ };
88
+
89
+ /**
90
+ * Template helper for runtime-aware caching compatible with the old API
91
+ * This provides a migration path from RuntimeAwareCache
92
+ */
93
+ template <typename T>
94
+ class RuntimeAwareCache {
95
+ public:
96
+ T& get(jsi::Runtime& rt) {
97
+ auto state = RNFRuntimeState::get(rt);
98
+ auto cache = state->getCache<T>();
99
+
100
+ // For compatibility, we use the runtime pointer as the object key
101
+ auto ptr = cache->getOrCreate(&rt);
102
+ return *ptr;
103
+ }
104
+ };
105
+
106
+ } // namespace rnwgpu
@@ -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