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.
Files changed (140) hide show
  1. package/Package.swift +191 -0
  2. package/android/CMakeLists.txt +1 -2
  3. package/android/src/main/java/com/webgpu/WebGPUSurfaceView.java +10 -1
  4. package/android/src/main/java/com/webgpu/WebGPUTextureView.java +2 -2
  5. package/android/src/main/java/com/webgpu/WebGPUView.java +48 -16
  6. package/android/src/main/java/com/webgpu/WebGPUViewManager.java +21 -4
  7. package/cpp/jsi/JSICache.cpp +97 -0
  8. package/cpp/jsi/JSICache.h +90 -0
  9. package/cpp/jsi/NativeObject.h +24 -86
  10. package/cpp/rnwgpu/RNWebGPUManager.cpp +0 -3
  11. package/cpp/rnwgpu/SurfaceRegistry.h +153 -3
  12. package/cpp/rnwgpu/api/GPUAdapter.cpp +43 -1
  13. package/cpp/rnwgpu/api/GPUDevice.cpp +6 -1
  14. package/cpp/rnwgpu/api/GPUExternalTexture.cpp +3 -3
  15. package/cpp/rnwgpu/api/GPUFeatures.h +2 -1
  16. package/cpp/rnwgpu/api/GPUSharedTextureMemory.cpp +2 -2
  17. package/cpp/rnwgpu/api/descriptors/GPUDeviceDescriptor.h +11 -0
  18. package/cpp/webgpu/webgpu.h +63 -29
  19. package/cpp/webgpu/webgpu_cpp.h +415 -367
  20. package/cpp/webgpu/webgpu_cpp_print.h +21 -9
  21. package/cpp/webgpu/webgpu_enum_class_bitmasks.h +2 -1
  22. package/lib/commonjs/Canvas.js +8 -2
  23. package/lib/commonjs/Canvas.js.map +1 -1
  24. package/lib/commonjs/WebGPUViewNativeComponent.js.map +1 -1
  25. package/lib/commonjs/WebGPUViewNativeComponent.web.js +4 -2
  26. package/lib/commonjs/WebGPUViewNativeComponent.web.js.map +1 -1
  27. package/lib/commonjs/mock.js +3 -1
  28. package/lib/commonjs/mock.js.map +1 -1
  29. package/lib/module/Canvas.js +8 -2
  30. package/lib/module/Canvas.js.map +1 -1
  31. package/lib/module/WebGPUViewNativeComponent.js.map +1 -1
  32. package/lib/module/WebGPUViewNativeComponent.web.js +4 -2
  33. package/lib/module/WebGPUViewNativeComponent.web.js.map +1 -1
  34. package/lib/module/mock.js +3 -1
  35. package/lib/module/mock.js.map +1 -1
  36. package/lib/typescript/lib/commonjs/Canvas.d.ts +3 -2
  37. package/lib/typescript/lib/commonjs/Canvas.d.ts.map +1 -1
  38. package/lib/typescript/lib/commonjs/WebGPUViewNativeComponent.web.d.ts.map +1 -1
  39. package/lib/typescript/lib/commonjs/mock.d.ts +3 -2
  40. package/lib/typescript/lib/commonjs/mock.d.ts.map +1 -1
  41. package/lib/typescript/lib/module/Canvas.d.ts +3 -2
  42. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  43. package/lib/typescript/lib/module/WebGPUViewNativeComponent.web.d.ts.map +1 -1
  44. package/lib/typescript/lib/module/mock.d.ts +3 -2
  45. package/lib/typescript/lib/module/mock.d.ts.map +1 -1
  46. package/lib/typescript/src/Canvas.d.ts +24 -3
  47. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  48. package/lib/typescript/src/WebGPUViewNativeComponent.d.ts +4 -2
  49. package/lib/typescript/src/WebGPUViewNativeComponent.d.ts.map +1 -1
  50. package/lib/typescript/src/WebGPUViewNativeComponent.web.d.ts +3 -1
  51. package/lib/typescript/src/WebGPUViewNativeComponent.web.d.ts.map +1 -1
  52. package/lib/typescript/src/index.d.ts +1 -0
  53. package/lib/typescript/src/index.d.ts.map +1 -1
  54. package/lib/typescript/src/mock.d.ts +3 -7
  55. package/lib/typescript/src/mock.d.ts.map +1 -1
  56. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  57. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  58. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  59. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  60. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +12 -6
  61. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/dawn_proc_table.h +329 -0
  62. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/DawnNative.h +367 -0
  63. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/NullBackend.h +39 -0
  64. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/OpenGLBackend.h +89 -0
  65. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/VulkanBackend.h +183 -0
  66. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/native/dawn_native_export.h +49 -0
  67. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu.h +5063 -0
  68. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu.ixx +358 -0
  69. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu_cpp.h +10401 -0
  70. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/webgpu_cpp_print.h +2868 -0
  71. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/wire/client/webgpu.h +369 -0
  72. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/wire/client/webgpu_cpp.h +10584 -0
  73. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/dawn/wire/client/webgpu_cpp_print.h +2868 -0
  74. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu.h +33 -0
  75. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_cpp.h +33 -0
  76. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_cpp_chained_struct.h +57 -0
  77. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_cpp_print.h +33 -0
  78. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu/webgpu_enum_class_bitmasks.h +163 -0
  79. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_cpp.h +5932 -0
  80. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_cpp_chained_struct.h +54 -0
  81. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_cpp_print.h +2059 -0
  82. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/Headers/webgpu_upstream/webgpu/webgpu_enum_class_bitmasks.h +163 -0
  83. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  84. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/dawn_proc_table.h +329 -0
  85. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/DawnNative.h +367 -0
  86. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/NullBackend.h +39 -0
  87. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/OpenGLBackend.h +89 -0
  88. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/VulkanBackend.h +183 -0
  89. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/native/dawn_native_export.h +49 -0
  90. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu.h +5063 -0
  91. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu.ixx +358 -0
  92. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu_cpp.h +10401 -0
  93. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/webgpu_cpp_print.h +2868 -0
  94. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/wire/client/webgpu.h +369 -0
  95. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/wire/client/webgpu_cpp.h +10584 -0
  96. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/dawn/wire/client/webgpu_cpp_print.h +2868 -0
  97. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu.h +33 -0
  98. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_cpp.h +33 -0
  99. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_cpp_chained_struct.h +57 -0
  100. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_cpp_print.h +33 -0
  101. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu/webgpu_enum_class_bitmasks.h +163 -0
  102. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_cpp.h +5932 -0
  103. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_cpp_chained_struct.h +54 -0
  104. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_cpp_print.h +2059 -0
  105. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/Headers/webgpu_upstream/webgpu/webgpu_enum_class_bitmasks.h +163 -0
  106. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  107. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/dawn_proc_table.h +329 -0
  108. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/DawnNative.h +367 -0
  109. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/NullBackend.h +39 -0
  110. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/OpenGLBackend.h +89 -0
  111. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/VulkanBackend.h +183 -0
  112. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/native/dawn_native_export.h +49 -0
  113. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu.h +5063 -0
  114. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu.ixx +358 -0
  115. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu_cpp.h +10401 -0
  116. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/webgpu_cpp_print.h +2868 -0
  117. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/wire/client/webgpu.h +369 -0
  118. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/wire/client/webgpu_cpp.h +10584 -0
  119. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/dawn/wire/client/webgpu_cpp_print.h +2868 -0
  120. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu.h +33 -0
  121. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_cpp.h +33 -0
  122. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_cpp_chained_struct.h +57 -0
  123. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_cpp_print.h +33 -0
  124. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu/webgpu_enum_class_bitmasks.h +163 -0
  125. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_cpp.h +5932 -0
  126. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_cpp_chained_struct.h +54 -0
  127. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_cpp_print.h +2059 -0
  128. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/Headers/webgpu_upstream/webgpu/webgpu_enum_class_bitmasks.h +163 -0
  129. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  130. package/package.json +6 -4
  131. package/react-native-webgpu.podspec +33 -9
  132. package/src/Canvas.tsx +43 -4
  133. package/src/WebGPUViewNativeComponent.ts +10 -2
  134. package/src/WebGPUViewNativeComponent.web.ts +12 -3
  135. package/src/index.tsx +7 -0
  136. package/src/mock.ts +12 -9
  137. package/cpp/jsi/RuntimeAwareCache.cpp +0 -8
  138. package/cpp/jsi/RuntimeAwareCache.h +0 -133
  139. package/cpp/jsi/RuntimeLifecycleMonitor.cpp +0 -72
  140. package/cpp/jsi/RuntimeLifecycleMonitor.h +0 -32
