react-native-wgpu 0.1.13 → 0.1.15

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 (56) hide show
  1. package/android/CMakeLists.txt +7 -0
  2. package/android/build.gradle +4 -4
  3. package/android/cpp/cpp-adapter.cpp +10 -4
  4. package/android/cpp/platform/ThreadUtils.cpp +41 -0
  5. package/apple/platform/ThreadUtils.cpp +33 -0
  6. package/cpp/jsi/RNFJSIConverter.h +47 -28
  7. package/cpp/platform/ThreadUtils.h +30 -0
  8. package/cpp/rnwgpu/RNWebGPUManager.cpp +8 -0
  9. package/cpp/rnwgpu/SurfaceRegistry.h +12 -8
  10. package/cpp/rnwgpu/api/Convertors.h +13 -5
  11. package/cpp/rnwgpu/api/GPU.cpp +4 -4
  12. package/cpp/rnwgpu/api/GPUAdapter.cpp +15 -14
  13. package/cpp/rnwgpu/api/GPUAdapterInfo.h +25 -4
  14. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +3 -2
  15. package/cpp/rnwgpu/api/GPUDevice.cpp +5 -5
  16. package/cpp/rnwgpu/api/GPUDevice.h +7 -1
  17. package/cpp/rnwgpu/api/GPUFeatures.h +4 -4
  18. package/cpp/rnwgpu/api/GPUShaderModule.cpp +2 -1
  19. package/cpp/rnwgpu/api/descriptors/GPUCanvasConfiguration.h +3 -1
  20. package/cpp/rnwgpu/api/descriptors/Unions.h +30 -0
  21. package/cpp/threading/CallInvokerDispatcher.h +37 -0
  22. package/cpp/threading/Dispatcher.cpp +54 -0
  23. package/cpp/threading/Dispatcher.h +93 -0
  24. package/cpp/threading/ThreadPool.cpp +86 -0
  25. package/cpp/threading/ThreadPool.h +53 -0
  26. package/cpp/webgpu/webgpu.h +762 -758
  27. package/cpp/webgpu/webgpu_cpp.h +1827 -1626
  28. package/cpp/webgpu/webgpu_cpp_chained_struct.h +2 -0
  29. package/lib/commonjs/hooks.js +4 -2
  30. package/lib/commonjs/hooks.js.map +1 -1
  31. package/lib/module/hooks.js +4 -2
  32. package/lib/module/hooks.js.map +1 -1
  33. package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -1
  34. package/lib/typescript/lib/module/hooks.d.ts.map +1 -1
  35. package/lib/typescript/src/hooks.d.ts.map +1 -1
  36. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  37. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  38. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  39. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  40. package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
  41. package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  42. package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
  43. package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  44. package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
  45. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +10 -10
  46. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  47. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  48. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  49. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
  50. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
  51. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  52. package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  53. package/libs/dawn.json +270 -251
  54. package/package.json +2 -2
  55. package/src/__tests__/Device.spec.ts +31 -0
  56. package/src/hooks.tsx +3 -2
@@ -25,6 +25,7 @@ find_package(fbjni REQUIRED CONFIG)
25
25
 
