react-native-webgpu 0.15.2 → 0.16.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/android/CMakeLists.txt +5 -0
- package/android/cpp/cpp-adapter.cpp +109 -11
- package/android/src/main/java/com/webgpu/SurfaceFrameRateVote.java +97 -85
- package/android/src/main/java/com/webgpu/WebGPUView.java +13 -8
- package/apple/ApplePlatformContext.h +1 -0
- package/cpp/jsi/JSICache.cpp +2 -0
- package/cpp/jsi/NativeObject.h +36 -12
- package/cpp/rnwgpu/RNWebGPUManager.cpp +4 -0
- package/cpp/rnwgpu/SurfaceRegistry.h +4 -4
- package/cpp/rnwgpu/api/GPUDevice.cpp +96 -0
- package/cpp/rnwgpu/api/GPUDevice.h +22 -0
- package/cpp/rnwgpu/api/GPUError.h +1 -0
- package/cpp/rnwgpu/api/GPUExtent2D.h +56 -0
- package/cpp/rnwgpu/api/GPUExternalTexture.cpp +32 -408
- package/cpp/rnwgpu/api/GPUExternalTexture.h +12 -37
- package/cpp/rnwgpu/api/GPUInternalError.h +1 -0
- package/cpp/rnwgpu/api/GPUNativeBufferExternalTexture.h +60 -0
- package/cpp/rnwgpu/api/GPUNativeBufferTexture.h +52 -0
- package/cpp/rnwgpu/api/GPUNativeBufferWrapper.cpp +144 -0
- package/cpp/rnwgpu/api/GPUNativeBufferWrapper.h +142 -0
- package/cpp/rnwgpu/api/GPUOutOfMemoryError.h +1 -0
- package/cpp/rnwgpu/api/GPUQueue.h +1 -0
- package/cpp/rnwgpu/api/GPUSharedFence.h +1 -0
- package/cpp/rnwgpu/api/GPUSharedTextureMemory.cpp +12 -44
- package/cpp/rnwgpu/api/GPUSharedTextureMemory.h +1 -0
- package/cpp/rnwgpu/api/GPUUncapturedErrorEvent.h +1 -0
- package/cpp/rnwgpu/api/GPUValidationError.h +1 -0
- package/cpp/rnwgpu/api/NativeFrameImport.cpp +638 -0
- package/cpp/rnwgpu/api/NativeFrameImport.h +86 -0
- package/cpp/rnwgpu/api/VideoFrame.h +21 -7
- package/cpp/rnwgpu/api/descriptors/GPUExternalTextureDescriptor.h +153 -1
- package/cpp/rnwgpu/api/descriptors/GPUNativeBufferTextureDescriptor.h +55 -0
- package/cpp/rnwgpu/async/RuntimeContext.cpp +1 -0
- package/lib/commonjs/Canvas.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/Canvas.d.ts +2 -31
- package/lib/typescript/src/Canvas.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +4 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +33 -0
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Canvas.tsx +3 -36
- package/src/index.tsx +24 -0
- package/src/types.ts +97 -0
package/src/Canvas.tsx
CHANGED
|
@@ -2,49 +2,16 @@ import React, { useEffect, useImperativeHandle, useRef, useState } from "react";
|
|
|
2
2
|
import type { ViewProps } from "react-native";
|
|
3
3
|
import { Platform, View } from "react-native";
|
|
4
4
|
|
|
5
|
+
import type { CanvasRef, RNCanvasContext } from "./types";
|
|
5
6
|
import WebGPUNativeView from "./WebGPUViewNativeComponent";
|
|
6
7
|
|
|
8
|
+
export type { CanvasRef, NativeCanvas, RNCanvasContext } from "./types";
|
|
9
|
+
|
|
7
10
|
let CONTEXT_COUNTER = 1;
|
|
8
11
|
function generateContextId() {
|
|
9
12
|
return CONTEXT_COUNTER++;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
type SurfacePointer = bigint;
|
|
13
|
-
|
|
14
|
-
export interface NativeCanvas {
|
|
15
|
-
surface: SurfacePointer;
|
|
16
|
-
width: number;
|
|
17
|
-
height: number;
|
|
18
|
-
clientWidth: number;
|
|
19
|
-
clientHeight: number;
|
|
20
|
-
// No-op DOM-compatibility stubs so web renderers (Three.js,
|
|
21
|
-
// react-three-fiber) can treat the canvas like an HTMLCanvasElement.
|
|
22
|
-
addEventListener(type: string, listener: EventListener): void;
|
|
23
|
-
removeEventListener(type: string, listener: EventListener): void;
|
|
24
|
-
dispatchEvent(event: Event): void;
|
|
25
|
-
setPointerCapture(pointerId: number): void;
|
|
26
|
-
releasePointerCapture(pointerId: number): void;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export type RNCanvasContext = GPUCanvasContext & {
|
|
30
|
-
/**
|
|
31
|
-
* Present the current frame.
|
|
32
|
-
*
|
|
33
|
-
* Call this after `queue.submit()` on every runtime: the main JS runtime, the
|
|
34
|
-
* Reanimated UI runtime, and dedicated worklet runtimes (e.g.
|
|
35
|
-
* `createWorkletRuntime` / `runOnRuntime`, or a Vision Camera frame
|
|
36
|
-
* processor). It runs synchronously on the calling thread, so the frame is
|
|
37
|
-
* presented from whichever thread did the rendering.
|
|
38
|
-
*/
|
|
39
|
-
present: () => void;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export interface CanvasRef {
|
|
43
|
-
getContextId: () => number;
|
|
44
|
-
getContext(contextName: "webgpu"): RNCanvasContext | null;
|
|
45
|
-
getNativeSurface: () => NativeCanvas;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
15
|
export type AndroidSurfaceType =
|
|
49
16
|
"SurfaceView" | "TextureView" | "HardwareBufferView";
|
|
50
17
|
|
package/src/index.tsx
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
import "./main/installNative";
|
|
10
10
|
|
|
11
11
|
import type {
|
|
12
|
+
GPUNativeBufferExternalTexture,
|
|
13
|
+
GPUNativeBufferExternalTextureDescriptor,
|
|
14
|
+
GPUNativeBufferTexture,
|
|
15
|
+
GPUNativeBufferTextureDescriptor,
|
|
12
16
|
GPUDrawElementImageDestination,
|
|
13
17
|
GPUDrawElementImageSource,
|
|
14
18
|
GPUSharedFence,
|
|
@@ -44,6 +48,13 @@ export type {
|
|
|
44
48
|
GPUCopyExternalNativeFrameSourceInfo,
|
|
45
49
|
GPUDawnTogglesDescriptor,
|
|
46
50
|
GPUNativeExternalTextureDescriptor,
|
|
51
|
+
NativeVideoFrameColorSpace,
|
|
52
|
+
GPUExtent2D,
|
|
53
|
+
GPUNativeBufferExternalTextureDescriptor,
|
|
54
|
+
GPUNativeBufferTextureDescriptor,
|
|
55
|
+
GPUNativeBufferWrapper,
|
|
56
|
+
GPUNativeBufferTexture,
|
|
57
|
+
GPUNativeBufferExternalTexture,
|
|
47
58
|
GPUDrawElementImageDestination,
|
|
48
59
|
GPUDrawElementImageSource,
|
|
49
60
|
GPUDrawElementImageSourceView,
|
|
@@ -120,6 +131,19 @@ declare global {
|
|
|
120
131
|
descriptor: GPUSharedTextureMemoryDescriptor,
|
|
121
132
|
): GPUSharedTextureMemory;
|
|
122
133
|
importSharedFence(descriptor: GPUSharedFenceDescriptor): GPUSharedFence;
|
|
134
|
+
// Non-spec RN extensions, the counterparts of createTexture /
|
|
135
|
+
// createExternalTexture in GPUAndroidHardwareBufferUtil of Dawn's Android
|
|
136
|
+
// layer: import a native buffer once, as a regular texture or as an
|
|
137
|
+
// external texture, and bracket each use with beginAccess() / endAccess()
|
|
138
|
+
// on the wrapper instead of importing the buffer again per frame.
|
|
139
|
+
createNativeBufferTexture(
|
|
140
|
+
source: NativeVideoFrame,
|
|
141
|
+
descriptor?: GPUNativeBufferTextureDescriptor,
|
|
142
|
+
): GPUNativeBufferTexture;
|
|
143
|
+
createNativeBufferExternalTexture(
|
|
144
|
+
source: NativeVideoFrame,
|
|
145
|
+
descriptor?: GPUNativeBufferExternalTextureDescriptor,
|
|
146
|
+
): GPUNativeBufferExternalTexture;
|
|
123
147
|
}
|
|
124
148
|
|
|
125
149
|
// Non-spec RN extension modeled on the html-in-canvas proposal's
|
package/src/types.ts
CHANGED
|
@@ -52,6 +52,13 @@ export type NativeVideoPixelFormat = "bgra8" | "nv12";
|
|
|
52
52
|
// - pixelFormat describes the surface layout: 'bgra8' for a sampled
|
|
53
53
|
// GPUTexture; 'nv12' (biplanar Y + CbCr) for the importExternalTexture
|
|
54
54
|
// path.
|
|
55
|
+
// - acquireFenceFd is the sync fd the producer of the frame (the decoder,
|
|
56
|
+
// the camera) signals once it has written the buffer, as a BigInt, on
|
|
57
|
+
// Android; null when the frame has none (Apple platforms, a released
|
|
58
|
+
// frame). importExternalTexture() waits for it on its own; a hardware
|
|
59
|
+
// buffer wrapper takes it through importSharedFence({ type: "sync-fd",
|
|
60
|
+
// handle }) in beginAccess(). The frame owns the descriptor: import it
|
|
61
|
+
// before release(), and never close it.
|
|
55
62
|
// - release() drops the underlying backing object (a CVPixelBuffer on Apple).
|
|
56
63
|
// The frame is also released when the JS wrapper is garbage-collected; call
|
|
57
64
|
// release() eagerly when you know you're done.
|
|
@@ -60,9 +67,31 @@ export interface NativeVideoFrame {
|
|
|
60
67
|
readonly width: number;
|
|
61
68
|
readonly height: number;
|
|
62
69
|
readonly pixelFormat: NativeVideoPixelFormat;
|
|
70
|
+
readonly acquireFenceFd: bigint | null;
|
|
63
71
|
release(): void;
|
|
64
72
|
}
|
|
65
73
|
|
|
74
|
+
// The color space of a YUV frame, the way its producer reports it: the YCbCr
|
|
75
|
+
// matrix and range that encode the samples, and the primaries and transfer
|
|
76
|
+
// function of the RGB they encode. Each member is optional; what is left out
|
|
77
|
+
// comes from the frame, then from the platform's best guess for the buffer.
|
|
78
|
+
export interface NativeVideoFrameColorSpace {
|
|
79
|
+
matrix?: "identity" | "rec601" | "rec709" | "rec2020";
|
|
80
|
+
range?: "identity" | "narrow" | "full";
|
|
81
|
+
primaries?: "srgb" | "rec709" | "rec601" | "rec2020" | "display-p3";
|
|
82
|
+
transfer?:
|
|
83
|
+
| "identity"
|
|
84
|
+
| "srgb"
|
|
85
|
+
| "display-p3"
|
|
86
|
+
| "smpte-170m"
|
|
87
|
+
| "hlg"
|
|
88
|
+
| "pq"
|
|
89
|
+
| "bt-1886";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// A 2D size, as { width, height } or [width, height].
|
|
93
|
+
export type GPUExtent2D = { width: number; height: number } | [number, number];
|
|
94
|
+
|
|
66
95
|
// GPUExternalTextureDescriptor with a NativeVideoFrame as the source: what
|
|
67
96
|
// GPUDevice.importExternalTexture() takes on React Native, where there is no
|
|
68
97
|
// HTMLVideoElement or WebCodecs VideoFrame. The other members (label,
|
|
@@ -72,6 +101,74 @@ export interface GPUNativeExternalTextureDescriptor extends Omit<
|
|
|
72
101
|
"source"
|
|
73
102
|
> {
|
|
74
103
|
source: NativeVideoFrame;
|
|
104
|
+
// Overrides the members of the frame's own color space, for a buffer that
|
|
105
|
+
// carries none (one wrapped from another library) or reports it wrong.
|
|
106
|
+
sourceColorSpace?: NativeVideoFrameColorSpace;
|
|
107
|
+
// The part of the frame the external texture shows, the whole frame by
|
|
108
|
+
// default (Dawn's cropOrigin / cropSize).
|
|
109
|
+
cropOrigin?: GPUOrigin2D;
|
|
110
|
+
cropSize?: GPUExtent2D;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// The descriptor of GPUDevice.createNativeBufferExternalTexture(): the same
|
|
114
|
+
// options as importExternalTexture(), without the source (the frame is the
|
|
115
|
+
// first argument).
|
|
116
|
+
export type GPUNativeBufferExternalTextureDescriptor = Omit<
|
|
117
|
+
GPUNativeExternalTextureDescriptor,
|
|
118
|
+
"source"
|
|
119
|
+
>;
|
|
120
|
+
|
|
121
|
+
// The options of GPUDevice.createNativeBufferTexture(). `usage` defaults to
|
|
122
|
+
// every usage the buffer allows, as GPUSharedTextureMemory.createTexture()
|
|
123
|
+
// without a descriptor.
|
|
124
|
+
export interface GPUNativeBufferTextureDescriptor {
|
|
125
|
+
usage?: GPUTextureUsageFlags;
|
|
126
|
+
label?: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// A native buffer imported once, with the access window of each use explicit:
|
|
130
|
+
// the counterpart of GPUHardwareBufferWrapper in Dawn's Android layer
|
|
131
|
+
// (androidx.webgpu). A decoder or a camera renders into the same few buffers
|
|
132
|
+
// in turn; keep one wrapper per buffer (keyed by NativeVideoFrame.handle), and
|
|
133
|
+
// bracket each frame with beginAccess() / endAccess() instead of importing it
|
|
134
|
+
// again. The wrapper keeps the frame it was created from alive until
|
|
135
|
+
// destroy().
|
|
136
|
+
export interface GPUNativeBufferWrapper {
|
|
137
|
+
label: string;
|
|
138
|
+
// Begins an access to the buffer: the GPU waits for each fence to reach its
|
|
139
|
+
// signaledValue first (the producer's fence for the frame, e.g. the frame's
|
|
140
|
+
// acquireFenceFd imported with importSharedFence, 1n for a sync fd). Throws,
|
|
141
|
+
// after a validation error, on a destroyed wrapper or fence, and if Dawn
|
|
142
|
+
// rejects the access (one is already open).
|
|
143
|
+
beginAccess(fences?: GPUSharedFenceState[]): void;
|
|
144
|
+
// Ends the access, after the queue.submit() that used the buffer, and
|
|
145
|
+
// returns the one fence that signals once that GPU work is done (on Android,
|
|
146
|
+
// the sync fds of the access merged into one), or null when there is none.
|
|
147
|
+
// Hand it to the producer before it reuses the buffer, or destroy it.
|
|
148
|
+
endAccess(): GPUSharedFenceState | null;
|
|
149
|
+
// Releases the import (and the frame) now rather than when the object is
|
|
150
|
+
// garbage collected. An access still open is a validation error; it is
|
|
151
|
+
// ended, and its fence is lost. A later use is a validation error and a
|
|
152
|
+
// throw.
|
|
153
|
+
destroy(): void;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// A color buffer (an RGBA / R8 / ... AHardwareBuffer, a BGRA IOSurface)
|
|
157
|
+
// imported once as a regular texture. Bind `texture` only between
|
|
158
|
+
// beginAccess() and endAccess().
|
|
159
|
+
export interface GPUNativeBufferTexture extends GPUNativeBufferWrapper {
|
|
160
|
+
readonly __brand: "GPUNativeBufferTexture";
|
|
161
|
+
readonly texture: GPUTexture;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// A frame buffer (the YUV AHardwareBuffer of a decoder or a camera, an NV12 or
|
|
165
|
+
// BGRA IOSurface) imported once as an external texture, color conversion
|
|
166
|
+
// included. Bind `externalTexture` only between beginAccess() and endAccess();
|
|
167
|
+
// destroying it on its own (externalTexture.destroy()) only releases the
|
|
168
|
+
// external texture, the wrapper keeps the import.
|
|
169
|
+
export interface GPUNativeBufferExternalTexture extends GPUNativeBufferWrapper {
|
|
170
|
+
readonly __brand: "GPUNativeBufferExternalTexture";
|
|
171
|
+
readonly externalTexture: GPUExternalTexture;
|
|
75
172
|
}
|
|
76
173
|
|
|
77
174
|
// A decoded video, modeled on HTMLMediaElement: play(), pause(), paused,
|