react-native-wgpu 0.4.2 → 0.5.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 (186) hide show
  1. package/README.md +31 -0
  2. package/android/CMakeLists.txt +3 -3
  3. package/cpp/jsi/{RNFEnumMapper.h → EnumMapper.h} +2 -6
  4. package/cpp/jsi/{RNFJSIConverter.h → JSIConverter.h} +27 -110
  5. package/cpp/jsi/NativeObject.h +607 -0
  6. package/cpp/jsi/{RNFPromise.cpp → Promise.cpp} +3 -6
  7. package/cpp/jsi/{RNFPromise.h → Promise.h} +2 -5
  8. package/cpp/jsi/RuntimeAwareCache.cpp +7 -0
  9. package/cpp/jsi/RuntimeAwareCache.h +100 -0
  10. package/cpp/jsi/RuntimeLifecycleMonitor.cpp +72 -0
  11. package/cpp/jsi/RuntimeLifecycleMonitor.h +32 -0
  12. package/cpp/rnwgpu/ArrayBuffer.h +8 -12
  13. package/cpp/rnwgpu/RNWebGPUManager.cpp +187 -28
  14. package/cpp/rnwgpu/RNWebGPUManager.h +7 -0
  15. package/cpp/rnwgpu/api/Canvas.h +14 -12
  16. package/cpp/rnwgpu/api/GPU.cpp +4 -6
  17. package/cpp/rnwgpu/api/GPU.h +13 -11
  18. package/cpp/rnwgpu/api/GPUAdapter.cpp +9 -9
  19. package/cpp/rnwgpu/api/GPUAdapter.h +14 -11
  20. package/cpp/rnwgpu/api/GPUAdapterInfo.h +17 -15
  21. package/cpp/rnwgpu/api/GPUBindGroup.h +11 -10
  22. package/cpp/rnwgpu/api/GPUBindGroupLayout.h +12 -11
  23. package/cpp/rnwgpu/api/GPUBuffer.h +19 -16
  24. package/cpp/rnwgpu/api/GPUCanvasContext.h +17 -13
  25. package/cpp/rnwgpu/api/GPUCommandBuffer.h +12 -10
  26. package/cpp/rnwgpu/api/GPUCommandEncoder.h +35 -32
  27. package/cpp/rnwgpu/api/GPUCompilationInfo.h +19 -19
  28. package/cpp/rnwgpu/api/GPUCompilationMessage.h +10 -7
  29. package/cpp/rnwgpu/api/GPUComputePassEncoder.h +28 -27
  30. package/cpp/rnwgpu/api/GPUComputePipeline.h +14 -13
  31. package/cpp/rnwgpu/api/GPUDevice.cpp +111 -95
  32. package/cpp/rnwgpu/api/GPUDevice.h +51 -43
  33. package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +12 -10
  34. package/cpp/rnwgpu/api/GPUError.h +19 -29
  35. package/cpp/rnwgpu/api/GPUExtent3D.h +7 -10
  36. package/cpp/rnwgpu/api/GPUExternalTexture.h +12 -11
  37. package/cpp/rnwgpu/api/GPUInternalError.h +31 -0
  38. package/cpp/rnwgpu/api/GPUOrigin2D.h +6 -10
  39. package/cpp/rnwgpu/api/GPUOrigin3D.h +6 -10
  40. package/cpp/rnwgpu/api/GPUOutOfMemoryError.h +33 -0
  41. package/cpp/rnwgpu/api/GPUPipelineLayout.h +12 -10
  42. package/cpp/rnwgpu/api/GPUQuerySet.h +14 -12
  43. package/cpp/rnwgpu/api/GPUQueue.h +18 -17
  44. package/cpp/rnwgpu/api/GPURenderBundle.h +11 -10
  45. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +36 -33
  46. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +49 -47
  47. package/cpp/rnwgpu/api/GPURenderPipeline.h +14 -12
  48. package/cpp/rnwgpu/api/GPUSampler.h +11 -10
  49. package/cpp/rnwgpu/api/GPUShaderModule.cpp +7 -8
  50. package/cpp/rnwgpu/api/GPUShaderModule.h +13 -12
  51. package/cpp/rnwgpu/api/GPUSupportedLimits.h +73 -93
  52. package/cpp/rnwgpu/api/GPUTexture.h +24 -20
  53. package/cpp/rnwgpu/api/GPUTextureView.h +11 -10
  54. package/cpp/rnwgpu/api/GPUValidationError.h +32 -0
  55. package/cpp/rnwgpu/api/ImageBitmap.h +10 -6
  56. package/cpp/rnwgpu/api/RNWebGPU.h +21 -21
  57. package/cpp/rnwgpu/api/descriptors/GPUBindGroupDescriptor.h +3 -7
  58. package/cpp/rnwgpu/api/descriptors/GPUBindGroupEntry.h +7 -11
  59. package/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutDescriptor.h +3 -7
  60. package/cpp/rnwgpu/api/descriptors/GPUBindGroupLayoutEntry.h +3 -7
  61. package/cpp/rnwgpu/api/descriptors/GPUBlendComponent.h +3 -8
  62. package/cpp/rnwgpu/api/descriptors/GPUBlendState.h +3 -7
  63. package/cpp/rnwgpu/api/descriptors/GPUBufferBinding.h +3 -7
  64. package/cpp/rnwgpu/api/descriptors/GPUBufferBindingLayout.h +3 -8
  65. package/cpp/rnwgpu/api/descriptors/GPUBufferDescriptor.h +3 -8
  66. package/cpp/rnwgpu/api/descriptors/GPUBufferUsage.h +28 -32
  67. package/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h +3 -7
  68. package/cpp/rnwgpu/api/descriptors/GPUColor.h +3 -8
  69. package/cpp/rnwgpu/api/descriptors/GPUColorTargetState.h +3 -7
  70. package/cpp/rnwgpu/api/descriptors/GPUColorWrite.h +18 -20
  71. package/cpp/rnwgpu/api/descriptors/GPUCommandBufferDescriptor.h +3 -8
  72. package/cpp/rnwgpu/api/descriptors/GPUCommandEncoderDescriptor.h +3 -8
  73. package/cpp/rnwgpu/api/descriptors/GPUComputePassDescriptor.h +3 -7
  74. package/cpp/rnwgpu/api/descriptors/GPUComputePassTimestampWrites.h +3 -7
  75. package/cpp/rnwgpu/api/descriptors/GPUComputePipelineDescriptor.h +3 -7
  76. package/cpp/rnwgpu/api/descriptors/GPUDepthStencilState.h +3 -7
  77. package/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h +3 -7
  78. package/cpp/rnwgpu/api/descriptors/GPUExternalTextureBindingLayout.h +3 -8
  79. package/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h +3 -7
  80. package/cpp/rnwgpu/api/descriptors/GPUFragmentState.h +3 -7
  81. package/cpp/rnwgpu/api/descriptors/GPUImageCopyBuffer.h +3 -7
  82. package/cpp/rnwgpu/api/descriptors/GPUImageCopyExternalImage.h +3 -7
  83. package/cpp/rnwgpu/api/descriptors/GPUImageCopyTexture.h +3 -7
  84. package/cpp/rnwgpu/api/descriptors/GPUImageCopyTextureTagged.h +3 -7
  85. package/cpp/rnwgpu/api/descriptors/GPUImageDataLayout.h +3 -8
  86. package/cpp/rnwgpu/api/descriptors/GPUMapMode.h +11 -14
  87. package/cpp/rnwgpu/api/descriptors/GPUMultisampleState.h +3 -8
  88. package/cpp/rnwgpu/api/descriptors/GPUPipelineLayoutDescriptor.h +3 -7
  89. package/cpp/rnwgpu/api/descriptors/GPUPrimitiveState.h +3 -8
  90. package/cpp/rnwgpu/api/descriptors/GPUProgrammableStage.h +3 -7
  91. package/cpp/rnwgpu/api/descriptors/GPUQuerySetDescriptor.h +3 -8
  92. package/cpp/rnwgpu/api/descriptors/GPUQueueDescriptor.h +3 -8
  93. package/cpp/rnwgpu/api/descriptors/GPURenderBundleDescriptor.h +3 -8
  94. package/cpp/rnwgpu/api/descriptors/GPURenderBundleEncoderDescriptor.h +3 -8
  95. package/cpp/rnwgpu/api/descriptors/GPURenderPassColorAttachment.h +3 -7
  96. package/cpp/rnwgpu/api/descriptors/GPURenderPassDepthStencilAttachment.h +3 -7
  97. package/cpp/rnwgpu/api/descriptors/GPURenderPassDescriptor.h +3 -7
  98. package/cpp/rnwgpu/api/descriptors/GPURenderPassTimestampWrites.h +3 -7
  99. package/cpp/rnwgpu/api/descriptors/GPURenderPipelineDescriptor.h +3 -7
  100. package/cpp/rnwgpu/api/descriptors/GPURequestAdapterOptions.h +3 -8
  101. package/cpp/rnwgpu/api/descriptors/GPUSamplerBindingLayout.h +3 -8
  102. package/cpp/rnwgpu/api/descriptors/GPUSamplerDescriptor.h +3 -8
  103. package/cpp/rnwgpu/api/descriptors/GPUShaderModuleCompilationHint.h +3 -7
  104. package/cpp/rnwgpu/api/descriptors/GPUShaderModuleDescriptor.h +3 -7
  105. package/cpp/rnwgpu/api/descriptors/GPUShaderStage.h +14 -16
  106. package/cpp/rnwgpu/api/descriptors/GPUStencilFaceState.h +3 -8
  107. package/cpp/rnwgpu/api/descriptors/GPUStorageTextureBindingLayout.h +3 -8
  108. package/cpp/rnwgpu/api/descriptors/GPUTextureBindingLayout.h +3 -8
  109. package/cpp/rnwgpu/api/descriptors/GPUTextureDescriptor.h +3 -7
  110. package/cpp/rnwgpu/api/descriptors/GPUTextureUsage.h +18 -29
  111. package/cpp/rnwgpu/api/descriptors/GPUTextureViewDescriptor.h +3 -8
  112. package/cpp/rnwgpu/api/descriptors/GPUUncapturedErrorEventInit.h +3 -7
  113. package/cpp/rnwgpu/api/descriptors/GPUVertexAttribute.h +3 -8
  114. package/cpp/rnwgpu/api/descriptors/GPUVertexBufferLayout.h +3 -7
  115. package/cpp/rnwgpu/api/descriptors/GPUVertexState.h +3 -7
  116. package/cpp/rnwgpu/api/descriptors/Unions.h +3 -3
  117. package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +10 -10
  118. package/cpp/rnwgpu/async/AsyncTaskHandle.h +2 -2
  119. package/lib/commonjs/external/ModuleProxy.js +36 -0
  120. package/lib/commonjs/external/ModuleProxy.js.map +1 -0
  121. package/lib/commonjs/external/index.js +17 -0
  122. package/lib/commonjs/external/index.js.map +1 -0
  123. package/lib/commonjs/external/reanimated/ReanimatedProxy.js +18 -0
  124. package/lib/commonjs/external/reanimated/ReanimatedProxy.js.map +1 -0
  125. package/lib/commonjs/external/reanimated/index.js +21 -0
  126. package/lib/commonjs/external/reanimated/index.js.map +1 -0
  127. package/lib/commonjs/external/reanimated/registerWebGPUForReanimated.js +50 -0
  128. package/lib/commonjs/external/reanimated/registerWebGPUForReanimated.js.map +1 -0
  129. package/lib/commonjs/main/index.js +2 -142
  130. package/lib/commonjs/main/index.js.map +1 -1
  131. package/lib/module/external/ModuleProxy.js +28 -0
  132. package/lib/module/external/ModuleProxy.js.map +1 -0
  133. package/lib/module/external/index.js +2 -0
  134. package/lib/module/external/index.js.map +1 -0
  135. package/lib/module/external/reanimated/ReanimatedProxy.js +12 -0
  136. package/lib/module/external/reanimated/ReanimatedProxy.js.map +1 -0
  137. package/lib/module/external/reanimated/index.js +3 -0
  138. package/lib/module/external/reanimated/index.js.map +1 -0
  139. package/lib/module/external/reanimated/registerWebGPUForReanimated.js +43 -0
  140. package/lib/module/external/reanimated/registerWebGPUForReanimated.js.map +1 -0
  141. package/lib/module/main/index.js +2 -141
  142. package/lib/module/main/index.js.map +1 -1
  143. package/lib/typescript/babel.config.d.ts +1 -0
  144. package/lib/typescript/lib/commonjs/external/ModuleProxy.d.ts +12 -0
  145. package/lib/typescript/lib/commonjs/external/ModuleProxy.d.ts.map +1 -0
  146. package/lib/typescript/lib/commonjs/external/index.d.ts +2 -0
  147. package/lib/typescript/lib/commonjs/external/index.d.ts.map +1 -0
  148. package/lib/typescript/lib/commonjs/external/reanimated/ReanimatedProxy.d.ts +6 -0
  149. package/lib/typescript/lib/commonjs/external/reanimated/ReanimatedProxy.d.ts.map +1 -0
  150. package/lib/typescript/lib/commonjs/external/reanimated/index.d.ts +4 -0
  151. package/lib/typescript/lib/commonjs/external/reanimated/index.d.ts.map +1 -0
  152. package/lib/typescript/lib/commonjs/external/reanimated/registerWebGPUForReanimated.d.ts +9 -0
  153. package/lib/typescript/lib/commonjs/external/reanimated/registerWebGPUForReanimated.d.ts.map +1 -0
  154. package/lib/typescript/lib/module/external/ModuleProxy.d.ts +7 -0
  155. package/lib/typescript/lib/module/external/ModuleProxy.d.ts.map +1 -0
  156. package/lib/typescript/lib/module/external/index.d.ts +2 -0
  157. package/lib/typescript/lib/module/external/index.d.ts.map +1 -0
  158. package/lib/typescript/lib/module/external/reanimated/ReanimatedProxy.d.ts +5 -0
  159. package/lib/typescript/lib/module/external/reanimated/ReanimatedProxy.d.ts.map +1 -0
  160. package/lib/typescript/lib/module/external/reanimated/index.d.ts +3 -0
  161. package/lib/typescript/lib/module/external/reanimated/index.d.ts.map +1 -0
  162. package/lib/typescript/lib/module/external/reanimated/registerWebGPUForReanimated.d.ts +2 -0
  163. package/lib/typescript/lib/module/external/reanimated/registerWebGPUForReanimated.d.ts.map +1 -0
  164. package/lib/typescript/src/external/ModuleProxy.d.ts +11 -0
  165. package/lib/typescript/src/external/ModuleProxy.d.ts.map +1 -0
  166. package/lib/typescript/src/external/index.d.ts +2 -0
  167. package/lib/typescript/src/external/index.d.ts.map +1 -0
  168. package/lib/typescript/src/external/reanimated/ReanimatedProxy.d.ts +4 -0
  169. package/lib/typescript/src/external/reanimated/ReanimatedProxy.d.ts.map +1 -0
  170. package/lib/typescript/src/external/reanimated/index.d.ts +3 -0
  171. package/lib/typescript/src/external/reanimated/index.d.ts.map +1 -0
  172. package/lib/typescript/src/external/reanimated/registerWebGPUForReanimated.d.ts +8 -0
  173. package/lib/typescript/src/external/reanimated/registerWebGPUForReanimated.d.ts.map +1 -0
  174. package/package.json +16 -3
  175. package/src/external/ModuleProxy.ts +30 -0
  176. package/src/external/index.ts +1 -0
  177. package/src/external/reanimated/ReanimatedProxy.ts +19 -0
  178. package/src/external/reanimated/index.ts +2 -0
  179. package/src/external/reanimated/registerWebGPUForReanimated.ts +43 -0
  180. package/src/main/index.tsx +3 -170
  181. package/cpp/jsi/RNFHybridObject.cpp +0 -150
  182. package/cpp/jsi/RNFHybridObject.h +0 -181
  183. package/cpp/jsi/RNFJSIHelper.h +0 -51
  184. package/cpp/jsi/RNFPointerHolder.h +0 -95
  185. package/cpp/jsi/RNFRuntimeState.cpp +0 -18
  186. package/cpp/jsi/RNFRuntimeState.h +0 -106
