Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,7 @@ jobs:

- name: Install CocoaPods
working-directory: apps/example/ios
run: |
HASH_FILE="/tmp/.podfile-lock-hash"
CURRENT_HASH=$(shasum Podfile.lock | cut -d' ' -f1)
if [ -f "$HASH_FILE" ] && [ "$(cat "$HASH_FILE")" = "$CURRENT_HASH" ] && [ -d "Pods" ]; then
echo "Podfile.lock unchanged and Pods exists — skipping pod install"
else
pod install
echo "$CURRENT_HASH" > "$HASH_FILE"
fi
run: pod install

- name: Ensure Metro port is free
run: |
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,41 @@ device.queue.copyExternalImageToTexture(
);
```

### Shared Texture Memory

React Native WebGPU exposes Dawn's `SharedTextureMemory` so you can import a native pixel surface (an `IOSurface`-backed `CVPixelBuffer` on iOS, an `AHardwareBuffer` on Android) as a sampleable `GPUTexture` without copying pixels through the CPU. This is the path you want for camera frames, video frames, or anything coming out of a hardware producer.

We expose a single umbrella feature name, `"rnwebgpu/shared-texture-memory"`. Request it at device creation.

```tsx
import type { VideoFrame } from "react-native-wgpu";

const FEATURE = "rnwebgpu/shared-texture-memory" as GPUFeatureName;

const adapter = await navigator.gpu.requestAdapter();
const requiredFeatures = adapter!.features.has(FEATURE) ? [FEATURE] : [];
const device = await adapter!.requestDevice({ requiredFeatures });

// `frame` here is a VideoFrame whose .handle is the native surface
// (IOSurfaceRef / AHardwareBuffer*). VideoFrames are produced by helpers
// like RNWebGPU.createVideoPlayer or RNWebGPU.createTestVideoFrame, or by
// any third-party module that hands you a compatible native pointer.
const memory = device.importSharedTextureMemory({
handle: frame.handle,
label: "video-frame",
});
const texture = memory.createTexture();

memory.beginAccess(texture, /* initialized */ true);
// ... bind `texture` into a sampler and render normally ...
memory.endAccess(texture);