package/Package.swift ADDED
@@ -0,0 +1,191 @@
1
+ // swift-tools-version: 5.9
2
+ // Generated by scripts/generate-package-swift.ts — do not edit by hand.
3
+ // Re-run that script after a new Dawn release to update the URL/checksum below.
4
+ import Foundation
5
+ import PackageDescription
6
+
7
+ // Integration model: a local Swift package next to a CocoaPods install.
8
+ //
9
+ // This manifest targets React Native 0.81+ (the package's peer range), where
10
+ // React Native's own headers and the RNWgpuViewSpec codegen output only exist
11
+ // inside the consuming app's CocoaPods install. Add this package as a local
12
+ // Swift Package dependency in place of the react-native-webgpu pod (export
13
+ // RNWGPU_USE_SPM=1 for `pod install`) and keep running `pod install` for
14
+ // everything else. The header search paths below point into that Pods
15
+ // directory. They can only be expressed as `unsafeFlags`, and SwiftPM rejects
16
+ // unsafeFlags in anything but a path dependency, so this package can only be
17
+ // consumed locally, never by URL and version.
18
+ //
19
+ // React Native 0.87 added SwiftPM autolinking. There, a dependency shipping
20
+ // its own Package.swift is treated as self-managed and referenced directly,
21
+ // and it consumes React Native's headers as SwiftPM products (ReactHeaders,
22
+ // ReactNativeHeaders, ReactNativeDependenciesHeaders, plus ReactAppHeaders
23
+ // from the app's generated codegen package) with no CocoaPods at all. This
24
+ // manifest does not implement that model yet: on a 0.87+ app that has opted
25
+ // into SwiftPM autolinking it is picked up as self-managed but cannot find
26
+ // React Native's headers. Keep CocoaPods for React Native on those apps.
27
+
28
+ // Absolute location of this package. Xcode may hand over a symlink (React
29
+ // Native 0.87's autolinker does), so resolve it before deriving sibling paths.
30
+ let packageRoot = URL(fileURLWithPath: Context.packageDirectory)
31
+ .resolvingSymlinksInPath().path
32
+ let sibling = { (relative: String) -> String in
33
+ URL(fileURLWithPath: "\(packageRoot)/\(relative)").standardized.path
34
+ }
35
+
36
+ // Where the consuming app's Pods live. PODS_ROOT is exported by Xcode.app for
37
+ // a real build, but never by plain `xcodebuild`, and never while Xcode indexes
38
+ // the manifest before a first build. SwiftPM also caches manifest evaluations,
39
+ // so an evaluation that ran without it would otherwise be cached with an empty
40
+ // include list and surface later as header-not-found errors. Fall back to
41
+ // where Pods sit relative to this package for every standard app layout, so
42
+ // the result is the same with or without the environment variable.
43
+ let podsRootCandidates = [
44
+ sibling("../../ios/Pods"), // consumer: <app>/node_modules/react-native-webgpu
45
+ sibling("../../apps/spm-example/ios/Pods"), // this monorepo
46
+ ]
47
+ let podsRoot =
48
+ ProcessInfo.processInfo.environment["PODS_ROOT"]
49
+ ?? podsRootCandidates.first { FileManager.default.fileExists(atPath: $0) }
50
+ ?? podsRootCandidates[0]
51
+
52
+ // Skia Graphite and WebGPU must link the exact same Dawn, or the pair links
53
+ // fine and crashes at runtime. react-native-skia's podspec enforces this at
54
+ // `pod install` time by comparing its libs/.dawn-version against this
55
+ // package's `dawn` field. A Swift package has no install hook, so the same
56
+ // check runs here, at manifest evaluation. SwiftPM caches evaluations, so
57
+ // after changing either package's Dawn version reset the package caches
58
+ // (File > Packages > Reset Package Caches) if this does not re-run.
59
+ let dawnReleaseTag = "dawn-chrome-m154"
60
+ let skiaCandidates = [
61
+ sibling("../@shopify/react-native-skia"), // consumer: sibling in node_modules
62
+ sibling("../../node_modules/@shopify/react-native-skia"), // this monorepo
63
+ ]
64
+ for skia in skiaCandidates {
65
+ // Only Graphite builds of react-native-skia write this marker (Ganesh
66
+ // builds do not link Dawn and impose no constraint).
67
+ guard let data = FileManager.default.contents(atPath: "\(skia)/libs/.dawn-version"),
68
+ let skiaDawn = String(data: data, encoding: .utf8)?
69
+ .trimmingCharacters(in: .whitespacesAndNewlines)
70
+ else { continue }
71
+ if skiaDawn != dawnReleaseTag {
72
+ fatalError(
73
+ """
74
+ react-native-webgpu: Dawn version mismatch. This package links \(dawnReleaseTag) \
75
+ but the @shopify/react-native-skia Graphite build at \(skia) links \(skiaDawn). \
76
+ Align the two packages so the app contains exactly one Dawn.
77
+ """)
78
+ }
79
+ break
80
+ }
81
+
82
+ // Static-library Pods layout. With `use_frameworks!` CocoaPods keeps headers
83
+ // inside each framework instead and none of these paths exist; the podspec
84
+ // refuses RNWGPU_USE_SPM in that mode.
85
+ let publicHeaders = "\(podsRoot)/Headers/Public"
86
+ let privateHeaders = "\(podsRoot)/Headers/Private"
87
+ let headerSearchPaths = [
88
+ publicHeaders,
89
+ // Yoga's headers are CocoaPods-private (apps aren't meant to use Yoga's
90
+ // C++ API directly), but React-Fabric's view props headers include them
91
+ // transitively.
92
+ "\(privateHeaders)/Yoga",
93
+ "\(publicHeaders)/React-Core",
94
+ "\(publicHeaders)/React-jsi",
95
+ "\(publicHeaders)/React-callinvoker",
96
+ "\(publicHeaders)/React-NativeModulesApple",
97
+ "\(publicHeaders)/React-RCTFabric",
98
+ "\(publicHeaders)/ReactCodegen",
99
+ "\(publicHeaders)/RCT-Folly",
100
+ "\(publicHeaders)/RCTRequired",
101
+ "\(publicHeaders)/RCTTypeSafety",
102
+ "\(publicHeaders)/FBLazyVector",
103
+ "\(publicHeaders)/ReactCommon",
104
+ "\(publicHeaders)/React-Fabric",
105
+ "\(publicHeaders)/React-graphics",
106
+ "\(publicHeaders)/React-utils",
107
+ "\(publicHeaders)/React-featureflags",
108
+ "\(publicHeaders)/React-rendererdebug",
109
+ "\(publicHeaders)/React-debug",
110
+ "\(publicHeaders)/React-timing",
111
+ "\(publicHeaders)/React-runtimescheduler",
112
+ "\(publicHeaders)/React-rendererconsistency",
113
+ "\(publicHeaders)/React-performancetimeline",
114
+ "\(publicHeaders)/React-runtimeexecutor",
115
+ "\(publicHeaders)/React-cxxreact",
116
+ "\(publicHeaders)/hermes-engine",
117
+ "\(publicHeaders)/glog",
118
+ "\(publicHeaders)/DoubleConversion",
119
+ "\(publicHeaders)/fmt",
120
+ "\(publicHeaders)/fast_float",
121
+ ]
122
+ // The only unsafe flags left: .headerSearchPath cannot escape the target
123
+ // path, and these live in the app's Pods directory.
124
+ let cFamilyIncludeFlags = headerSearchPaths.map { "-I\($0)" }
125
+ let follyDefines: [(name: String, value: String?)] = [
126
+ ("FOLLY_NO_CONFIG", nil),
127
+ ("FOLLY_MOBILE", "1"),
128
+ ("FOLLY_USE_LIBCPP", "1"),
129
+ ("FOLLY_CFG_NO_COROUTINES", "1"),
130
+ ("FOLLY_HAVE_CLOCK_GETTIME", "1"),
131
+ ]
132
+
133
+ // Unlike a native Xcode target, SwiftPM doesn't generate an implicit
134
+ // per-target header map, so quoted includes only resolve within the
135
+ // including file's own directory. The sources use bare cross-directory
136
+ // includes (e.g. apple/WebGPUModule.h includes "RNWebGPUManager.h" from
137
+ // cpp/rnwgpu), so every directory that's the target of one of those bare
138
+ // includes has to be listed explicitly here.
139
+ let internalHeaderDirs = [
140
+ "apple",
141
+ // "cpp" itself resolves the "webgpu/..." and "dawn/..." namespaced
142
+ // includes. Those two directories are only present locally when built via
143
+ // `yarn install-dawn` (without the xcframework's embedded headers); a
144
+ // remote binaryTarget's xcframework embeds them instead (see
145
+ // build-dawn.yml's `-headers` flag), so "cpp" not containing them there
146
+ // is fine — the xcframework's own headers cover it.
147
+ "cpp",
148
+ "cpp/jsi",
149
+ "cpp/rnwgpu",
150
+ "cpp/rnwgpu/api",
151
+ "cpp/rnwgpu/api/descriptors",
152
+ "cpp/rnwgpu/async",
153
+ ]
154
+
155
+ let package = Package(
156
+ name: "react-native-webgpu",
157
+ platforms: [.iOS("15.1"), .macOS("11.0")],
158
+ products: [
159
+ .library(name: "react-native-webgpu", targets: ["react-native-webgpu"])
160
+ ],
161
+ targets: [
162
+ // Dawn's compiled WebGPU implementation. The xcframework embeds the
163
+ // `webgpu/` and `dawn/` C headers per-slice (built via `-headers` in
164
+ // build-dawn.yml), so SPM exposes them to dependents automatically.
165
+ .binaryTarget(
166
+ name: "WebGPUDawn",
167
+ url: "https://github.com/wcandillon/react-native-webgpu/releases/download/dawn-chrome-m154/dawn-apple-dawn-chrome-m154.xcframework.zip",
168
+ checksum: "896575ffbc99610198a83d061f8c5a2789139b7f16c669fbf3a9f7a7ac9be123"
169
+ ),
170
+ .target(
171
+ name: "react-native-webgpu",
172
+ dependencies: ["WebGPUDawn"],
173
+ path: ".",
174
+ sources: ["apple", "cpp/jsi", "cpp/rnwgpu"],
175
+ publicHeadersPath: "apple",
176
+ cSettings: internalHeaderDirs.map { CSetting.headerSearchPath($0) }
177
+ + follyDefines.map { CSetting.define($0.name, to: $0.value) }
178
+ + [.unsafeFlags(cFamilyIncludeFlags)],
179
+ cxxSettings: internalHeaderDirs.map { CXXSetting.headerSearchPath($0) }
180
+ + follyDefines.map { CXXSetting.define($0.name, to: $0.value) }
181
+ + [.unsafeFlags(cFamilyIncludeFlags)],
182
+ linkerSettings: [
183
+ .linkedFramework("AVFoundation"),
184
+ .linkedFramework("CoreMedia"),
185
+ .linkedFramework("CoreVideo"),
186
+ .linkedFramework("ImageIO"),
187
+ ]
188
+ ),
189
+ ],
190
+ cxxLanguageStandard: .cxx20
191
+ )
@@ -49,8 +49,7 @@ add_library(${PACKAGE_NAME} SHARED
49
49
  ../cpp/rnwgpu/api/GPUCanvasContext.cpp
50
50
  ../cpp/rnwgpu/RNWebGPUManager.cpp
51
51
  ../cpp/jsi/Promise.cpp
52
- ../cpp/jsi/RuntimeLifecycleMonitor.cpp
53
- ../cpp/jsi/RuntimeAwareCache.cpp
52
+ ../cpp/jsi/JSICache.cpp
54
53
  ../cpp/rnwgpu/async/RuntimeContext.cpp
55
54
  ../cpp/rnwgpu/async/AsyncTaskHandle.cpp
56
55
  )
