react-native-webgpu 0.11.1 → 0.11.2

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.
@@ -25,18 +25,24 @@ namespace rnwgpu {
25
25
  async::AsyncTaskHandle GPUAdapter::requestDevice(
26
26
  jsi::Runtime &runtime,
27
27
  std::optional<std::shared_ptr<GPUDeviceDescriptor>> descriptor) {
28
- // Enable the react-native-wgpu "native-texture" umbrella by default, mirroring
29
- // the web where importExternalTexture is core and needs no feature request.
30
- // We append the umbrella's backing Dawn features to requiredFeatures so the
31
- // capability is on without the caller listing it. Two rules keep this safe:
28
+ // Enable the react-native-wgpu "native-texture" umbrella by default,
29
+ // mirroring the web where importExternalTexture is core and needs no feature
30
+ // request. We append the umbrella's backing Dawn features to requiredFeatures
31
+ // so the capability is on without the caller listing it. Two rules keep this
32
+ // safe:
32
33
  // - All-or-nothing: only inject when the adapter supports *every* backing
33
34
  // feature (same semantics as maybeSynthesizeRnNativeTextureFeature). On a
34
- // web/fallback adapter the backing set is empty or unsupported, so this is
35
- // a no-op and device creation is unaffected.
35
+ // web/fallback adapter the backing set is empty or unsupported, so this
36
+ // is a no-op and device creation is unaffected.
36
37
  // - Requesting a feature the adapter doesn't support makes RequestDevice
37
38
  // fail, hence the support check below.
38
39
  // Callers can still pass "rnwebgpu/native-texture" explicitly; the dedupe
39
40
  // keeps that idempotent.
41
+ // The optional features (rnNativeTextureOptionalFeatures) ride along one by
42
+ // one, each only when the adapter supports it: on Android the YUV frames of
43
+ // the decoder and of the camera cannot be imported without
44
+ // OpaqueYCbCrAndroidForExternalTexture, while RGBA buffers need nothing
45
+ // beyond the backing set.
40
46
  {
41
47
  auto backing = rnNativeTextureBackingFeatures();
42
48
  if (!backing.empty()) {
@@ -44,9 +50,10 @@ async::AsyncTaskHandle GPUAdapter::requestDevice(
44
50
  _instance.GetFeatures(&supported);
45
51
  std::unordered_set<wgpu::FeatureName> supportedSet(
46
52
  supported.features, supported.features + supported.featureCount);
47
- bool allSupported = std::all_of(
48
- backing.begin(), backing.end(),
49
- [&](wgpu::FeatureName f) { return supportedSet.count(f) > 0; });
53
+ bool allSupported =
54
+ std::all_of(backing.begin(), backing.end(), [&](wgpu::FeatureName f) {
55
+ return supportedSet.count(f) > 0;
56
+ });
50
57
  if (allSupported) {
51
58
  if (!descriptor.has_value()) {
52
59
  descriptor = std::make_shared<GPUDeviceDescriptor>();
@@ -62,6 +69,13 @@ async::AsyncTaskHandle GPUAdapter::requestDevice(
62
69
  features.push_back(f);
63
70
  }
64
71
  }
72
+ for (auto f : rnNativeTextureOptionalFeatures()) {
73
+ if (supportedSet.count(f) > 0 &&
74
+ std::find(features.begin(), features.end(), f) ==
75
+ features.end()) {
76
+ features.push_back(f);
77
+ }
78
+ }
65
79
  }
66
80
  }
67
81
  }
@@ -101,8 +115,7 @@ async::AsyncTaskHandle GPUAdapter::requestDevice(
101
115
  if (std::find(features.begin(), features.end(),
102
116
  wgpu::FeatureName::ImplicitDeviceSynchronization) ==
103
117
  features.end()) {
104
- features.push_back(
105
- wgpu::FeatureName::ImplicitDeviceSynchronization);
118
+ features.push_back(wgpu::FeatureName::ImplicitDeviceSynchronization);
106
119
  }
107
120
  }
108
121
  }
@@ -211,7 +224,8 @@ async::AsyncTaskHandle GPUAdapter::requestDevice(
211
224
  }
212
225
  }
213
226
  }
214
- // TODO: in the latest version of Dawn, this won't be needed (https://issues.chromium.org/issues/42241591)
227
+ // TODO: in the latest version of Dawn, this won't be needed
228
+ // (https://issues.chromium.org/issues/42241591)
215
229
  #if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
216
230
  // The iOS Simulator only advertises MTLFeatureSet_iOS_GPUFamily2, so
217
231
  // Dawn defaults disable_base_instance/disable_base_vertex on and then
@@ -8,8 +8,47 @@
8
8
 
9
9
  #include "GPUExternalTextureDescriptor.h"
10
10
 