26
26
  add_library(${PACKAGE_NAME} SHARED
27
27
  ./cpp/cpp-adapter.cpp
28
+ ./cpp/platform/ThreadUtils.cpp
28
29
  ../cpp/rnwgpu/api/GPU.cpp
29
30
  ../cpp/rnwgpu/api/GPUAdapter.cpp
30
31
  ../cpp/rnwgpu/api/GPUSupportedLimits.cpp
@@ -48,6 +49,8 @@ add_library(${PACKAGE_NAME} SHARED
48
49
  ../cpp/jsi/RNFHybridObject.cpp
49
50
  ../cpp/jsi/RNFRuntimeCache.cpp
50
51
  ../cpp/jsi/RNFWorkletRuntimeRegistry.cpp
52
+ ../cpp/threading/Dispatcher.cpp
53
+ ../cpp/threading/ThreadPool.cpp
51
54
  )
52
55
 
53
56
  target_include_directories(
@@ -61,6 +64,7 @@ target_include_directories(
61
64
  "${NODE_MODULES_DIR}/react-native/ReactCommon/runtimeexecutor"
62
65
  "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni"
63
66
  "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
67
+ "${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni/react/turbomodule"
64
68
 
65
69
  ../cpp
66
70
  ../cpp/rnwgpu
@@ -68,6 +72,8 @@ target_include_directories(
68
72
  ../cpp/rnwgpu/api/descriptors
69
73
  ../cpp/jsi
70
74
  ../cpp/webgpu
75
+ ../cpp/threading
76
+ ../cpp/platform
71
77
 
72
78
  ${libfbjni_include_DIRS}
73
79
  )
@@ -84,5 +90,6 @@ target_link_libraries(
84
90
  android
85
91
  fbjni::fbjni
86
92
  ReactAndroid::jsi
93
+ ReactAndroid::reactnativejni
87
94
  webgpu_dawn
88
95
  )
@@ -87,10 +87,10 @@ android {
87
87
  }
88
88
 
89
89
  packagingOptions {
90
- exclude "lib/arm64-v8a/libjsi.so"
91
- exclude "lib/x86_64/libjsi.so"
92
- exclude "lib/x86/libjsi.so"
93
- exclude "lib/armeabi-v7a/libjsi.so"
90
+ excludes = [
91
+ "**/libjsi.so",
92
+ "**/libreactnativejni.so",
93
+ ]
94
94
  }
95
95
 
96
96
  buildFeatures {
@@ -5,6 +5,7 @@
5
5
  #include <jni.h>
6
6
  #include <jsi/jsi.h>
7
7
 
8
+ #include <ReactCommon/CallInvokerHolder.h>
8
9
  #include <android/native_window_jni.h>
9
10
  #include <webgpu/webgpu_cpp.h>
10
11
 
@@ -17,13 +18,18 @@
17
18
  std::shared_ptr<rnwgpu::RNWebGPUManager> manager;
18
19
 
19
20
  extern "C" JNIEXPORT void JNICALL Java_com_webgpu_WebGPUModule_initializeNative(
20
- JNIEnv *env, jobject /* this */, jlong jsRuntime, jobject jsInvokerHolder,
21
- jobject blobModule) {
21
+ JNIEnv *env, jobject /* this */, jlong jsRuntime,
22
+ jobject jsCallInvokerHolder, jobject blobModule) {
22
23
  auto runtime = reinterpret_cast<facebook::jsi::Runtime *>(jsRuntime);
23
24
  jobject globalBlobModule = env->NewGlobalRef(blobModule);
25
+ auto jsCallInvoker{
26
+ facebook::jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>{
27
+ reinterpret_cast<facebook::react::CallInvokerHolder::javaobject>(
28
+ jsCallInvokerHolder)} -> cthis()
29
+ ->getCallInvoker()};
24
30
  auto platformContext =
25
31
  std::make_shared<rnwgpu::AndroidPlatformContext>(globalBlobModule);
26
- manager = std::make_shared<rnwgpu::RNWebGPUManager>(runtime, nullptr,
32
+ manager = std::make_shared<rnwgpu::RNWebGPUManager>(runtime, jsCallInvoker,
27
33
  platformContext);
28
34
  }
29
35
 
@@ -55,7 +61,7 @@ Java_com_webgpu_WebGPUView_switchToOffscreenSurface(JNIEnv *env, jobject thiz,
55
61
  jint contextId) {
56
62
  auto &registry = rnwgpu::SurfaceRegistry::getInstance();
57
63
  auto nativeSurface = registry.getSurfaceInfo(contextId)->switchToOffscreen();
58
- ANativeWindow_release(reinterpret_cast<ANativeWindow *>(nativeSurface));
64
+ // ANativeWindow_release(reinterpret_cast<ANativeWindow *>(nativeSurface));
59
65
  }
60
66
 
61
67
  extern "C" JNIEXPORT void JNICALL Java_com_webgpu_WebGPUView_onSurfaceDestroy(
@@ -0,0 +1,41 @@
1
+ //
2
+ // ThreadUtils.cpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 14.07.24.
6
+ //
7
+
8
+ #include "ThreadUtils.h"
9
+ #include <pthread.h>
10
+ #include <sstream>
11
+ #include <string>
12
+ #include <sys/prctl.h>
13
+ #include <thread>
14
+
15
+ namespace margelo {
16
+
17
+ std::string ThreadUtils::getThreadName() {
18
+ #ifdef HAVE_ANDROID_PTHREAD_SETNAME_NP
19
+ // Try using pthread APIs
20
+ pthread_t this_thread = pthread_self();
21
+ char thread_name[16]; // Thread name length limit in Android is 16 characters
22
+
23
+ int result =
24
+ pthread_getname_np(this_thread, thread_name, sizeof(thread_name));
25
+ if (result == 0) {
26
+ return std::string(thread_name);
27
+ }
28
+ #endif
29
+
30
+ // Fall back to this_thread ID
31
+ std::stringstream stream;
32
+ stream << std::this_thread::get_id();
33
+ std::string threadId = stream.str();
34
+ return "Thread #" + threadId;
35
+ }
36
+
37
+ void ThreadUtils::setThreadName(const std::string &name) {
38
+ prctl(PR_SET_NAME, name.c_str(), 0, 0, 0);
39
+ }
40
+
41
+ } // namespace margelo
@@ -0,0 +1,33 @@
1
+ //
2
+ // ThreadUtils.cpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 14.07.24.
6
+ //
7
+
8
+ #include "ThreadUtils.h"
9
+ #include <pthread.h>
10
+ #include <sstream>
11
+ #include <thread>
12
+
13
+ namespace margelo {
14
+
15
+ std::string ThreadUtils::getThreadName() {
16
+ // Try using pthread APIs
17
+ char name[256];
18
+ if (pthread_getname_np(pthread_self(), name, sizeof(name)) == 0) {
19
+ return std::string(name);
20
+ }
21
+
22
+ // Fall back to this_thread ID
23
+ std::stringstream stream;
24
+ stream << std::this_thread::get_id();
25
+ std::string threadId = stream.str();
26
+ return "Thread #" + threadId;
27
+ }
28
+
29
+ void ThreadUtils::setThreadName(const std::string &name) {
30
+ pthread_setname_np(name.c_str());
31
+ }
32
+
33
+ } // namespace margelo
@@ -25,6 +25,9 @@
25
25
  #include "RNFPromise.h"
26
26
  #include "RNFWorkletRuntimeRegistry.h"
27
27
 
28
+ #include "Dispatcher.h"
29
+ #include "ThreadPool.h"
30
+
28
31
  #if __has_include(<cxxabi.h>)
29
32
  #include <cxxabi.h>
30
33
  #endif
@@ -207,39 +210,55 @@ template <typename TResult> struct JSIConverter<std::future<TResult>> {
207
210
  }
208
211
  static jsi::Value toJSI(jsi::Runtime& runtime, std::future<TResult>&& arg) {
209
212
  auto sharedFuture = std::make_shared<std::future<TResult>>(std::move(arg));
210
- return Promise::createPromise(runtime, [sharedFuture = std::move(sharedFuture)](jsi::Runtime& runtime,
213
+ std::shared_ptr<Dispatcher> strongDispatcher = Dispatcher::getRuntimeGlobalDispatcher(runtime);
214
+ std::weak_ptr<Dispatcher> weakDispatcher = strongDispatcher;
215
+
216
+ return Promise::createPromise(runtime, [sharedFuture = std::move(sharedFuture), weakDispatcher](jsi::Runtime& runtime,
211
217
  std::shared_ptr<Promise> promise) {
212
- try {
213
- // wait until the future completes.
218
+ // Spawn new async thread to synchronously wait for the `future<T>` to complete
219
+ std::shared_ptr<ThreadPool> pool = ThreadPool::getSharedPool();
220
+ pool->run([promise, &runtime, weakDispatcher, sharedFuture]() {
221
+ // synchronously wait until the `future<T>` completes. we are running on a background task here.
214
222
  sharedFuture->wait();
215
223
 
216
- if constexpr (std::is_same_v<TResult, void>) {
217
- // it's returning void, just return undefined to JS
218
- sharedFuture->get();
219
- promise->resolve(jsi::Value::undefined());
220
- } else {
221
- // it's returning a custom type, convert it to a jsi::Value
222
- TResult result = sharedFuture->get();
223
- jsi::Value jsResult = JSIConverter<TResult>::toJSI(runtime, result);
224
- promise->resolve(std::move(jsResult));
224
+ std::shared_ptr<Dispatcher> dispatcher = weakDispatcher.lock();
225
+ if (!dispatcher) {
226
+ throw std::runtime_error("Tried resolving Promise on JS Thread, but the `Dispatcher` has already been destroyed!");
227
+ return;
225
228
  }
226
- } catch (const std::exception& exception) {
227
- // the async function threw an error, reject the promise
228
- std::string what = exception.what();
229
- promise->reject(what);
230
- } catch (...) {
231
- // the async function threw a non-std error, try getting it
232
- #if __has_include(<cxxabi.h>)
233
- std::string name = __cxxabiv1::__cxa_current_exception_type()->name();
234
- #else
235
- std::string name = "<unknown>";
236
- #endif
237
- promise->reject("Unknown non-std exception: " + name);
238
- }
239
229
 
240
- // This lambda owns the promise shared pointer, and we need to call its
241
- // destructor correctly here - ensuring it's properly handled.
242
- promise = nullptr;
230
+ dispatcher->runAsync([&runtime, promise, sharedFuture]() mutable {
231
+ try {
232
+ if constexpr (std::is_same_v<TResult, void>) {
233
+ // it's returning void, just return undefined to JS
234
+ sharedFuture->get();
235
+ promise->resolve(jsi::Value::undefined());
236
+ } else {
237
+ // it's returning a custom type, convert it to a jsi::Value
238
+ TResult result = sharedFuture->get();
239
+ jsi::Value jsResult = JSIConverter<TResult>::toJSI(runtime, result);
240
+ promise->resolve(std::move(jsResult));
241
+ }
242
+ } catch (const std::exception& exception) {
243
+ // the async function threw an error, reject the promise
244
+ std::string what = exception.what();
245
+ promise->reject(what);
246
+ } catch (...) {
247
+ // the async function threw a non-std error, try getting it
248
+ #if __has_include(<cxxabi.h>)
249
+ std::string name = __cxxabiv1::__cxa_current_exception_type()->name();
250
+ #else
251
+ std::string name = "<unknown>";
252
+ #endif
253
+ promise->reject("Unknown non-std exception: " + name);
254
+ }
255
+
256
+ // This lambda owns the promise shared pointer, and we need to call its
257
+ // destructor correctly here - otherwise it might be called
258
+ // from the threadPool thread.
259
+ promise = nullptr;
260
+ });
261
+ });
243
262
  });
244
263
  }
245
264
  };
@@ -0,0 +1,30 @@
1
+ //
2
+ // ThreadUtils.hpp
3
+ // react-native-nitro
4
+ //
5
+ // Created by Marc Rousavy on 14.07.24.
6
+ //
7
+ #pragma once
8
+
9
+ #include <string>
10
+
11
+ namespace margelo {
12
+
13
+ class ThreadUtils final {
14
+ public:
15
+ ThreadUtils() = delete;
16
+
17
+ /**
18
+ * Get the current Thread's name.
19
+ * This is implemented differently on iOS and Android.
20
+ */
21
+ static std::string getThreadName();
22
+
23
+ /**
24
+ * Set the current Thread's name.
25
+ * This is implemented differently on iOS and Android.
26
+ */
27
+ static void setThreadName(const std::string &name);
28
+ };
29
+
30
+ } // namespace margelo
@@ -1,5 +1,7 @@
1
1
  #include "RNWebGPUManager.h"
2
2
 
3
+ #include "CallInvokerDispatcher.h"
4
+ #include "Dispatcher.h"
3
5
  #include "GPU.h"
4
6
  #include "RNWebGPU.h"
5
7
 
@@ -22,6 +24,12 @@ RNWebGPUManager::RNWebGPUManager(
22
24
  : _jsRuntime(jsRuntime), _jsCallInvoker(jsCallInvoker),
23
25
  _platformContext(platformContext) {
24
26
 
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
+
25
33
  auto gpu = std::make_shared<GPU>();
26
34
  auto rnWebGPU = std::make_shared<RNWebGPU>(gpu, _platformContext);
27
35
  _gpu = gpu->get();
@@ -50,14 +50,18 @@ public:
50
50
 
51
51
  void *switchToOffscreen() {
52
52
  std::unique_lock<std::shared_mutex> lock(_mutex);
53
- wgpu::TextureDescriptor textureDesc;
54
- textureDesc.usage = wgpu::TextureUsage::RenderAttachment |
55
- wgpu::TextureUsage::CopySrc |
56
- wgpu::TextureUsage::TextureBinding;
57
- textureDesc.format = config.format;
58
- textureDesc.size.width = config.width;
59
- textureDesc.size.height = config.height;
60
- texture = config.device.CreateTexture(&textureDesc);
53
+ // We only do this if the onscreen surface is configured.
54
+ auto isConfigured = config.device != nullptr;
55
+ if (isConfigured) {
56
+ wgpu::TextureDescriptor textureDesc;
57
+ textureDesc.usage = wgpu::TextureUsage::RenderAttachment |
58
+ wgpu::TextureUsage::CopySrc |
59
+ wgpu::TextureUsage::TextureBinding;
60
+ textureDesc.format = config.format;
61
+ textureDesc.size.width = config.width;
62
+ textureDesc.size.height = config.height;
63
+ texture = config.device.CreateTexture(&textureDesc);
64
+ }
61
65
  surface = nullptr;
62
66
  return nativeSurface;
63
67
  }
@@ -175,6 +175,17 @@ public:
175
175
  return true;
176
176
  }
177
177
 
178
+ [[nodiscard]] bool Convert(wgpu::OptionalBool &out,
179
+ const std::optional<bool> &in) {
180
+ out = in;
181
+ return true;
182
+ }
183
+
184
+ [[nodiscard]] bool Convert(wgpu::StringView &out, const std::string &in) {
185
+ out = {in.data(), in.size()};
186
+ return true;
187
+ }
188
+
178
189
  [[nodiscard]] bool Convert(const char *&out, const std::string &in) {
179
190
  out = in.c_str();
180
191
  return true;
@@ -481,11 +492,8 @@ public:
481
492
  const GPUPrimitiveState &in) {
482
493
  out = {};
483
494
 
484
- if (in.unclippedDepth) {
485
- wgpu::PrimitiveDepthClipControl *depthClip =
486
- Allocate<wgpu::PrimitiveDepthClipControl>();
487
- depthClip->unclippedDepth = true;
488
- out.nextInChain = depthClip;
495
+ if (in.unclippedDepth.has_value()) {
496
+ out.unclippedDepth = in.unclippedDepth.value();
489
497
  }
490
498
 
491
499
  return Convert(out.topology, in.topology) &&
@@ -28,10 +28,10 @@ GPU::requestAdapter(
28
28
  wgpu::Adapter adapter = nullptr;
29
29
  _instance.RequestAdapter(
30
30
  &aOptions,
31
- [](WGPURequestAdapterStatus, WGPUAdapter cAdapter, const char *message,
32
- void *userdata) {
33
- if (message != nullptr) {
34
- fprintf(stderr, "%s", message);
31
+ [](WGPURequestAdapterStatus, WGPUAdapter cAdapter,
32
+ const WGPUStringView message, void *userdata) {
33
+ if (message.length) {
34
+ fprintf(stderr, "%s", message.data);
35
35
  return;
36
36
  }
37
37
  *static_cast<wgpu::Adapter *>(userdata) =
@@ -23,7 +23,7 @@ std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
23
23
  }
24
24
  wgpu::DeviceLostCallbackInfo info = {
25
25
  .callback = [](WGPUDevice const *device, WGPUDeviceLostReason reason,
26
- char const *message, void *userdata) {
26
+ const WGPUStringView message, void *userdata) {
27
27
  const char *lostReason = "";
28
28
  switch (reason) {
29
29
  case WGPUDeviceLostReason_Destroyed:
@@ -35,12 +35,13 @@ std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
35
35
  default:
36
36
  lostReason = "Unknown";
37
37
  }
38
- Logger::logToConsole("GPU Device Lost (%s): %s", lostReason, message);
38
+ Logger::logToConsole("GPU Device Lost (%s): %s", lostReason,
39
+ message.data);
39
40
  }};
40
41
  aDescriptor.deviceLostCallbackInfo = info;
41
42
  wgpu::UncapturedErrorCallbackInfo errorInfo;
42
43
  errorInfo.userdata = static_cast<void *>(_creationRuntime);
43
- errorInfo.callback = [](WGPUErrorType type, const char *message,
44
+ errorInfo.callback = [](WGPUErrorType type, const WGPUStringView message,
44
45
  void *userdata) {
45
46
  auto creationRuntime = static_cast<jsi::Runtime *>(userdata);
46
47
  const char *errorType = "";
@@ -60,16 +61,16 @@ std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
60
61
  default:
61
62
  errorType = "Unknown";
62
63
  }
63
- std::string fullMessage = std::string(errorType) + ": " + message;
64
- Logger::errorToJavascriptConsole(*creationRuntime, fullMessage.c_str());
64
+ std::string fullMessage = std::string(errorType) + ": " + message.data;
65
+ Logger::errorToJavascriptConsole(*creationRuntime, fullMessage);
65
66
  };
66
67
  aDescriptor.uncapturedErrorCallbackInfo = errorInfo;
67
68
  _instance.RequestDevice(
68
69
  &aDescriptor,
69
70
  [](WGPURequestDeviceStatus status, WGPUDevice cDevice,
70
- const char *message, void *userdata) {
71
- if (message != nullptr) {
72
- fprintf(stderr, "%s", message);
71
+ const WGPUStringView message, void *userdata) {
72
+ if (message.length) {
73
+ fprintf(stderr, "%s", message.data);
73
74
  return;
74
75
  }
75
76
  *static_cast<wgpu::Device *>(userdata) = wgpu::Device::Acquire(cDevice);
@@ -80,17 +81,17 @@ std::future<std::shared_ptr<GPUDevice>> GPUAdapter::requestDevice(
80
81
  throw std::runtime_error("Failed to request device");
81
82
  }
82
83
  device.SetLoggingCallback(
83
- [](WGPULoggingType type, const char *message, void *userdata) {
84
+ [](WGPULoggingType type, const WGPUStringView message, void *userdata) {
84
85
  auto creationRuntime = static_cast<jsi::Runtime *>(userdata);
85
86
  const char *logLevel = "";
86
87
  switch (type) {
87
88
  case WGPULoggingType_Warning:
88
89
  logLevel = "Warning";
89
- Logger::warnToJavascriptConsole(*creationRuntime, message);
90
+ Logger::warnToJavascriptConsole(*creationRuntime, message.data);
90
91
  break;
91
92
  case WGPULoggingType_Error:
92
93
  logLevel = "Error";
93
- Logger::errorToJavascriptConsole(*creationRuntime, message);
94
+ Logger::errorToJavascriptConsole(*creationRuntime, message.data);
94
95
  break;
95
96
  case WGPULoggingType_Verbose:
96
97
  logLevel = "Verbose";
@@ -139,9 +140,9 @@ std::shared_ptr<GPUAdapterInfo> GPUAdapter::getInfo() {
139
140
  }
140
141
 
141
142
  bool GPUAdapter::getIsFallbackAdapter() {
142
- wgpu::AdapterProperties adapterProperties = {};
143
- _instance.GetProperties(&adapterProperties);
144
- return adapterProperties.adapterType == wgpu::AdapterType::DiscreteGPU;
143
+ wgpu::AdapterInfo adapterInfo = {};
144
+ _instance.GetInfo(&adapterInfo);
145
+ return adapterInfo.adapterType == wgpu::AdapterType::CPU;
145
146
  }
146
147
 
147
148
  } // namespace rnwgpu
@@ -8,6 +8,7 @@
8
8
  #include "RNFHybridObject.h"
9
9
 
10
10
  #include "AsyncRunner.h"
11
+ #include "Convertors.h"
11
12
 
12
13
  #include "webgpu/webgpu_cpp.h"
13
14
 
@@ -23,10 +24,30 @@ public:
23
24
  public:
24
25
  std::string getBrand() { return _name; }
25
26
 
26
- std::string getVendor() { return _instance.vendor; }
27
- std::string getArchitecture() { return _instance.architecture; }
28
- std::string getDevice() { return _instance.device; }
29
- std::string getDescription() { return _instance.description; }
27
+ std::string getVendor() {
28
+ if (_instance.vendor.length) {
29
+ return _instance.vendor.data;
30
+ }
31
+ return "";
32
+ }
33
+ std::string getArchitecture() {
34
+ if (_instance.architecture.length) {
35
+ return _instance.architecture.data;
36
+ }
37
+ return "";
38
+ }
39
+ std::string getDevice() {
40
+ if (_instance.device.length) {
41
+ return _instance.device.data;
42
+ }
43
+ return "";
44
+ }
45
+ std::string getDescription() {
46
+ if (_instance.device.length) {
47
+ return _instance.device.data;
48
+ }
49
+ return "";
50
+ }
30
51
 
31
52
  void loadHybridMethods() override {
32
53
  registerHybridGetter("__brand", &GPUAdapterInfo::getBrand, this);
@@ -16,8 +16,9 @@ void GPUCanvasContext::configure(
16
16
  throw std::runtime_error("Error with SurfaceConfiguration");
17
17
  }
18
18
  }
19
- if (!conv(surfaceConfiguration.usage, configuration->usage) || !conv(surfaceConfiguration.format, configuration->format)) {
20
- throw std::runtime_error("Error with SurfaceConfiguration");
19
+ if (!conv(surfaceConfiguration.usage, configuration->usage) ||
20
+ !conv(surfaceConfiguration.format, configuration->format)) {
21
+ throw std::runtime_error("Error with SurfaceConfiguration");
21
22
  }
22
23
 
23
24
  #ifdef __APPLE__
@@ -76,10 +76,9 @@ std::shared_ptr<GPUShaderModule> GPUDevice::createShaderModule(
76
76
  }
77
77
  sm_desc.nextInChain = &wgsl_desc;
78
78
  if (descriptor->code.find('\0') != std::string::npos) {
79
- return std::make_shared<GPUShaderModule>(
80
- _instance.CreateErrorShaderModule(
81
- &sm_desc, "The WGSL shader contains an illegal character '\\0'"),
82
- _async, sm_desc.label);
79
+ auto mod = _instance.CreateErrorShaderModule(
80
+ &sm_desc, "The WGSL shader contains an illegal character '\\0'");
81
+ return std::make_shared<GPUShaderModule>(mod, _async, sm_desc.label.data);
83
82
  }
84
83
  auto module = _instance.CreateShaderModule(&sm_desc);
85
84
  return std::make_shared<GPUShaderModule>(module, _async,
@@ -337,6 +336,7 @@ std::unordered_set<std::string> GPUDevice::getFeatures() {
337
336
  }
338
337
 
339
338
  std::future<std::shared_ptr<GPUDeviceLostInfo>> GPUDevice::getLost() {
340
- return m_lostPromise->get_future();
339
+ return std::async(std::launch::async,
340
+ [=]() { return m_lostSharedFuture->get(); });
341
341
  }
342
342
  } // namespace rnwgpu
@@ -57,6 +57,10 @@ public:
57
57
  _label(label) {
58
58
  m_lostPromise =
59
59
  std::make_shared<std::promise<std::shared_ptr<GPUDeviceLostInfo>>>();
60
+
61
+ auto sharedFuture = m_lostPromise->get_future().share();
62
+ m_lostSharedFuture = std::make_shared<
63
+ std::shared_future<std::shared_ptr<GPUDeviceLostInfo>>>(sharedFuture);
60
64
  }
61
65
 
62
66
  public:
@@ -154,6 +158,8 @@ private:
154
158
  std::string _label;
155
159
  std::shared_ptr<std::promise<std::shared_ptr<GPUDeviceLostInfo>>>
156
160
  m_lostPromise;
161
+ std::shared_ptr<std::shared_future<std::shared_ptr<GPUDeviceLostInfo>>>
162
+ m_lostSharedFuture;
157
163
  };
158
164
 
159
- } // namespace rnwgpu
165
+ } // namespace rnwgpu
@@ -65,9 +65,9 @@ static void convertEnumToJSUnion(wgpu::FeatureName inEnum,
65
65
  case wgpu::FeatureName::ImplicitDeviceSynchronization:
66
66
  *outUnion = "implicit-device-synchronization";
67
67
  break;
68
- case wgpu::FeatureName::SurfaceCapabilities:
69
- *outUnion = "surface-capabilities";
70
- break;
68
+ // case wgpu::FeatureName::SurfaceCapabilities:
69
+ // *outUnion = "surface-capabilities";
70
+ // break;
71
71
  case wgpu::FeatureName::TransientAttachments:
72
72
  *outUnion = "transient-attachments";
73
73
  break;
@@ -218,4 +218,4 @@ static void convertEnumToJSUnion(wgpu::FeatureName inEnum,
218
218
  }
219
219
  }
220
220
 
221
- } // namespace rnwgpu
221
+ } // namespace rnwgpu
@@ -18,7 +18,8 @@ GPUShaderModule::getCompilationInfo() {
18
18
  for (size_t i = 0; i < compilationInfo->messageCount; ++i) {
19
19
  const auto &wgpuMessage = compilationInfo->messages[i];
20
20
  GPUCompilationMessage message;
21
- message.message = wgpuMessage.message ? wgpuMessage.message : "";
21
+ message.message =
22
+ wgpuMessage.message.length ? wgpuMessage.message.data : "";
22
23
  message.type = wgpuMessage.type;
23
24
  message.lineNum = wgpuMessage.lineNum;
24
25
  message.linePos = wgpuMessage.linePos;
@@ -60,7 +60,9 @@ struct JSIConverter<std::shared_ptr<rnwgpu::GPUCanvasConfiguration>> {
60
60
  false);
61
61
  }
62
62
  if (value.hasProperty(runtime, "alphaMode")) {
63
- auto prop = value.getProperty(runtime, "alphaMode").asString(runtime).utf8(runtime);
63
+ auto prop = value.getProperty(runtime, "alphaMode")
64
+ .asString(runtime)
65
+ .utf8(runtime);
64
66
  if (prop == "premultiplied") {
65
67
  result->alphaMode = wgpu::CompositeAlphaMode::Premultiplied;
66
68
  }