package/README.md CHANGED
@@ -222,6 +222,37 @@ device.queue.copyExternalImageToTexture(
222
222
  );
223
223
  ```
224
224
 
225
+ ### Reanimated Integration
226
+
227
+ React Native WebGPU supports running WebGPU rendering on the UI thread using [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/) and [React Native Worklets](https://github.com/margelo/react-native-worklets).
228
+
229
+ First, install the optional peer dependencies:
230
+
231
+ ```sh
232
+ npm install react-native-reanimated react-native-worklets
233
+ ```
234
+
235
+ WebGPU objects are automatically registered for Worklets serialization when the module loads. You can pass WebGPU objects like `GPUDevice` and `GPUCanvasContext` directly to worklets:
236
+
237
+ ```tsx
238
+ import { Canvas } from "react-native-wgpu";
239
+ import { runOnUI } from "react-native-reanimated";
240
+
241
+ const renderFrame = (device: GPUDevice, context: GPUCanvasContext) => {
242
+ "worklet";
243
+ // WebGPU rendering code runs on the UI thread
244
+ const commandEncoder = device.createCommandEncoder();
245
+ // ... render ...
246
+ device.queue.submit([commandEncoder.finish()]);
247
+ context.present();
248
+ };
249
+
250
+ // Initialize WebGPU on main thread, then run on UI thread
251
+ const device = await adapter.requestDevice();
252
+ const context = canvasRef.current.getContext("webgpu");
253
+ runOnUI(renderFrame)(device, context);
254
+ ```
255
+
225
256
  ## Troubleshooting
226
257
 
227
258
  ### iOS
@@ -44,9 +44,9 @@ add_library(${PACKAGE_NAME} SHARED
44
44
  ../cpp/rnwgpu/api/GPUComputePipeline.cpp
45
45
  ../cpp/rnwgpu/api/GPUCanvasContext.cpp
46
46
  ../cpp/rnwgpu/RNWebGPUManager.cpp
47
- ../cpp/jsi/RNFPromise.cpp
48
- ../cpp/jsi/RNFHybridObject.cpp
49
- ../cpp/jsi/RNFRuntimeState.cpp
47
+ ../cpp/jsi/Promise.cpp
48
+ ../cpp/jsi/RuntimeLifecycleMonitor.cpp
49
+ ../cpp/jsi/RuntimeAwareCache.cpp
50
50
  ../cpp/rnwgpu/async/AsyncRunner.cpp
51
51
  ../cpp/rnwgpu/async/AsyncTaskHandle.cpp
52
52
  ../cpp/rnwgpu/async/JSIMicrotaskDispatcher.cpp
@@ -1,13 +1,9 @@
1
- //
2
- // Created by Marc Rousavy on 22.02.24.
3
- //
4
-
5
1
  #pragma once
6
2
 
7
3
  #include <stdexcept>
8
4
  #include <string>
9
5
 
10
- namespace margelo {
6
+ namespace rnwgpu {
11
7
 
12
8
  namespace EnumMapper {
13
9
  // Add these two methods in namespace "EnumMapper" to allow parsing a custom enum:
@@ -46,4 +42,4 @@ namespace EnumMapper {
46
42
  }
47
43
  } // namespace EnumMapper
48
44
 
49
- } // namespace margelo
45
+ } // namespace rnwgpu
@@ -1,17 +1,10 @@
1
- //
2
- // Created by Marc Rousavy on 21.02.24.
3
- //
4
-
5
1
  #pragma once
6
2
 
7
3
  #include <memory>
8
- #include <array>
9
- #include <future>
10
4
  #include <vector>
11
5
  #include <string>
12
6
  #include <utility>
13
7
  #include <type_traits>
14
- #include <unordered_map>
15
8
  #include <limits>
16
9
  #include <variant>
17
10
  #include <map>
@@ -19,9 +12,8 @@
19
12
 
20
13
  #include <jsi/jsi.h>
21
14
 
22
- #include "RNFEnumMapper.h"
23
- #include "RNFJSIHelper.h"
24
- #include "RNFPromise.h"
15
+ #include "EnumMapper.h"
16
+ #include "Promise.h"
25
17
 
26
18
  #include "Unions.h"
27
19
 
@@ -34,7 +26,7 @@
34
26
  #include <cxxabi.h>
35
27
  #endif
36
28
 
37
- namespace margelo {
29
+ namespace rnwgpu {
38
30
 
39
31
  namespace jsi = facebook::jsi;
40
32
 
@@ -212,8 +204,8 @@ template <> struct JSIConverter<rnwgpu::async::AsyncTaskHandle> {
212
204
  }
213
205
 
214
206
  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 {
207
+ return rnwgpu::Promise::createPromise(runtime, [handle = std::move(handle)](jsi::Runtime& runtime,
208
+ std::shared_ptr<rnwgpu::Promise> promise) mutable {
217
209
  if (!handle.valid()) {
218
210
  promise->resolve(jsi::Value::undefined());
219
211
  return;
@@ -275,98 +267,6 @@ template <typename ElementType> struct JSIConverter<std::vector<ElementType>> {
275
267
  }
276
268
  };
277
269
 
278
- // std::unordered_map<std::string, T> <> Record<string, T>
279
- template <typename ValueType> struct JSIConverter<std::unordered_map<std::string, ValueType>> {
280
- static std::unordered_map<std::string, ValueType> fromJSI(jsi::Runtime& runtime, const jsi::Value& arg, bool outOfBound) {
281
- jsi::Object object = arg.asObject(runtime);
282
- jsi::Array propertyNames = object.getPropertyNames(runtime);
283
- size_t length = propertyNames.size(runtime);
284
-
285
- std::unordered_map<std::string, ValueType> map;
286
- map.reserve(length);
287
- for (size_t i = 0; i < length; ++i) {
288
- std::string key = propertyNames.getValueAtIndex(runtime, i).asString(runtime).utf8(runtime);
289
- jsi::Value value = object.getProperty(runtime, key.c_str());
290
- map.emplace(key, JSIConverter<ValueType>::fromJSI(runtime, value, outOfBound));
291
- }
292
- return map;
293
- }
294
- static jsi::Value toJSI(jsi::Runtime& runtime, const std::unordered_map<std::string, ValueType>& map) {
295
- jsi::Object object(runtime);
296
- for (const auto& pair : map) {
297
- jsi::Value value = JSIConverter<ValueType>::toJSI(runtime, pair.second);
298
- jsi::String key = jsi::String::createFromUtf8(runtime, pair.first);
299
- object.setProperty(runtime, key, std::move(value));
300
- }
301
- return object;
302
- }
303
- };
304
-
305
- // HybridObject <> {}
306
- template <typename T> struct is_shared_ptr_to_host_object : std::false_type {};
307
-
308
- template <typename T> struct is_shared_ptr_to_host_object<std::shared_ptr<T>> : std::is_base_of<jsi::HostObject, T> {};
309
-
310
- template <typename T> struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_host_object<T>::value>> {
311
- using TPointee = typename T::element_type;
312
-
313
- #if DEBUG
314
- inline static std::string getFriendlyTypename() {
315
- std::string name = std::string(typeid(TPointee).name());
316
- #if __has_include(<cxxabi.h>)
317
- int status = 0;
318
- char* demangled_name = abi::__cxa_demangle(name.c_str(), NULL, NULL, &status);
319
- if (status == 0) {
320
- name = demangled_name;
321
- std::free(demangled_name);
322
- }
323
- #endif
324
- return name;
325
- }
326
-
327
- inline static std::string invalidTypeErrorMessage(const std::string& typeDescription, const std::string& reason) {
328
- return "Cannot convert \"" + typeDescription + "\" to HostObject<" + getFriendlyTypename() + ">! " + reason;
329
- }
330
- #endif
331
-
332
- static T fromJSI(jsi::Runtime& runtime, const jsi::Value& arg, bool outOfBound) {
333
- #if DEBUG
334
- if (arg.isUndefined()) {
335
- [[unlikely]];
336
- throw jsi::JSError(runtime, invalidTypeErrorMessage("undefined", "It is undefined!"));
337
- }
338
- if (!arg.isObject()) {
339
- [[unlikely]];
340
- std::string stringRepresentation = arg.toString(runtime).utf8(runtime);
341
- throw jsi::JSError(runtime, invalidTypeErrorMessage(stringRepresentation, "It is not an object!"));
342
- }
343
- #endif
344
- jsi::Object object = arg.getObject(runtime);
345
- #if DEBUG
346
- if (!object.isHostObject<TPointee>(runtime)) {
347
- [[unlikely]];
348
- std::string stringRepresentation = arg.toString(runtime).utf8(runtime);
349
- throw jsi::JSError(runtime, invalidTypeErrorMessage(stringRepresentation, "It is a different HostObject<T>!"));
350
- }
351
- #endif
352
- return object.getHostObject<TPointee>(runtime);
353
- }
354
- static jsi::Value toJSI(jsi::Runtime& runtime, const T& arg) {
355
- #if DEBUG
356
- if (arg == nullptr) {
357
- [[unlikely]];
358
- throw jsi::JSError(runtime, "Cannot convert nullptr to HostObject<" + getFriendlyTypename() + ">!");
359
- }
360
- #endif
361
- auto result = jsi::Object::createFromHostObject(runtime, arg);
362
- auto memoryPressure = arg->getMemoryPressure();
363
- if (memoryPressure > 0) {
364
- result.setExternalMemoryPressure(runtime, memoryPressure);
365
- }
366
- return result;
367
- }
368
- };
369
-
370
270
  // NativeState <> {}
371
271
  template <typename T> struct is_shared_ptr_to_native_state : std::false_type {};
372
272
 
@@ -416,16 +316,33 @@ template <typename T> struct JSIConverter<T, std::enable_if_t<is_shared_ptr_to_n
416
316
  #endif
417
317
  return object.getNativeState<TPointee>(runtime);
418
318
  }
319
+ private:
320
+ // SFINAE helper to detect if T has a IsNativeObject marker type
321
+ template <typename U, typename = typename U::IsNativeObject>
322
+ static std::true_type hasNativeObjectMarker(int);
323
+ template <typename U>
324
+ static std::false_type hasNativeObjectMarker(...);
325
+
326
+ // Type trait for detection
327
+ static constexpr bool is_native_object = decltype(hasNativeObjectMarker<TPointee>(0))::value;
328
+
329
+ public:
419
330
  static jsi::Value toJSI(jsi::Runtime& runtime, const T& arg) {
420
331
  #if DEBUG
421
332
  if (arg == nullptr) {
422
333
  [[unlikely]];
423
- throw jsi::JSError(runtime, "Cannot convert nullptr to HostObject<" + getFriendlyTypename() + ">!");
334
+ throw jsi::JSError(runtime, "Cannot convert nullptr to NativeState<" + getFriendlyTypename() + ">!");
424
335
  }
425
336
  #endif
426
- jsi::Object object(runtime);
427
- object.setNativeState(runtime, arg);
428
- return object;
337
+ // Check if the type is a NativeObject (has IsNativeObject marker)
338
+ // Use TPointee::create() if it's a NativeObject, otherwise fall back to plain setNativeState
339
+ if constexpr (is_native_object) {
340
+ return TPointee::create(runtime, arg);
341
+ } else {
342
+ jsi::Object object(runtime);
343
+ object.setNativeState(runtime, arg);
344
+ return object;
345
+ }
429
346
  }
430
347
  };
431
348
 
@@ -545,4 +462,4 @@ struct JSIConverter<std::unordered_set<std::string>> {
545
462
  }
546
463
  };
547
464
 
548
- } // namespace margelo
465
+ } // namespace rnwgpu