texture.destroy();
frame.release();
```

`beginAccess`/`endAccess` bracket the GPU's read window on the shared surface. Pass `initialized: true` when the producer has already written meaningful pixels (the typical video/camera case) and `false` when the next pass will fully overwrite the texture.

### Reanimated Integration

React Native WebGPU supports running WebGPU rendering on the UI thread using [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/) and [React Native Worklets](https://github.com/margelo/react-native-worklets).
Expand Down
4 changes: 4 additions & 0 deletions apps/example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
newArchEnabled=true
hermesEnabled=true

# react-native-wgpu requires API 26+ (AHardwareBuffer for shared texture memory,
# and Dawn's Android backend itself).
react.minSdkVersion=26

# Use this property to enable support to the new architecture.
# This will allow you to use TurboModules and the Fabric render in
# your application. You should enable this flag either if you want
Expand Down
28 changes: 14 additions & 14 deletions apps/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- react-native-wgpu (0.5.11):
- react-native-wgpu (0.5.12):
- boost
- DoubleConversion
- fast_float
Expand Down Expand Up @@ -2460,7 +2460,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- RNReanimated (4.2.1):
- RNReanimated (4.3.1):
- boost
- DoubleConversion
- fast_float
Expand All @@ -2487,11 +2487,12 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/reanimated (= 4.2.1)
- RNReanimated/apple (= 4.3.1)
- RNReanimated/common (= 4.3.1)
- RNWorklets
- SocketRocket
- Yoga
- RNReanimated/reanimated (4.2.1):
- RNReanimated/apple (4.3.1):
- boost
- DoubleConversion
- fast_float
Expand All @@ -2518,11 +2519,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/reanimated/apple (= 4.2.1)
- RNWorklets
- SocketRocket
- Yoga
- RNReanimated/reanimated/apple (4.2.1):
- RNReanimated/common (4.3.1):
- boost
- DoubleConversion
- fast_float
Expand Down Expand Up @@ -2552,7 +2552,7 @@ PODS:
- RNWorklets
- SocketRocket
- Yoga
- RNWorklets (0.7.2):
- RNWorklets (0.8.3):
- boost
- DoubleConversion
- fast_float
Expand All @@ -2579,10 +2579,11 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNWorklets/worklets (= 0.7.2)
- RNWorklets/apple (= 0.8.3)
- RNWorklets/common (= 0.8.3)
- SocketRocket
- Yoga
- RNWorklets/worklets (0.7.2):
- RNWorklets/apple (0.8.3):
- boost
- DoubleConversion
- fast_float
Expand All @@ -2609,10 +2610,9 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNWorklets/worklets/apple (= 0.7.2)
- SocketRocket
- Yoga
- RNWorklets/worklets/apple (0.7.2):
- RNWorklets/common (0.8.3):
- boost
- DoubleConversion
- fast_float
Expand Down Expand Up @@ -2938,7 +2938,7 @@ SPEC CHECKSUMS:
React-microtasksnativemodule: 75b6604b667d297292345302cc5bfb6b6aeccc1b
react-native-safe-area-context: c00143b4823773bba23f2f19f85663ae89ceb460
react-native-skia: fc73e9bdc46ebb420a98c9c2be29fee80f565e79
react-native-wgpu: 990ed34b0216cb4980a52344ec959cb8899d2845
react-native-wgpu: 274ffec11ee3a082260d9f3d1fb54030a5ca0873
React-NativeModulesApple: 879fbdc5dcff7136abceb7880fe8a2022a1bd7c3
React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d
React-perflogger: 5536d2df3d18fe0920263466f7b46a56351c0510
Expand Down Expand Up @@ -2973,8 +2973,8 @@ SPEC CHECKSUMS:
ReactTestApp-DevSupport: 9b7bbba5e8fed998e763809171d9906a1375f9d3
ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf
RNGestureHandler: e37bdb684df1ac17c7e1d8f71a3311b2793c186b
RNReanimated: 464375ff2caa801358547c44eca894ff0bf68e74
RNWorklets: ee58e869ea579800ec5f2f1cb6ae195fd3537546
RNReanimated: 9d012d4031abc9df896f8a82f9928eb2b9eae417
RNWorklets: 0da2552f9ff5d17506918a692304110cfebb9f0a
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: a3ed390a19db0459bd6839823a6ac6d9c6db198d

Expand Down
5 changes: 5 additions & 0 deletions apps/example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { Reanimated } from "./Reanimated";
import { AsyncStarvation } from "./Diagnostics/AsyncStarvation";
import { DeviceLostHang } from "./Diagnostics/DeviceLostHang";
import { StorageBufferVertices } from "./StorageBufferVertices";
import { SharedTextureMemory } from "./SharedTextureMemory";

// The two lines below are needed by three.js
import "fast-text-encoding";
Expand Down Expand Up @@ -97,6 +98,10 @@ function App() {
name="StorageBufferVertices"
component={StorageBufferVertices}
/>
<Stack.Screen
name="SharedTextureMemory"
component={SharedTextureMemory}
/>
</Stack.Navigator>
</NavigationContainer>
</GestureHandlerRootView>
Expand Down
4 changes: 4 additions & 0 deletions apps/example/src/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ export const examples = [
screen: "StorageBufferVertices",
title: "💾 Storage Buffer Vertices",
},
{
screen: "SharedTextureMemory",
title: "🎞️ Shared Texture Memory",
},
];

const styles = StyleSheet.create({
Expand Down
1 change: 1 addition & 0 deletions apps/example/src/Route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ export type Routes = {
AsyncStarvation: undefined;
DeviceLostHang: undefined;
StorageBufferVertices: undefined;
SharedTextureMemory: undefined;
};
Loading
Loading