11
+ #if defined(__ANDROID__)
12
+ #include <android/hardware_buffer.h>
13
+ #endif
14
+
11
15
  namespace rnwgpu {
12
16
 
17
+ #if defined(__ANDROID__)
18
+ // Whether Dawn imports an AHardwareBuffer of this format as an
19
+ // OpaqueYCbCrAndroid texture. Mirrors FormatFromAHardwareBufferFormat
20
+ // (dawn/native/AHBFunctions.cpp): the color and depth formats with a WebGPU
21
+ // equivalent import as that format; the YUV formats and the formats outside
22
+ // the public enum, which drivers use for the camera and the video decoder,
23
+ // import as OpaqueYCbCrAndroid.
24
+ static bool isOpaqueYCbCrFormat(uint32_t format) {
25
+ switch (format) {
26
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
27
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
28
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
29
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
30
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
31
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
32
+ case AHARDWAREBUFFER_FORMAT_BLOB:
33
+ case AHARDWAREBUFFER_FORMAT_D16_UNORM:
34
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM:
35
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
36
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
37
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
38
+ case AHARDWAREBUFFER_FORMAT_S8_UINT:
39
+ // Single-channel formats of the API 33 and 34 headers, by value so that
40
+ // older NDKs compile.
41
+ case 0x38: // AHARDWAREBUFFER_FORMAT_R8_UNORM
42
+ case 0x39: // AHARDWAREBUFFER_FORMAT_R16_UINT
43
+ case 0x3a: // AHARDWAREBUFFER_FORMAT_R16G16_UINT
44
+ case 0x3b: // AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM
45
+ return false;
46
+ default:
47
+ return true;
48
+ }
49
+ }
50
+ #endif
51
+
13
52
  // Identity gamut (BT.709 -> sRGB, same primaries) as a 3x3 column-major matrix.
14
53
  static const float kIdentityGamutMatrix[9] = {
15
54
  1.0f, 0.0f, 0.0f, //
@@ -254,6 +293,28 @@ std::shared_ptr<GPUExternalTexture> GPUExternalTexture::Create(
254
293
  // sampled texel is already RGB.
255
294
  kYuvPassthroughMatrix);
256
295
  #elif defined(__ANDROID__)
296
+ // 0. A YUV frame imports as an OpaqueYCbCrAndroid texture, which Dawn only
297
+ // accepts on a device with OpaqueYCbCrAndroidForExternalTexture.
298
+ // requestDevice() enables the feature whenever the adapter supports it;
299
+ // a device created by another library (importDevice) has to request it
300
+ // itself. Fail with the cause here: Dawn's own report is a bare
301
+ // "Unsupported texture format TextureFormat::OpaqueYCbCrAndroid" device
302
+ // error, followed by the failure of every call made with the result.
303
+ if (!device.HasFeature(
304
+ wgpu::FeatureName::OpaqueYCbCrAndroidForExternalTexture)) {
305
+ AHardwareBuffer_Desc ahbDesc{};
306
+ AHardwareBuffer_describe(static_cast<AHardwareBuffer *>(frame.handle),
307
+ &ahbDesc);
308
+ if (isOpaqueYCbCrFormat(ahbDesc.format)) {
309
+ throw std::runtime_error(
310
+ "GPUExternalTexture::Create(): a YUV frame can only be imported on "
311
+ "a device with the 'opaque-ycbcr-android-for-external-texture' "
312
+ "feature. requestDevice() enables it whenever the adapter supports "
313
+ "it; a device imported from another library has to request it "
314
+ "itself.");
315
+ }
316
+ }
317
+
257
318
  // 1. Import the AHardwareBuffer as SharedTextureMemory. For YUV AHBs this
258
319
  // yields a Dawn texture in the implementation-defined OpaqueYCbCrAndroid
259
320
  // format; for RGBA AHBs, a regular single-plane texture.
@@ -31,11 +31,24 @@ inline std::vector<wgpu::FeatureName> rnNativeTextureBackingFeatures() {
31
31
  #endif
32
32
  }
33
33
 
34
+ // Dawn features that complete the umbrella on the current platform. They are
35
+ // requested by default when the adapter supports them, but they are not part
36
+ // of the all-or-nothing backing set: on Android, Dawn imports the YUV buffers
37
+ // of the video decoder and of the camera as OpaqueYCbCrAndroid textures, a
38
+ // format it only accepts, and only samples as an external texture, with
39
+ // OpaqueYCbCrAndroidForExternalTexture; RGBA buffers import without it.
40
+ inline std::vector<wgpu::FeatureName> rnNativeTextureOptionalFeatures() {
41
+ #if defined(__ANDROID__)
42
+ return {wgpu::FeatureName::OpaqueYCbCrAndroidForExternalTexture};
43
+ #else
44
+ return {};
45
+ #endif
46
+ }
47
+
34
48
  // If every Dawn feature backing the umbrella is in `enabled`, add the
35
49
  // umbrella name to `out`. Used by adapter.features / device.features so JS
36
50
  // callers can see (and call .has on) the same name they pass in.
37
- inline void
38
- maybeSynthesizeRnNativeTextureFeature(
51
+ inline void maybeSynthesizeRnNativeTextureFeature(
39
52
  const std::unordered_set<wgpu::FeatureName> &enabled,
40
53
  std::unordered_set<std::string> &out) {
41
54
  auto backing = rnNativeTextureBackingFeatures();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-webgpu",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "React Native WebGPU",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",