react-native-webgpu 0.9.0 → 0.10.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.
- package/Package.swift +191 -0
- package/android/CMakeLists.txt +1 -2
- package/android/src/main/java/com/webgpu/WebGPUSurfaceView.java +10 -1
- package/android/src/main/java/com/webgpu/WebGPUTextureView.java +2 -2
- package/android/src/main/java/com/webgpu/WebGPUView.java +48 -16
- package/android/src/main/java/com/webgpu/WebGPUViewManager.java +21 -4
- package/cpp/jsi/JSICache.cpp +97 -0
- package/cpp/jsi/JSICache.h +90 -0
- package/cpp/jsi/NativeObject.h +24 -86
- package/cpp/rnwgpu/RNWebGPUManager.cpp +0 -3
- package/cpp/rnwgpu/SurfaceRegistry.h +153 -3
- package/cpp/rnwgpu/api/GPUAdapter.cpp +43 -1
- package/cpp/rnwgpu/api/GPUDevice.cpp +6 -1
- package/cpp/rnwgpu/api/GPUExternalTexture.cpp +3 -3
- package/cpp/rnwgpu/api/GPUFeatures.h +2 -1
- package/cpp/rnwgpu/api/GPUSharedTextureMemory.cpp +2 -2
- package/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h +11 -0
- package/cpp/webgpu/webgpu.h +63 -29
- package/cpp/webgpu/webgpu_cpp.h +415 -367
- package/cpp/webgpu/webgpu_cpp_print.h +21 -9
- package/cpp/webgpu/webgpu_enum_class_bitmasks.h +2 -1
- package/lib/commonjs/Canvas.js +8 -2
- package/lib/commonjs/Canvas.js.map +1 -1
- package/lib/commonjs/WebGPUViewNativeComponent.js.map +1 -1
- package/lib/commonjs/WebGPUViewNativeComponent.web.js +4 -2
- package/lib/commonjs/WebGPUViewNativeComponent.web.js.map +1 -1
- package/lib/commonjs/mock.js +3 -1
- package/lib/commonjs/mock.js.map +1 -1
- package/lib/module/Canvas.js +8 -2
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/WebGPUViewNativeComponent.js.map +1 -1
- package/lib/module/WebGPUViewNativeComponent.web.js +4 -2
- package/lib/module/WebGPUViewNativeComponent.web.js.map +1 -1
- package/lib/module/mock.js +3 -1
- package/lib/module/mock.js.map +1 -1
- package/lib/typescript/lib/commonjs/Canvas.d.ts +3 -2
- package/lib/typescript/lib/commonjs/Canvas.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/WebGPUViewNativeComponent.web.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/mock.d.ts +3 -2
- package/lib/typescript/lib/commonjs/mock.d.ts.map +1 -1
- package/lib/typescript/lib/module/Canvas.d.ts +3 -2
- package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
- package/lib/typescript/lib/module/WebGPUViewNativeComponent.web.d.ts.map +1 -1
- package/lib/typescript/lib/module/mock.d.ts +3 -2
- package/lib/typescript/lib/module/mock.d.ts.map +1 -1
- package/lib/typescript/src/Canvas.d.ts +24 -3
- package/lib/typescript/src/Canvas.d.ts.map +1 -1
- package/lib/typescript/src/WebGPUViewNativeComponent.d.ts +4 -2
- package/lib/typescript/src/WebGPUViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/WebGPUViewNativeComponent.web.d.ts +3 -1
- package/lib/typescript/src/WebGPUViewNativeComponent.web.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mock.d.ts +3 -7
- package/lib/typescript/src/mock.d.ts.map +1 -1
- package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
- package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
- package/libs/android/x86/libwebgpu_dawn.so +0 -0
- package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +12 -6
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/dawn_proc_table.h +329 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/DawnNative.h +367 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/NullBackend.h +39 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/OpenGLBackend.h +89 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/VulkanBackend.h +183 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/dawn_native_export.h +49 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu.h +5063 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu.ixx +358 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu_cpp.h +10401 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu_cpp_print.h +2868 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/wire/client/webgpu.h +369 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/wire/client/webgpu_cpp.h +10584 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/wire/client/webgpu_cpp_print.h +2868 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_cpp.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_cpp_chained_struct.h +57 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_cpp_print.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_enum_class_bitmasks.h +163 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_cpp.h +5932 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_cpp_chained_struct.h +54 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_cpp_print.h +2059 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_enum_class_bitmasks.h +163 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/dawn_proc_table.h +329 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/DawnNative.h +367 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/NullBackend.h +39 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/OpenGLBackend.h +89 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/VulkanBackend.h +183 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/dawn_native_export.h +49 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu.h +5063 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu.ixx +358 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu_cpp.h +10401 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu_cpp_print.h +2868 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/wire/client/webgpu.h +369 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/wire/client/webgpu_cpp.h +10584 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/wire/client/webgpu_cpp_print.h +2868 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_cpp.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_cpp_chained_struct.h +57 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_cpp_print.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_enum_class_bitmasks.h +163 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_cpp.h +5932 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_cpp_chained_struct.h +54 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_cpp_print.h +2059 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_enum_class_bitmasks.h +163 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/dawn_proc_table.h +329 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/DawnNative.h +367 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/NullBackend.h +39 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/OpenGLBackend.h +89 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/VulkanBackend.h +183 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/dawn_native_export.h +49 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu.h +5063 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu.ixx +358 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu_cpp.h +10401 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu_cpp_print.h +2868 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/wire/client/webgpu.h +369 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/wire/client/webgpu_cpp.h +10584 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/wire/client/webgpu_cpp_print.h +2868 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_cpp.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_cpp_chained_struct.h +57 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_cpp_print.h +33 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_enum_class_bitmasks.h +163 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_cpp.h +5932 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_cpp_chained_struct.h +54 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_cpp_print.h +2059 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_enum_class_bitmasks.h +163 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
- package/package.json +6 -4
- package/react-native-webgpu.podspec +33 -9
- package/src/Canvas.tsx +43 -4
- package/src/WebGPUViewNativeComponent.ts +10 -2
- package/src/WebGPUViewNativeComponent.web.ts +12 -3
- package/src/index.tsx +7 -0
- package/src/mock.ts +12 -9
- package/cpp/jsi/RuntimeAwareCache.cpp +0 -8
- package/cpp/jsi/RuntimeAwareCache.h +0 -133
- package/cpp/jsi/RuntimeLifecycleMonitor.cpp +0 -72
- package/cpp/jsi/RuntimeLifecycleMonitor.h +0 -32
package/cpp/jsi/NativeObject.h
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
#include <jsi/jsi.h>
|
|
9
9
|
#include <memory>
|
|
10
10
|
#include <mutex>
|
|
11
|
-
#include <optional>
|
|
12
11
|
#include <stdexcept>
|
|
13
12
|
#include <string>
|
|
14
13
|
#include <type_traits>
|
|
14
|
+
#include <typeindex>
|
|
15
15
|
#include <unordered_map>
|
|
16
16
|
#include <utility>
|
|
17
17
|
|
|
18
|
-
#include "
|
|
18
|
+
#include "JSICache.h"
|
|
19
19
|
#include "WGPULogger.h"
|
|
20
20
|
|
|
21
21
|
// Forward declare to avoid circular dependency
|
|
@@ -74,50 +74,6 @@ private:
|
|
|
74
74
|
std::unordered_map<std::string, InstallerFunc> _installers;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
/**
|
|
78
|
-
* Per-runtime cache entry for a prototype object.
|
|
79
|
-
* Uses std::optional<jsi::Object> so the prototype is stored directly
|
|
80
|
-
* without extra indirection.
|
|
81
|
-
*/
|
|
82
|
-
struct PrototypeCacheEntry {
|
|
83
|
-
std::optional<jsi::Object> prototype;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Wrapper for static RuntimeAwareCache that handles hot reload.
|
|
88
|
-
*
|
|
89
|
-
* When used with static storage (like prototype caches), the cache persists
|
|
90
|
-
* across hot reloads. But the JSI objects inside become invalid when the
|
|
91
|
-
* runtime is destroyed. This wrapper tracks which main-runtime generation the
|
|
92
|
-
* cache was created for and allocates a new cache when the native module is
|
|
93
|
-
* reinstalled (RNWebGPUManager construction bumps the generation).
|
|
94
|
-
*
|
|
95
|
-
* The generation is used instead of the runtime pointer on purpose: on an
|
|
96
|
-
* in-process runtime recreate (expo-updates reloadAsync, DevSettings.reload)
|
|
97
|
-
* Hermes frequently allocates the new runtime at the address of the freed
|
|
98
|
-
* one. A pointer comparison then sees "same runtime", keeps the stale cache,
|
|
99
|
-
* and installConstructor() ends up touching a jsi::Object owned by the dead
|
|
100
|
-
* runtime (SIGSEGV in jsi::Value::~Value, see issue #461).
|
|
101
|
-
*
|
|
102
|
-
* The old cache is intentionally leaked - we cannot safely destroy JSI
|
|
103
|
-
* objects after their runtime is gone.
|
|
104
|
-
*/
|
|
105
|
-
template <typename T> struct StaticRuntimeAwareCache {
|
|
106
|
-
RuntimeAwareCache<T> *cache = nullptr;
|
|
107
|
-
uint64_t cacheGeneration = 0;
|
|
108
|
-
|
|
109
|
-
RuntimeAwareCache<T> &get(jsi::Runtime & /*rt*/) {
|
|
110
|
-
auto generation = BaseRuntimeAwareCache::getMainJsRuntimeGeneration();
|
|
111
|
-
if (cache == nullptr || cacheGeneration != generation) {
|
|
112
|
-
// First use, or the main runtime was reinstalled (hot reload / OTA):
|
|
113
|
-
// allocate a fresh cache and leak the old one.
|
|
114
|
-
cache = new RuntimeAwareCache<T>();
|
|
115
|
-
cacheGeneration = generation;
|
|
116
|
-
}
|
|
117
|
-
return *cache;
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
|
|
121
77
|
/**
|
|
122
78
|
* BoxedWebGPUObject is a HostObject wrapper that holds a reference to ANY
|
|
123
79
|
* WebGPU NativeObject. This is used for Reanimated/Worklets serialization.
|
|
@@ -243,29 +199,20 @@ public:
|
|
|
243
199
|
using IsNativeObject = std::true_type;
|
|
244
200
|
|
|
245
201
|
/**
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* Uses StaticRuntimeAwareCache to properly handle runtime lifecycle
|
|
249
|
-
* and hot reload (where the main runtime is destroyed and recreated).
|
|
250
|
-
*
|
|
251
|
-
* Callers must hold getPrototypeCacheMutex(): the cache is reached
|
|
252
|
-
* concurrently from the main JS thread (create()) and from worklet
|
|
253
|
-
* runtime threads (BoxedWebGPUObject::unbox() -> installPrototype()).
|
|
202
|
+
* Key under which this class's prototype is stored in the per-runtime
|
|
203
|
+
* JSICache: the C++ type of Derived.
|
|
254
204
|
*/
|
|
255
|
-
static
|
|
256
|
-
|
|
257
|
-
static StaticRuntimeAwareCache<PrototypeCacheEntry> cache;
|
|
258
|
-
return cache.get(runtime);
|
|
205
|
+
static JSICache::PrototypeKey prototypeKey() {
|
|
206
|
+
return std::type_index(typeid(Derived));
|
|
259
207
|
}
|
|
260
208
|
|
|
261
209
|
/**
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
210
|
+
* Returns this class's prototype on `runtime`, or nullptr if it has not
|
|
211
|
+
* been installed there yet. The prototype is owned by the runtime (see
|
|
212
|
+
* JSICache), so the pointer is valid for as long as `runtime` is.
|
|
265
213
|
*/
|
|
266
|
-
static
|
|
267
|
-
|
|
268
|
-
return mutex;
|
|
214
|
+
static jsi::Object *getCachedPrototype(jsi::Runtime &runtime) {
|
|
215
|
+
return JSICache::get(runtime).getPrototype(prototypeKey());
|
|
269
216
|
}
|
|
270
217
|
|
|
271
218
|
/**
|
|
@@ -273,10 +220,8 @@ public:
|
|
|
273
220
|
* Called automatically by create(), but can be called manually.
|
|
274
221
|
*/
|
|
275
222
|
static void installPrototype(jsi::Runtime &runtime) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (entry.prototype.has_value()) {
|
|
279
|
-
return; // Already installed
|
|
223
|
+
if (getCachedPrototype(runtime) != nullptr) {
|
|
224
|
+
return; // Already installed on this runtime
|
|
280
225
|
}
|
|
281
226
|
|
|
282
227
|
// Create prototype object
|
|
@@ -348,8 +293,8 @@ public:
|
|
|
348
293
|
});
|
|
349
294
|
prototype.setProperty(runtime, "toJSON", toJSON);
|
|
350
295
|
|
|
351
|
-
//
|
|
352
|
-
|
|
296
|
+
// Hand the prototype to the runtime-owned cache
|
|
297
|
+
JSICache::get(runtime).setPrototype(prototypeKey(), std::move(prototype));
|
|
353
298
|
}
|
|
354
299
|
|
|
355
300
|
/**
|
|
@@ -373,9 +318,8 @@ public:
|
|
|
373
318
|
|
|
374
319
|
installPrototype(runtime);
|
|
375
320
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
if (!entry.prototype.has_value()) {
|
|
321
|
+
auto *prototype = getCachedPrototype(runtime);
|
|
322
|
+
if (prototype == nullptr) {
|
|
379
323
|
return;
|
|
380
324
|
}
|
|
381
325
|
|
|
@@ -391,10 +335,10 @@ public:
|
|
|
391
335
|
|
|
392
336
|
// Set the prototype property on the constructor
|
|
393
337
|
// This is what makes `instanceof` work
|
|
394
|
-
ctor.setProperty(runtime, "prototype", *
|
|
338
|
+
ctor.setProperty(runtime, "prototype", *prototype);
|
|
395
339
|
|
|
396
340
|
// Set constructor property on prototype pointing back to constructor
|
|
397
|
-
|
|
341
|
+
prototype->setProperty(runtime, "constructor", ctor);
|
|
398
342
|
|
|
399
343
|
// Install on global
|
|
400
344
|
runtime.global().setProperty(runtime, Derived::CLASS_NAME, std::move(ctor));
|
|
@@ -417,17 +361,11 @@ public:
|
|
|
417
361
|
obj.setNativeState(runtime, instance);
|
|
418
362
|
|
|
419
363
|
// Set prototype
|
|
420
|
-
{
|
|
421
|
-
|
|
422
|
-
auto
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
auto objectCtor =
|
|
426
|
-
runtime.global().getPropertyAsObject(runtime, "Object");
|
|
427
|
-
auto setPrototypeOf =
|
|
428
|
-
objectCtor.getPropertyAsFunction(runtime, "setPrototypeOf");
|
|
429
|
-
setPrototypeOf.call(runtime, obj, *entry.prototype);
|
|
430
|
-
}
|
|
364
|
+
if (auto *prototype = getCachedPrototype(runtime)) {
|
|
365
|
+
auto objectCtor = runtime.global().getPropertyAsObject(runtime, "Object");
|
|
366
|
+
auto setPrototypeOf =
|
|
367
|
+
objectCtor.getPropertyAsFunction(runtime, "setPrototypeOf");
|
|
368
|
+
setPrototypeOf.call(runtime, obj, *prototype);
|
|
431
369
|
}
|
|
432
370
|
|
|
433
371
|
// Set memory pressure hint for GC
|
|
@@ -61,9 +61,6 @@ RNWebGPUManager::RNWebGPUManager(
|
|
|
61
61
|
: _jsRuntime(jsRuntime), _jsCallInvoker(jsCallInvoker),
|
|
62
62
|
_platformContext(platformContext) {
|
|
63
63
|
|
|
64
|
-
// Register main runtime for RuntimeAwareCache
|
|
65
|
-
BaseRuntimeAwareCache::setMainJsRuntime(_jsRuntime);
|
|
66
|
-
|
|
67
64
|
// Register the main runtime + its CallInvoker so spontaneous events
|
|
68
65
|
// (device.lost / uncapturederror) on main-runtime devices can be delivered to
|
|
69
66
|
// the JS thread without the ProcessEvents pump. Worklet-runtime devices have
|
|
@@ -81,6 +81,10 @@ public:
|
|
|
81
81
|
~SurfaceInfo() {
|
|
82
82
|
// Drop the Dawn objects before releasing the native surfaces they borrow.
|
|
83
83
|
_surface = nullptr;
|
|
84
|
+
#if defined(__ANDROID__)
|
|
85
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
86
|
+
_surfaceDevice = nullptr;
|
|
87
|
+
#endif
|
|
84
88
|
_pendingSurface = nullptr;
|
|
85
89
|
_texture = nullptr;
|
|
86
90
|
if (_pendingReleaser && _pendingNativeSurface) {
|
|
@@ -170,6 +174,10 @@ public:
|
|
|
170
174
|
replacedSurface = _nativeSurface;
|
|
171
175
|
replacedReleaser = std::move(_releaser);
|
|
172
176
|
_surface = std::move(_pendingSurface);
|
|
177
|
+
#if defined(__ANDROID__)
|
|
178
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
179
|
+
_surfaceDevice = nullptr;
|
|
180
|
+
#endif
|
|
173
181
|
_nativeSurface = _pendingNativeSurface;
|
|
174
182
|
_releaser = std::move(_pendingReleaser);
|
|
175
183
|
_hasPendingAttach = false;
|
|
@@ -187,7 +195,7 @@ public:
|
|
|
187
195
|
if (blit) {
|
|
188
196
|
config.usage |= wgpu::TextureUsage::CopyDst;
|
|
189
197
|
}
|
|
190
|
-
|
|
198
|
+
configureSurfaceLocked(config);
|
|
191
199
|
#ifdef __APPLE__
|
|
192
200
|
applyCAMetalLayerColorSpace(_nativeSurface, _config.format);
|
|
193
201
|
#endif
|
|
@@ -275,6 +283,38 @@ public:
|
|
|
275
283
|
return _config.device != nullptr;
|
|
276
284
|
}
|
|
277
285
|
|
|
286
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
287
|
+
// Called right before `device` is destroyed. If the Dawn surface holds a
|
|
288
|
+
// swapchain for that device, drop the surface now, while the device is
|
|
289
|
+
// still alive, and recreate an unconfigured one for the same native window
|
|
290
|
+
// so a later configure() with another device still renders on screen.
|
|
291
|
+
//
|
|
292
|
+
// Why: on Vulkan, tearing a swapchain down (SwapChain::DetachFromSurfaceImpl)
|
|
293
|
+
// goes through the device's FencedDeleter. Dawn only tears it down when the
|
|
294
|
+
// surface is reconfigured or destroyed, and Unconfigure() is not enough (it
|
|
295
|
+
// parks the swapchain as "recycled" for the next Configure). So when the
|
|
296
|
+
// native view is dropped after device.destroy(), ~Surface dereferences the
|
|
297
|
+
// dead device (SIGSEGV, fault addr 0x20). Android only: Metal's detach does
|
|
298
|
+
// not touch the device, and this must not change behaviour there.
|
|
299
|
+
//
|
|
300
|
+
// Remove once the pinned Dawn contains the upstream fix; the check in
|
|
301
|
+
// scripts/install-dawn.ts fails the install when the Dawn pin changes so
|
|
302
|
+
// that decision is not forgotten.
|
|
303
|
+
void releaseSurfaceForDevice(const wgpu::Device &device) {
|
|
304
|
+
#if defined(__ANDROID__)
|
|
305
|
+
std::unique_lock<std::shared_mutex> lock(_mutex);
|
|
306
|
+
if (!_surface || !_surfaceDevice || _surfaceDevice.Get() != device.Get()) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
// Left unconfigured: _config still names the destroyed device, and
|
|
310
|
+
// configuring against it would only raise a validation error. The next
|
|
311
|
+
// configure() from JS (or a surface re-attach) configures it.
|
|
312
|
+
recreateSurfaceLocked();
|
|
313
|
+
#else
|
|
314
|
+
(void)device;
|
|
315
|
+
#endif
|
|
316
|
+
}
|
|
317
|
+
|
|
278
318
|
// True while a native view owns a surface for this context (attached or
|
|
279
319
|
// pending adoption). Used to decide which side retires the registry entry:
|
|
280
320
|
// the native view's teardown when a surface exists, the JS Canvas cleanup
|
|
@@ -384,6 +424,10 @@ private:
|
|
|
384
424
|
_texture = createOffscreenTextureLocked();
|
|
385
425
|
}
|
|
386
426
|
_surface = nullptr;
|
|
427
|
+
#if defined(__ANDROID__)
|
|
428
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
429
|
+
_surfaceDevice = nullptr;
|
|
430
|
+
#endif
|
|
387
431
|
// The in-flight frame (if any) rendered into the destroyed surface;
|
|
388
432
|
// presentFrame() must not present it.
|
|
389
433
|
_acquiredFromSurface = false;
|
|
@@ -432,7 +476,12 @@ private:
|
|
|
432
476
|
wgpu::SurfaceGetCurrentTextureStatus::Error) {
|
|
433
477
|
return nullptr;
|
|
434
478
|
}
|
|
435
|
-
|
|
479
|
+
configureSurfaceLocked(_config);
|
|
480
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE: the reconfigure
|
|
481
|
+
// may have replaced the surface and failed to create a new one.
|
|
482
|
+
if (!_surface) {
|
|
483
|
+
return nullptr;
|
|
484
|
+
}
|
|
436
485
|
_surface.GetCurrentTexture(&surfaceTexture);
|
|
437
486
|
if (!isAcquireSuccess(surfaceTexture)) {
|
|
438
487
|
return nullptr;
|
|
@@ -480,7 +529,7 @@ private:
|
|
|
480
529
|
|
|
481
530
|
void _configureLocked() {
|
|
482
531
|
if (_surface) {
|
|
483
|
-
|
|
532
|
+
configureSurfaceLocked(_config);
|
|
484
533
|
#ifdef __APPLE__
|
|
485
534
|
applyCAMetalLayerColorSpace(_nativeSurface, _config.format);
|
|
486
535
|
#endif
|
|
@@ -489,7 +538,67 @@ private:
|
|
|
489
538
|
}
|
|
490
539
|
}
|
|
491
540
|
|
|
541
|
+
// Every Surface::Configure goes through here. Once the
|
|
542
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE lines are gone, this
|
|
543
|
+
// is a plain wrapper around _surface.Configure.
|
|
544
|
+
void configureSurfaceLocked(const wgpu::SurfaceConfiguration &config) {
|
|
545
|
+
#if defined(__ANDROID__)
|
|
546
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
547
|
+
// Vulkan refuses to switch a surface to another device and keeps the old
|
|
548
|
+
// swapchain attached, so a device change (device swap, recovery after a
|
|
549
|
+
// lost device, a re-run effect) is done with a fresh surface. This also
|
|
550
|
+
// tears the old swapchain down while its device is still alive.
|
|
551
|
+
if (_surfaceDevice && _surfaceDevice.Get() != config.device.Get()) {
|
|
552
|
+
recreateSurfaceLocked();
|
|
553
|
+
if (!_surface) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
#endif
|
|
558
|
+
_surface.Configure(&config);
|
|
559
|
+
#if defined(__ANDROID__)
|
|
560
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
561
|
+
_surfaceDevice = config.device;
|
|
562
|
+
#endif
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
#if defined(__ANDROID__)
|
|
566
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
567
|
+
// Replace _surface with a new, unconfigured surface for the same native
|
|
568
|
+
// window. Dropping the old one runs ~Surface, which detaches both the
|
|
569
|
+
// active and the recycled swapchain against their still-alive device.
|
|
570
|
+
void recreateSurfaceLocked() {
|
|
571
|
+
_surface = nullptr;
|
|
572
|
+
_surfaceDevice = nullptr;
|
|
573
|
+
// A frame acquired from the old surface can no longer be presented.
|
|
574
|
+
_acquiredFromSurface = false;
|
|
575
|
+
_frameEpoch++;
|
|
576
|
+
if (_nativeSurface) {
|
|
577
|
+
wgpu::SurfaceSourceAndroidNativeWindow source;
|
|
578
|
+
source.window = _nativeSurface;
|
|
579
|
+
wgpu::SurfaceDescriptor descriptor;
|
|
580
|
+
descriptor.nextInChain = &source;
|
|
581
|
+
_surface = _gpu.CreateSurface(&descriptor);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
#endif
|
|
585
|
+
|
|
492
586
|
mutable std::shared_mutex _mutex;
|
|
587
|
+
#if defined(__ANDROID__)
|
|
588
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
589
|
+
// The device _surface was last configured with. Dawn keeps a swapchain for
|
|
590
|
+
// that device inside the surface even after Unconfigure() (it is recycled
|
|
591
|
+
// for the next Configure), so this outlives _config.device on purpose and
|
|
592
|
+
// is only reset when _surface itself is dropped or replaced. Owning: Dawn
|
|
593
|
+
// destroys a device when its last external reference goes away, which
|
|
594
|
+
// would leave the swapchain with a dead device just like an explicit
|
|
595
|
+
// destroy(). Declared before _surface so it is released after it.
|
|
596
|
+
//
|
|
597
|
+
// Android only: this is an extra owning reference to the device, and on
|
|
598
|
+
// Metal (where the detach never touches the device) it would keep a
|
|
599
|
+
// device alive past its last JS reference for no reason.
|
|
600
|
+
wgpu::Device _surfaceDevice = nullptr;
|
|
601
|
+
#endif
|
|
493
602
|
// Attached on-screen surface (null while offscreen).
|
|
494
603
|
void *_nativeSurface = nullptr;
|
|
495
604
|
wgpu::Surface _surface = nullptr;
|
|
@@ -579,6 +688,30 @@ public:
|
|
|
579
688
|
_registry.erase(it);
|
|
580
689
|
}
|
|
581
690
|
|
|
691
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
692
|
+
// See SurfaceInfo::releaseSurfaceForDevice. Lock order is registry ->
|
|
693
|
+
// SurfaceInfo, matching every other path.
|
|
694
|
+
void releaseSurfacesForDevice(const wgpu::Device &device) {
|
|
695
|
+
std::vector<std::shared_ptr<SurfaceInfo>> infos;
|
|
696
|
+
{
|
|
697
|
+
// Walking _allSurfaces, not _registry: a GPUCanvasContext keeps its own
|
|
698
|
+
// shared_ptr, so an entry erased by clear() (dev reload) or by
|
|
699
|
+
// removeSurfaceInfo() can still be alive and still hold a swapchain for
|
|
700
|
+
// this device.
|
|
701
|
+
std::unique_lock<std::shared_mutex> lock(_mutex);
|
|
702
|
+
pruneAllSurfacesLocked();
|
|
703
|
+
infos.reserve(_allSurfaces.size());
|
|
704
|
+
for (auto &weak : _allSurfaces) {
|
|
705
|
+
if (auto info = weak.lock()) {
|
|
706
|
+
infos.push_back(std::move(info));
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
for (auto &info : infos) {
|
|
711
|
+
info->releaseSurfaceForDevice(device);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
582
715
|
// Drops all entries. Called when the RN instance tears down (dev reload):
|
|
583
716
|
// JS context ids restart from scratch, so surviving entries would alias new
|
|
584
717
|
// canvases onto dead surfaces.
|
|
@@ -600,11 +733,28 @@ private:
|
|
|
600
733
|
}
|
|
601
734
|
auto info = std::make_shared<SurfaceInfo>(gpu, width, height);
|
|
602
735
|
_registry[id] = info;
|
|
736
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
737
|
+
pruneAllSurfacesLocked();
|
|
738
|
+
_allSurfaces.push_back(info);
|
|
603
739
|
return info;
|
|
604
740
|
}
|
|
605
741
|
|
|
742
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
743
|
+
void pruneAllSurfacesLocked() {
|
|
744
|
+
_allSurfaces.erase(
|
|
745
|
+
std::remove_if(_allSurfaces.begin(), _allSurfaces.end(),
|
|
746
|
+
[](const std::weak_ptr<SurfaceInfo> &weak) {
|
|
747
|
+
return weak.expired();
|
|
748
|
+
}),
|
|
749
|
+
_allSurfaces.end());
|
|
750
|
+
}
|
|
751
|
+
|
|
606
752
|
mutable std::shared_mutex _mutex;
|
|
607
753
|
std::unordered_map<int, std::shared_ptr<SurfaceInfo>> _registry;
|
|
754
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
755
|
+
// Every live SurfaceInfo, including the ones no longer in _registry.
|
|
756
|
+
// Non-owning; pruned on insert and on every device destroy.
|
|
757
|
+
std::vector<std::weak_ptr<SurfaceInfo>> _allSurfaces;
|
|
608
758
|
};
|
|
609
759
|
|
|
610
760
|
} // namespace rnwgpu
|
|
@@ -66,6 +66,48 @@ async::AsyncTaskHandle GPUAdapter::requestDevice(
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
// Request Dawn's ImplicitDeviceSynchronization feature by default. Dawn's
|
|
70
|
+
// native API is not thread-safe without it, and the react-native-wgpu model
|
|
71
|
+
// is "create the device on the JS thread, render from a worklet runtime",
|
|
72
|
+
// which uses one device from several threads. The feature wraps device and
|
|
73
|
+
// child-object entry points in a per-device mutex (command *encoding* stays
|
|
74
|
+
// unsynchronized: never share a GPUCommandEncoder across threads). Dawn
|
|
75
|
+
// exposes the feature on every physical device, but keep the support check
|
|
76
|
+
// so a hypothetical adapter without it still vends a device. Callers can opt
|
|
77
|
+
// out with `implicitDeviceSynchronization: false` on the device descriptor
|
|
78
|
+
// to skip the (small) per-call locking overhead when the device is only ever
|
|
79
|
+
// used from a single thread.
|
|
80
|
+
{
|
|
81
|
+
const bool optedOut = descriptor.has_value() &&
|
|
82
|
+
descriptor.value()->implicitDeviceSynchronization ==
|
|
83
|
+
std::optional<bool>(false);
|
|
84
|
+
if (!optedOut) {
|
|
85
|
+
wgpu::SupportedFeatures supported;
|
|
86
|
+
_instance.GetFeatures(&supported);
|
|
87
|
+
const bool isSupported =
|
|
88
|
+
std::find(supported.features,
|
|
89
|
+
supported.features + supported.featureCount,
|
|
90
|
+
wgpu::FeatureName::ImplicitDeviceSynchronization) !=
|
|
91
|
+
supported.features + supported.featureCount;
|
|
92
|
+
if (isSupported) {
|
|
93
|
+
if (!descriptor.has_value()) {
|
|
94
|
+
descriptor = std::make_shared<GPUDeviceDescriptor>();
|
|
95
|
+
}
|
|
96
|
+
auto &desc = descriptor.value();
|
|
97
|
+
if (!desc->requiredFeatures.has_value()) {
|
|
98
|
+
desc->requiredFeatures = std::vector<wgpu::FeatureName>{};
|
|
99
|
+
}
|
|
100
|
+
auto &features = desc->requiredFeatures.value();
|
|
101
|
+
if (std::find(features.begin(), features.end(),
|
|
102
|
+
wgpu::FeatureName::ImplicitDeviceSynchronization) ==
|
|
103
|
+
features.end()) {
|
|
104
|
+
features.push_back(
|
|
105
|
+
wgpu::FeatureName::ImplicitDeviceSynchronization);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
69
111
|
wgpu::DeviceDescriptor aDescriptor;
|
|
70
112
|
Convertor conv;
|
|
71
113
|
if (!conv(aDescriptor, descriptor)) {
|
|
@@ -285,7 +327,7 @@ std::unordered_set<std::string> GPUAdapter::getFeatures() {
|
|
|
285
327
|
|
|
286
328
|
std::shared_ptr<GPUSupportedLimits> GPUAdapter::getLimits() {
|
|
287
329
|
wgpu::Limits limits{};
|
|
288
|
-
if (
|
|
330
|
+
if (_instance.GetLimits(&limits) != wgpu::Status::Success) {
|
|
289
331
|
throw std::runtime_error("Failed to get limits");
|
|
290
332
|
}
|
|
291
333
|
return std::make_shared<GPUSupportedLimits>(limits);
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
#include "GPUOutOfMemoryError.h"
|
|
17
17
|
#include "GPUValidationError.h"
|
|
18
18
|
#include "RnFeatures.h"
|
|
19
|
+
#include "SurfaceRegistry.h"
|
|
19
20
|
|
|
20
21
|
namespace rnwgpu {
|
|
21
22
|
|
|
@@ -124,7 +125,7 @@ GPUDevice::createBuffer(std::shared_ptr<GPUBufferDescriptor> descriptor) {
|
|
|
124
125
|
|
|
125
126
|
std::shared_ptr<GPUSupportedLimits> GPUDevice::getLimits() {
|
|
126
127
|
wgpu::Limits limits{};
|
|
127
|
-
if (
|
|
128
|
+
if (_instance.GetLimits(&limits) != wgpu::Status::Success) {
|
|
128
129
|
throw std::runtime_error("failed to get device limits");
|
|
129
130
|
}
|
|
130
131
|
return std::make_shared<GPUSupportedLimits>(limits);
|
|
@@ -149,6 +150,10 @@ std::shared_ptr<GPUCommandEncoder> GPUDevice::createCommandEncoder(
|
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
void GPUDevice::destroy() {
|
|
153
|
+
// DAWN_WORKAROUND_DEVICE_DESTROY_BEFORE_SURFACE_RELEASE
|
|
154
|
+
// Any canvas surface holding a swapchain for this device must let go of it
|
|
155
|
+
// while the device is alive (see SurfaceInfo::releaseSurfaceForDevice).
|
|
156
|
+
SurfaceRegistry::getInstance().releaseSurfacesForDevice(_instance);
|
|
152
157
|
_instance.Destroy();
|
|
153
158
|
notifyDeviceLost(wgpu::DeviceLostReason::Destroyed, "device was destroyed");
|
|
154
159
|
}
|
|
@@ -190,7 +190,7 @@ std::shared_ptr<GPUExternalTexture> GPUExternalTexture::Create(
|
|
|
190
190
|
wgpu::SharedTextureMemoryBeginAccessDescriptor begin{};
|
|
191
191
|
begin.initialized = true;
|
|
192
192
|
begin.concurrentRead = false;
|
|
193
|
-
if (
|
|
193
|
+
if (memory.BeginAccess(texture, &begin) != wgpu::Status::Success) {
|
|
194
194
|
throw std::runtime_error(
|
|
195
195
|
"GPUExternalTexture::Create(): BeginAccess failed");
|
|
196
196
|
}
|
|
@@ -289,7 +289,7 @@ std::shared_ptr<GPUExternalTexture> GPUExternalTexture::Create(
|
|
|
289
289
|
begin.concurrentRead = false;
|
|
290
290
|
wgpu::SharedTextureMemoryVkImageLayoutBeginState beginLayout{};
|
|
291
291
|
begin.nextInChain = &beginLayout;
|
|
292
|
-
if (
|
|
292
|
+
if (memory.BeginAccess(texture, &begin) != wgpu::Status::Success) {
|
|
293
293
|
throw std::runtime_error(
|
|
294
294
|
"GPUExternalTexture::Create(): BeginAccess failed");
|
|
295
295
|
}
|
|
@@ -310,7 +310,7 @@ std::shared_ptr<GPUExternalTexture> GPUExternalTexture::Create(
|
|
|
310
310
|
wgpu::SharedTextureMemoryAHardwareBufferProperties ahbProps{};
|
|
311
311
|
wgpu::SharedTextureMemoryProperties props{};
|
|
312
312
|
props.nextInChain = &ahbProps;
|
|
313
|
-
if (memory.GetProperties(&props)) {
|
|
313
|
+
if (memory.GetProperties(&props) == wgpu::Status::Success) {
|
|
314
314
|
yuvToRgbMatrix = makeYuvToRgbMatrix(ahbProps.yCbCrInfo.vkYCbCrModel,
|
|
315
315
|
ahbProps.yCbCrInfo.vkYCbCrRange);
|
|
316
316
|
} else {
|
|
@@ -115,7 +115,8 @@ namespace rnwgpu {
|
|
|
115
115
|
V(RenderPassRenderArea, "render-pass-render-area") \
|
|
116
116
|
V(AdapterPropertiesDrm, "adapter-properties-drm") \
|
|
117
117
|
V(TextureCompressionUnaligned, "texture-compression-unaligned") \
|
|
118
|
-
V(DawnAllowUndefinedLoadStoreOp, "dawn-allow-undefined-load-store-op")
|
|
118
|
+
V(DawnAllowUndefinedLoadStoreOp, "dawn-allow-undefined-load-store-op") \
|
|
119
|
+
V(BufferMapWriteExtendedUsages, "buffer-map-write-extended-usages")
|
|
119
120
|
|
|
120
121
|
static void convertEnumToJSUnion(wgpu::FeatureName inEnum,
|
|
121
122
|
std::string *outUnion) {
|
|
@@ -75,7 +75,7 @@ void GPUSharedTextureMemory::beginAccess(
|
|
|
75
75
|
#endif
|
|
76
76
|
|
|
77
77
|
auto status = _instance.BeginAccess(texture->get(), &desc);
|
|
78
|
-
if (
|
|
78
|
+
if (status != wgpu::Status::Success) {
|
|
79
79
|
throw std::runtime_error("GPUSharedTextureMemory::beginAccess() failed");
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -101,7 +101,7 @@ jsi::Value GPUSharedTextureMemory::endAccess(jsi::Runtime &runtime,
|
|
|
101
101
|
#endif
|
|
102
102
|
|
|
103
103
|
auto status = _instance.EndAccess(texture->get(), &state);
|
|
104
|
-
if (
|
|
104
|
+
if (status != wgpu::Status::Success) {
|
|
105
105
|
throw jsi::JSError(runtime, "GPUSharedTextureMemory::endAccess() failed");
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -29,6 +29,11 @@ struct GPUDeviceDescriptor {
|
|
|
29
29
|
// Non-standard Dawn-only device toggles, chained onto the wgpu::Device
|
|
30
30
|
// descriptor in GPUAdapter::requestDevice.
|
|
31
31
|
std::optional<std::shared_ptr<GPUDawnTogglesDescriptor>> dawnToggles;
|
|
32
|
+
// Non-standard RN extension. Dawn's ImplicitDeviceSynchronization feature is
|
|
33
|
+
// requested by default so a single device can be used from several runtimes
|
|
34
|
+
// (JS thread + worklet runtimes). Set to false to opt out and get an
|
|
35
|
+
// unsynchronized (single-thread only) device.
|
|
36
|
+
std::optional<bool> implicitDeviceSynchronization;
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
} // namespace rnwgpu
|
|
@@ -108,6 +113,12 @@ template <> struct JSIConverter<std::shared_ptr<rnwgpu::GPUDeviceDescriptor>> {
|
|
|
108
113
|
std::optional<std::shared_ptr<GPUDawnTogglesDescriptor>>>::fromJSI(
|
|
109
114
|
runtime, prop, false);
|
|
110
115
|
}
|
|
116
|
+
if (value.hasProperty(runtime, "implicitDeviceSynchronization")) {
|
|
117
|
+
auto prop =
|
|
118
|
+
value.getProperty(runtime, "implicitDeviceSynchronization");
|
|
119
|
+
result->implicitDeviceSynchronization =
|
|
120
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, prop, false);
|
|
121
|
+
}
|
|
111
122
|
}
|
|
112
123
|
|
|
113
124
|
return result;
|