@@ -2,6 +2,7 @@ package com.webgpu;
2
2
 
3
3
  import android.annotation.SuppressLint;
4
4
  import android.content.Context;
5
+ import android.graphics.PixelFormat;
5
6
  import android.view.SurfaceHolder;
6
7
  import android.view.SurfaceView;
7
8
 
@@ -12,12 +13,20 @@ public class WebGPUSurfaceView extends SurfaceView implements SurfaceHolder.Call
12
13
 
13
14
  WebGPUAPI mApi;
14
15
 
15
- public WebGPUSurfaceView(Context context, WebGPUAPI api) {
16
+ public WebGPUSurfaceView(Context context, WebGPUAPI api, boolean zOrderOnTop, boolean opaque) {
16
17
  super(context);
17
18
  mApi = api;
19
+ setZOrderOnTop(zOrderOnTop);
20
+ setOpaque(opaque);
18
21
  getHolder().addCallback(this);
19
22
  }
20
23
 
24
+ // The format drives the compositor's opaque flag for this layer. It can
25
+ // change on a live surface: SurfaceView reports it through surfaceChanged.
26
+ public void setOpaque(boolean opaque) {
27
+ getHolder().setFormat(opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT);
28
+ }
29
+
21
30
  @Override
22
31
  protected void onDetachedFromWindow() {
23
32
  super.onDetachedFromWindow();
@@ -13,10 +13,10 @@ public class WebGPUTextureView extends TextureView implements TextureView.Surfac
13
13
  WebGPUAPI mApi;
14
14
  private Surface mSurface;
15
15
 
16
- public WebGPUTextureView(Context context, WebGPUAPI api) {
16
+ public WebGPUTextureView(Context context, WebGPUAPI api, boolean opaque) {
17
17
  super(context);
18
18
  mApi = api;
19
- setOpaque(false);
19
+ setOpaque(opaque);
20
20
  setSurfaceTextureListener(this);
21
21
  }
22
22
 
@@ -1,7 +1,6 @@
1
1
  package com.webgpu;
2
2
 
3
3
  import android.content.Context;
4
- import android.os.Build;
5
4
  import android.view.Surface;
6
5
  import android.view.View;
7
6
 
@@ -13,7 +12,11 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
13
12
 
14
13
 
15
14
  private int mContextId;
16
- private boolean mTransparent = false;
15
+ private boolean mOpaque = true;
16
+ private String mSurfaceType = "auto";
17
+ private boolean mZOrderOnTop = false;
18
+ private boolean mAppliedTextureView;
19
+ private boolean mAppliedZOrderOnTop;
17
20
  private WebGPUModule mModule;
18
21
  private View mView = null;
19
22
 
@@ -31,30 +34,59 @@ public class WebGPUView extends ReactViewGroup implements WebGPUAPI {
31
34
  mContextId = contextId;
32
35
  }
33
36
 
34
- public void setTransparent(boolean value) {
35
- Context ctx = getContext();
36
- if (value != mTransparent || mView == null) {
37
+ public void setOpaque(boolean value) {
38
+ mOpaque = value;
39
+ }
40
+
41
+ public void setSurfaceType(String value) {
42
+ mSurfaceType = value;
43
+ }
44
+
45
+ public void setZOrderOnTop(boolean value) {
46
+ mZOrderOnTop = value;
47
+ }
48
+
49
+ // Apply the complete prop transaction once, after contextId and all rendering
50
+ // options have arrived. Only a change of backing view (or of zOrderOnTop,
51
+ // which a SurfaceView must know before it attaches) replaces the child;
52
+ // opacity is applied in place.
53
+ public void updateView() {
54
+ boolean textureView = "TextureView".equals(mSurfaceType)
55
+ || (!"SurfaceView".equals(mSurfaceType) && !mOpaque);
56
+ boolean zOrderOnTop = !textureView && mZOrderOnTop;
57
+ if (mView == null || textureView != mAppliedTextureView
58
+ || zOrderOnTop != mAppliedZOrderOnTop) {
37
59
  if (mView != null) {
38
60
  removeView(mView);
39
61
  }
40
- mTransparent = value;
41
- if (mTransparent) {
42
- // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
43
- // mView = new WebGPUAHBView(ctx, this);
44
- // } else {
45
- mView = new WebGPUTextureView(ctx, this);
46
- // }
47
- } else {
48
- mView = new WebGPUSurfaceView(ctx, this);
49
- }
62
+ mAppliedTextureView = textureView;
63
+ mAppliedZOrderOnTop = zOrderOnTop;
64
+ Context ctx = getContext();
65
+ mView = textureView
66
+ ? new WebGPUTextureView(ctx, this, mOpaque)
67
+ : new WebGPUSurfaceView(ctx, this, zOrderOnTop, mOpaque);
50
68
  addView(mView);
69
+ // ReactViewGroup.requestLayout() is a deliberate no-op, so addView outside
70
+ // the layout pass never lays the child out; do it by hand or the new view
71
+ // stays 0x0 and never gets a surface.
72
+ layoutChild();
73
+ } else if (textureView) {
74
+ ((WebGPUTextureView) mView).setOpaque(mOpaque);
75
+ } else {
76
+ ((WebGPUSurfaceView) mView).setOpaque(mOpaque);
51
77
  }
52
78
  }
53
79
 
80
+ private void layoutChild() {
81
+ mView.layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
82
+ }
83
+
54
84
  @Override
55
85
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
56
86
  super.onLayout(changed, left, top, right, bottom);
57
- mView.layout(0, 0, this.getMeasuredWidth(), this.getMeasuredHeight());
87
+ if (mView != null) {
88
+ layoutChild();
89
+ }
58
90
  }
59
91
 
60
92
  @Override
@@ -1,7 +1,6 @@
1
1
  package com.webgpu;
2
2
 
3
3
  import androidx.annotation.NonNull;
4
- import androidx.annotation.Nullable;
5
4
 
6
5
  import com.facebook.react.module.annotations.ReactModule;
7
6
  import com.facebook.react.uimanager.ThemedReactContext;
@@ -31,9 +30,27 @@ public class WebGPUViewManager extends WebGPUViewManagerSpec<WebGPUView> {
31
30
  }
32
31
 
33
32
  @Override
34
- @ReactProp(name = "transparent")
35
- public void setTransparent(WebGPUView view, boolean value) {
36
- view.setTransparent(value);
33
+ @ReactProp(name = "opaque", defaultBoolean = true)
34
+ public void setOpaque(WebGPUView view, boolean value) {
35
+ view.setOpaque(value);
36
+ }
37
+
38
+ @Override
39
+ @ReactProp(name = "androidSurfaceType")
40
+ public void setAndroidSurfaceType(WebGPUView view, String value) {
41
+ view.setSurfaceType(value);
42
+ }
43
+
44
+ @Override
45
+ @ReactProp(name = "androidZOrderOnTop")
46
+ public void setAndroidZOrderOnTop(WebGPUView view, boolean value) {
47
+ view.setZOrderOnTop(value);
48
+ }
49
+
50
+ @Override
51
+ protected void onAfterUpdateTransaction(@NonNull WebGPUView view) {
52
+ super.onAfterUpdateTransaction(view);
53
+ view.updateView();
37
54
  }
38
55
 
39
56
  @Override
@@ -0,0 +1,97 @@
1
+ #include "JSICache.h"
2
+
3
+ #include <iterator>
4
+ #include <stdexcept>
5
+ #include <string>
6
+ #include <utility>
7
+
8
+ namespace rnwgpu {
9
+
10
+ namespace {
11
+ // Hidden global holding the per-runtime cache object. Named so it is
12
+ // obviously ours if it ever shows up in a debugger or heap snapshot.
13
+ constexpr const char *kGlobalName = "__rnwgpuJsiCache";
14
+ } // namespace
15
+
16
+ std::mutex JSICache::_registryMutex;
17
+ std::unordered_map<jsi::Runtime *, std::weak_ptr<JSICache>> JSICache::_registry;
18
+
19
+ JSICache &JSICache::get(jsi::Runtime &runtime) {
20
+ {
21
+ std::lock_guard<std::mutex> lock(_registryMutex);
22
+ auto it = _registry.find(&runtime);
23
+ if (it != _registry.end()) {
24
+ if (auto cache = it->second.lock()) {
25
+ // The cache is kept alive by `runtime`'s global, so the raw
26
+ // reference stays valid for as long as the caller may legally use
27
+ // `runtime` on this thread.
28
+ return *cache;
29
+ }
30
+ // Expired: the runtime that owned this entry is gone and `&runtime` is
31
+ // a new runtime reusing the address. Fall through and recreate.
32
+ }
33
+ }
34
+ auto cache = getOrCreateOnGlobal(runtime);
35
+ {
36
+ std::lock_guard<std::mutex> lock(_registryMutex);
37
+ // Drop entries of runtimes that are gone so the map does not grow by one
38
+ // stale pointer per reload / worklet runtime.
39
+ for (auto it = _registry.begin(); it != _registry.end();) {
40
+ it = it->second.expired() ? _registry.erase(it) : std::next(it);
41
+ }
42
+ _registry[&runtime] = cache;
43
+ }
44
+ return *cache;
45
+ }
46
+
47
+ std::shared_ptr<JSICache> JSICache::getOrCreateOnGlobal(jsi::Runtime &runtime) {
48
+ auto global = runtime.global();
49
+ auto existing = global.getProperty(runtime, kGlobalName);
50
+ if (existing.isObject()) {
51
+ auto obj = existing.getObject(runtime);
52
+ if (obj.hasNativeState<JSICache>(runtime)) {
53
+ return obj.getNativeState<JSICache>(runtime);
54
+ }
55
+ }
56
+ if (!existing.isUndefined()) {
57
+ // Something else already claimed our global. The most likely cause is two
58
+ // copies of react-native-webgpu loaded in one process (each has its own
59
+ // JSICache type, so the NativeState check above fails). Say so instead of
60
+ // letting Object.defineProperty throw a bare TypeError on the
61
+ // non-configurable property.
62
+ throw std::runtime_error(
63
+ std::string("react-native-webgpu: global.") + kGlobalName +
64
+ " already exists but is not our JSICache. Is react-native-webgpu "
65
+ "linked twice, or is another module using this global?");
66
+ }
67
+ auto cache = std::make_shared<JSICache>();
68
+ jsi::Object holder(runtime);
69
+ holder.setNativeState(runtime, cache);
70
+ // Non-enumerable, non-writable, non-configurable: JS code must not be able
71
+ // to drop the holder (which would finalize the cache under our feet).
72
+ auto objectCtor = global.getPropertyAsObject(runtime, "Object");
73
+ auto defineProperty =
74
+ objectCtor.getPropertyAsFunction(runtime, "defineProperty");
75
+ jsi::Object descriptor(runtime);
76
+ descriptor.setProperty(runtime, "value", std::move(holder));
77
+ descriptor.setProperty(runtime, "writable", false);
78
+ descriptor.setProperty(runtime, "enumerable", false);
79
+ descriptor.setProperty(runtime, "configurable", false);
80
+ defineProperty.call(runtime, global,
81
+ jsi::String::createFromAscii(runtime, kGlobalName),
82
+ descriptor);
83
+ return cache;
84
+ }
85
+
86
+ jsi::Object *JSICache::getPrototype(PrototypeKey key) {
87
+ auto it = _prototypes.find(key);
88
+ return it == _prototypes.end() ? nullptr : &it->second;
89
+ }
90
+
91
+ jsi::Object &JSICache::setPrototype(PrototypeKey key, jsi::Object prototype) {
92
+ auto [it, inserted] = _prototypes.insert_or_assign(key, std::move(prototype));
93
+ (void)inserted;
94
+ return it->second;
95
+ }
96
+
97
+ } // namespace rnwgpu
@@ -0,0 +1,90 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+
5
+ #include <memory>
6
+ #include <mutex>
7
+ #include <typeindex>
8
+ #include <unordered_map>
9
+
10
+ namespace rnwgpu {
11
+
12
+ namespace jsi = facebook::jsi;
13
+
14
+ /**
15
+ * Per-runtime store for JSI values that native code wants to keep across
16
+ * calls (currently: the prototype object of every NativeObject class).
17
+ *
18
+ * Ownership model (borrowed from react-native-nitro-modules' JSICache):
19
+ *
20
+ * - One JSICache exists per jsi::Runtime. It is attached as the NativeState
21
+ * of a hidden object stored on that runtime's `global`, so the RUNTIME owns
22
+ * the cache. When the runtime is destroyed the engine finalizes the object,
23
+ * ~JSICache runs while the runtime is still alive, and every cached
24
+ * jsi::Object is released correctly. Nothing outlives its runtime and
25
+ * nothing has to be leaked.
26
+ *
27
+ * - Native code reaches the cache through JSICache::get(runtime). A static
28
+ * map of std::weak_ptr, keyed by jsi::Runtime*, makes the lookup cheap; the
29
+ * pointer is only a map key, never proof that a runtime is alive. If the
30
+ * weak_ptr is expired (the runtime that owned it is gone) the entry is
31
+ * recreated on the runtime asking for it. This is what makes an in-process
32
+ * runtime recreate (expo-updates OTA apply, DevSettings.reload) safe even
33
+ * when the new runtime is allocated at the address of the freed one: the
34
+ * old cache was destroyed with the old runtime, so the reused address can
35
+ * only ever resolve to a fresh cache.
36
+ *
37
+ * - The cache itself is not locked: a jsi::Runtime is single-threaded, and
38
+ * the cache is only ever touched from its runtime's thread. Only the static
39
+ * runtime -> cache map is guarded.
40
+ *
41
+ * The same mechanism works for worklet runtimes (Reanimated UI runtime,
42
+ * createWorkletRuntime, ...); each gets its own JSICache.
43
+ */
44
+ class JSICache final : public jsi::NativeState {
45
+ public:
46
+ /**
47
+ * Key identifying one cached prototype: the C++ type of the NativeObject
48
+ * subclass (std::type_index(typeid(Derived))), as in Nitro. It prints as
49
+ * the class name in a debugger.
50
+ */
51
+ using PrototypeKey = std::type_index;
52
+
53
+ /**
54
+ * Returns the cache owned by `runtime`, creating it on first use. Must be
55
+ * called on the runtime's thread.
56
+ */
57
+ static JSICache &get(jsi::Runtime &runtime);
58
+
59
+ /**
60
+ * Returns the cached prototype for `key` or nullptr if none was stored.
61
+ *
62
+ * The pointer points into `_prototypes`. std::unordered_map never
63
+ * invalidates pointers/references to elements on insert or rehash (only on
64
+ * erase of that element, which we never do), so it stays valid for as long
65
+ * as the runtime does. Do not swap the container for one without that
66
+ * guarantee (std::vector, absl::flat_hash_map, ...).
67
+ */
68
+ jsi::Object *getPrototype(PrototypeKey key);
69
+
70
+ /**
71
+ * Stores (or replaces) the prototype for `key` and returns it.
72
+ */
73
+ jsi::Object &setPrototype(PrototypeKey key, jsi::Object prototype);
74
+
75
+ JSICache() = default;
76
+ ~JSICache() override = default;
77
+ JSICache(const JSICache &) = delete;
78
+ JSICache &operator=(const JSICache &) = delete;
79
+
80
+ private:
81
+ static std::shared_ptr<JSICache> getOrCreateOnGlobal(jsi::Runtime &runtime);
82
+
83
+ std::unordered_map<PrototypeKey, jsi::Object> _prototypes;
84
+
85
+ // Runtime -> cache. Weak on purpose: the runtime's global owns the cache.
86
+ static std::mutex _registryMutex;
87
+ static std::unordered_map<jsi::Runtime *, std::weak_ptr<JSICache>> _registry;
88
+ };
89
+
90
+ } // namespace rnwgpu