react-native-wgpu 0.1.8 → 0.1.9
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/cpp/cpp-adapter.cpp +13 -35
- package/android/src/main/java/com/webgpu/WebGPUModule.java +0 -37
- package/android/src/main/java/com/webgpu/WebGPUView.java +0 -1
- package/android/src/main/java/com/webgpu/WebGPUViewPackage.java +1 -1
- package/cpp/rnwgpu/RNWebGPUManager.h +2 -2
- package/cpp/rnwgpu/SurfaceRegistry.h +148 -13
- package/cpp/rnwgpu/api/Canvas.h +15 -15
- package/cpp/rnwgpu/api/GPUCanvasContext.cpp +81 -23
- package/cpp/rnwgpu/api/GPUCanvasContext.h +16 -7
- package/cpp/rnwgpu/api/GPUDevice.cpp +3 -2
- package/cpp/rnwgpu/api/OffscreenSurface.h +49 -0
- package/cpp/rnwgpu/api/RNWebGPU.h +21 -10
- package/ios/MetalView.mm +11 -0
- package/ios/SurfaceUtils.h +2 -0
- package/ios/SurfaceUtils.mm +16 -4
- package/ios/WebGPUModule.mm +8 -25
- package/ios/WebGPUView.mm +9 -6
- package/lib/commonjs/Canvas.js +79 -18
- package/lib/commonjs/Canvas.js.map +1 -1
- package/lib/commonjs/Offscreen.js +3 -0
- package/lib/commonjs/Offscreen.js.map +1 -1
- package/lib/commonjs/utils.js +26 -15
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/module/Canvas.js +80 -19
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/Offscreen.js +3 -0
- package/lib/module/Offscreen.js.map +1 -1
- package/lib/module/utils.js +25 -15
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/lib/commonjs/Offscreen.d.ts +1 -0
- package/lib/typescript/lib/commonjs/Offscreen.d.ts.map +1 -1
- package/lib/typescript/lib/commonjs/utils.d.ts +5 -1
- package/lib/typescript/lib/commonjs/utils.d.ts.map +1 -1
- package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
- package/lib/typescript/lib/module/Offscreen.d.ts +1 -0
- package/lib/typescript/lib/module/Offscreen.d.ts.map +1 -1
- package/lib/typescript/lib/module/utils.d.ts +5 -1
- package/lib/typescript/lib/module/utils.d.ts.map +1 -1
- package/lib/typescript/src/Canvas.d.ts +4 -2
- package/lib/typescript/src/Canvas.d.ts.map +1 -1
- package/lib/typescript/src/Offscreen.d.ts +16 -1
- package/lib/typescript/src/Offscreen.d.ts.map +1 -1
- package/lib/typescript/src/utils.d.ts +6 -3
- package/lib/typescript/src/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Canvas.tsx +99 -35
- package/src/Offscreen.ts +6 -2
- package/src/utils.ts +28 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Offscreen.d.ts","sourceRoot":"","sources":["../../../commonjs/Offscreen.js"],"names":[],"mappings":";AAOA;IAGE,qCAIC;IAND,oBAAqB;IACrB,wBAAyB;IAEvB,WAAkB;IAClB,YAAoB;IACpB,mCAAkD;IAEpD,mCAGC;IAID,4EAMC;IACD,8BAGC;IACD,kEAGC;IACD,qEAGC;IACD,iCAGC;IACD,oBA4BC;CACF;AAED;IAIE,yBAGC;IAND,gBAA6B;IAC7B,cAAe;IACf,aAAc;IAEZ,YAAoB;IACpB,gCAA6D;IAE/D,mBAKC;IACD,oBAKC;IACD,kCASC;IACD,yBAMC;IACD,2BAKC;CACF"}
|
|
1
|
+
{"version":3,"file":"Offscreen.d.ts","sourceRoot":"","sources":["../../../commonjs/Offscreen.js"],"names":[],"mappings":";AAOA;IAGE,qCAIC;IAND,oBAAqB;IACrB,wBAAyB;IAEvB,WAAkB;IAClB,YAAoB;IACpB,mCAAkD;IAEpD,mCAGC;IAID,4EAMC;IACD,8BAGC;IACD,kEAGC;IACD,qEAGC;IACD,iCAGC;IACD,oBA4BC;CACF;AAED;IAIE,yBAGC;IAND,gBAA6B;IAC7B,cAAe;IACf,aAAc;IAEZ,YAAoB;IACpB,gCAA6D;IAE/D,gBAEC;IACD,mBAKC;IACD,oBAKC;IACD,kCASC;IACD,yBAMC;IACD,2BAKC;CACF"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export const __esModule: boolean;
|
|
2
2
|
export function warnIfNotHardwareAccelerated(adapter: any): void;
|
|
3
|
-
export function
|
|
3
|
+
export function useGPUContext(): {
|
|
4
|
+
ref: _react.MutableRefObject<null>;
|
|
5
|
+
context: null;
|
|
6
|
+
};
|
|
7
|
+
export function useCanvasEffect(effect: any): _react.MutableRefObject<null>;
|
|
4
8
|
import _react = require("react");
|
|
5
9
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../commonjs/utils.js"],"names":[],"mappings":";AAOA,iEAIC;AAED,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../commonjs/utils.js"],"names":[],"mappings":";AAOA,iEAIC;AAED;;;EAUC;AAED,4EAsBC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../module/Canvas.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../module/Canvas.js"],"names":[],"mappings":"AAgDA,mGAmDG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Offscreen.d.ts","sourceRoot":"","sources":["../../../module/Offscreen.js"],"names":[],"mappings":"AACA;IAGE,qCAIC;IAND,oBAAqB;IACrB,wBAAyB;IAEvB,WAAkB;IAClB,YAAoB;IACpB,mCAAkD;IAEpD,mCAGC;IAID,4EAMC;IACD,8BAGC;IACD,kEAGC;IACD,qEAGC;IACD,iCAGC;IACD,oBA4BC;CACF;AACD;IAIE,yBAGC;IAND,gBAA6B;IAC7B,cAAe;IACf,aAAc;IAEZ,YAAoB;IACpB,gCAA6D;IAE/D,mBAKC;IACD,oBAKC;IACD,kCASC;IACD,yBAMC;IACD,2BAKC;CACF"}
|
|
1
|
+
{"version":3,"file":"Offscreen.d.ts","sourceRoot":"","sources":["../../../module/Offscreen.js"],"names":[],"mappings":"AACA;IAGE,qCAIC;IAND,oBAAqB;IACrB,wBAAyB;IAEvB,WAAkB;IAClB,YAAoB;IACpB,mCAAkD;IAEpD,mCAGC;IAID,4EAMC;IACD,8BAGC;IACD,kEAGC;IACD,qEAGC;IACD,iCAGC;IACD,oBA4BC;CACF;AACD;IAIE,yBAGC;IAND,gBAA6B;IAC7B,cAAe;IACf,aAAc;IAEZ,YAAoB;IACpB,gCAA6D;IAE/D,gBAEC;IACD,mBAKC;IACD,oBAKC;IACD,kCASC;IACD,yBAMC;IACD,2BAKC;CACF"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
export function warnIfNotHardwareAccelerated(adapter: any): void;
|
|
2
|
-
export function
|
|
2
|
+
export function useGPUContext(): {
|
|
3
|
+
ref: import("react").MutableRefObject<null>;
|
|
4
|
+
context: null;
|
|
5
|
+
};
|
|
6
|
+
export function useCanvasEffect(effect: any): import("react").MutableRefObject<null>;
|
|
3
7
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../module/utils.js"],"names":[],"mappings":"AACO,iEAIN;AACM,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../module/utils.js"],"names":[],"mappings":"AACO,iEAIN;AACM;;;EAUN;AACM,qFAsBN"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { ViewProps } from "react-native";
|
|
2
2
|
declare global {
|
|
3
|
-
var __WebGPUContextRegistry: Record<number, NativeCanvas>;
|
|
4
3
|
var RNWebGPU: {
|
|
5
4
|
gpu: GPU;
|
|
6
|
-
|
|
5
|
+
fabric: boolean;
|
|
6
|
+
getNativeSurface: (contextId: number) => NativeCanvas;
|
|
7
|
+
MakeWebGPUCanvasContext: (contextId: number, width: number, height: number) => RNCanvasContext;
|
|
7
8
|
DecodeToUTF8: (buffer: NodeJS.ArrayBufferView | ArrayBuffer) => string;
|
|
8
9
|
createImageBitmap: typeof createImageBitmap;
|
|
9
10
|
};
|
|
@@ -22,6 +23,7 @@ export type RNCanvasContext = GPUCanvasContext & {
|
|
|
22
23
|
export interface CanvasRef {
|
|
23
24
|
getContext(contextName: "webgpu"): RNCanvasContext | null;
|
|
24
25
|
getNativeSurface: () => NativeCanvas;
|
|
26
|
+
whenReady: (callback: () => void) => void;
|
|
25
27
|
}
|
|
26
28
|
export declare const Canvas: import("react").ForwardRefExoticComponent<ViewProps & import("react").RefAttributes<CanvasRef>>;
|
|
27
29
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../src/Canvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../../src/Canvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAqB,MAAM,cAAc,CAAC;AAoBjE,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,QAAQ,EAAE;QACZ,GAAG,EAAE,GAAG,CAAC;QACT,MAAM,EAAE,OAAO,CAAC;QAChB,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,YAAY,CAAC;QACtD,uBAAuB,EAAE,CACvB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,KACX,eAAe,CAAC;QACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,eAAe,GAAG,WAAW,KAAK,MAAM,CAAC;QACvE,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;KAC7C,CAAC;CACH;AAED,KAAK,cAAc,GAAG,MAAM,CAAC;AAE7B,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG;IAC/C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,WAAW,EAAE,QAAQ,GAAG,eAAe,GAAG,IAAI,CAAC;IAC1D,gBAAgB,EAAE,MAAM,YAAY,CAAC;IACrC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC3C;AAqCD,eAAO,MAAM,MAAM,iGA+ClB,CAAC"}
|
|
@@ -11,7 +11,7 @@ export declare class GPUOffscreenCanvas implements OffscreenCanvas {
|
|
|
11
11
|
getContext(contextId: "webgl", options?: any): WebGLRenderingContext | null;
|
|
12
12
|
getContext(contextId: "webgl2", options?: any): WebGL2RenderingContext | null;
|
|
13
13
|
getContext(contextId: OffscreenRenderingContextId, options?: any): OffscreenRenderingContext | null;
|
|
14
|
-
getContext(contextId: "webgpu"):
|
|
14
|
+
getContext(contextId: "webgpu"): GPUOffscreenCanvasContext | null;
|
|
15
15
|
transferToImageBitmap(): ImageBitmap;
|
|
16
16
|
addEventListener<K extends keyof OffscreenCanvasEventMap>(_type: K, _listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any, _options?: boolean | AddEventListenerOptions): void;
|
|
17
17
|
removeEventListener<K extends keyof OffscreenCanvasEventMap>(_type: K, _listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any, _options?: boolean | EventListenerOptions): void;
|
|
@@ -23,4 +23,19 @@ export declare class GPUOffscreenCanvas implements OffscreenCanvas {
|
|
|
23
23
|
format: GPUTextureFormat;
|
|
24
24
|
}>;
|
|
25
25
|
}
|
|
26
|
+
declare class GPUOffscreenCanvasContext implements GPUCanvasContext {
|
|
27
|
+
readonly canvas: OffscreenCanvas;
|
|
28
|
+
__brand: "GPUCanvasContext";
|
|
29
|
+
private textureFormat;
|
|
30
|
+
private texture;
|
|
31
|
+
private device;
|
|
32
|
+
constructor(canvas: OffscreenCanvas);
|
|
33
|
+
present(): void;
|
|
34
|
+
getDevice(): GPUDevice;
|
|
35
|
+
getTexture(): GPUTexture;
|
|
36
|
+
configure(config: GPUCanvasConfiguration): undefined;
|
|
37
|
+
unconfigure(): undefined;
|
|
38
|
+
getCurrentTexture(): GPUTexture;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
26
41
|
//# sourceMappingURL=Offscreen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Offscreen.d.ts","sourceRoot":"","sources":["../../../src/Offscreen.ts"],"names":[],"mappings":"AACA,qBAAa,kBAAmB,YAAW,eAAe;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,KAAK,GAAG,CAAC,GAAG,IAAI,CAAQ;IACzE,iBAAiB,EAAE,CAAC,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,KAAK,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE7E,OAAO,CAAC,OAAO,CAA4B;gBAE/B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAMzC,aAAa,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3D,UAAU,CACR,SAAS,EAAE,IAAI,EACf,OAAO,CAAC,EAAE,GAAG,GACZ,iCAAiC,GAAG,IAAI;IAC3C,UAAU,CACR,SAAS,EAAE,gBAAgB,EAC3B,OAAO,CAAC,EAAE,GAAG,GACZ,2BAA2B,GAAG,IAAI;IACrC,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,qBAAqB,GAAG,IAAI;IAC3E,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,sBAAsB,GAAG,IAAI;IAC7E,UAAU,CACR,SAAS,EAAE,2BAA2B,EACtC,OAAO,CAAC,EAAE,GAAG,GACZ,yBAAyB,GAAG,IAAI;IACnC,UAAU,CAAC,SAAS,EAAE,QAAQ,GAAG,
|
|
1
|
+
{"version":3,"file":"Offscreen.d.ts","sourceRoot":"","sources":["../../../src/Offscreen.ts"],"names":[],"mappings":"AACA,qBAAa,kBAAmB,YAAW,eAAe;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,KAAK,GAAG,CAAC,GAAG,IAAI,CAAQ;IACzE,iBAAiB,EAAE,CAAC,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,KAAK,GAAG,CAAC,GAAG,IAAI,CAAQ;IAE7E,OAAO,CAAC,OAAO,CAA4B;gBAE/B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAMzC,aAAa,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3D,UAAU,CACR,SAAS,EAAE,IAAI,EACf,OAAO,CAAC,EAAE,GAAG,GACZ,iCAAiC,GAAG,IAAI;IAC3C,UAAU,CACR,SAAS,EAAE,gBAAgB,EAC3B,OAAO,CAAC,EAAE,GAAG,GACZ,2BAA2B,GAAG,IAAI;IACrC,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,qBAAqB,GAAG,IAAI;IAC3E,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,sBAAsB,GAAG,IAAI;IAC7E,UAAU,CACR,SAAS,EAAE,2BAA2B,EACtC,OAAO,CAAC,EAAE,GAAG,GACZ,yBAAyB,GAAG,IAAI;IACnC,UAAU,CAAC,SAAS,EAAE,QAAQ,GAAG,yBAAyB,GAAG,IAAI;IAYjE,qBAAqB,IAAI,WAAW;IAKpC,gBAAgB,CAAC,CAAC,SAAS,MAAM,uBAAuB,EACtD,KAAK,EAAE,CAAC,EACR,SAAS,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAAK,GAAG,EACzE,QAAQ,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC3C,IAAI;IAKP,mBAAmB,CAAC,CAAC,SAAS,MAAM,uBAAuB,EACzD,KAAK,EAAE,CAAC,EACR,SAAS,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAAK,GAAG,EACzE,QAAQ,CAAC,EAAE,OAAO,GAAG,oBAAoB,GACxC,IAAI;IAKP,aAAa,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO;IAKrC,YAAY;;;;;;CA6Bb;AAED,cAAM,yBAA0B,YAAW,gBAAgB;aAO7B,MAAM,EAAE,eAAe;IANnD,OAAO,qBAA+B;IAEtC,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAA0B;gBAEZ,MAAM,EAAE,eAAe;IAInD,OAAO;IAIP,SAAS;IAOT,UAAU;IAOV,SAAS,CAAC,MAAM,EAAE,sBAAsB;IAcxC,WAAW;IAQX,iBAAiB,IAAI,UAAU;CAMhC"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { CanvasRef } from "./Canvas";
|
|
1
|
+
import type { RNCanvasContext, CanvasRef } from "./Canvas";
|
|
3
2
|
type Unsubscribe = () => void;
|
|
4
3
|
export declare const warnIfNotHardwareAccelerated: (adapter: GPUAdapter) => void;
|
|
5
|
-
export declare const
|
|
4
|
+
export declare const useGPUContext: () => {
|
|
5
|
+
ref: import("react").RefObject<CanvasRef>;
|
|
6
|
+
context: RNCanvasContext | null;
|
|
7
|
+
};
|
|
8
|
+
export declare const useCanvasEffect: (effect: () => void | Unsubscribe | Promise<Unsubscribe | void> | Promise<void>) => import("react").RefObject<CanvasRef>;
|
|
6
9
|
export {};
|
|
7
10
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE3D,KAAK,WAAW,GAAG,MAAM,IAAI,CAAC;AAE9B,eAAO,MAAM,4BAA4B,YAAa,UAAU,SAM/D,CAAC;AAEF,eAAO,MAAM,aAAa;;;CAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,WAClB,MACJ,IAAI,GACJ,WAAW,GACX,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,yCAuBlB,CAAC"}
|
package/package.json
CHANGED
package/src/Canvas.tsx
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import type { ViewProps } from "react-native";
|
|
2
|
-
import {
|
|
1
|
+
import type { ViewProps, LayoutChangeEvent } from "react-native";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import {
|
|
4
|
+
forwardRef,
|
|
5
|
+
useEffect,
|
|
6
|
+
useImperativeHandle,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
useLayoutEffect,
|
|
10
|
+
useCallback,
|
|
11
|
+
} from "react";
|
|
12
|
+
import type { RefObject } from "react";
|
|
3
13
|
|
|
4
14
|
import WebGPUNativeView from "./WebGPUViewNativeComponent";
|
|
5
|
-
import WebGPUNativeModule from "./NativeWebGPUModule";
|
|
6
15
|
|
|
7
16
|
let CONTEXT_COUNTER = 1;
|
|
8
17
|
function generateContextId() {
|
|
@@ -10,12 +19,16 @@ function generateContextId() {
|
|
|
10
19
|
}
|
|
11
20
|
|
|
12
21
|
declare global {
|
|
13
|
-
// eslint-disable-next-line no-var
|
|
14
|
-
var __WebGPUContextRegistry: Record<number, NativeCanvas>;
|
|
15
22
|
// eslint-disable-next-line no-var
|
|
16
23
|
var RNWebGPU: {
|
|
17
24
|
gpu: GPU;
|
|
18
|
-
|
|
25
|
+
fabric: boolean;
|
|
26
|
+
getNativeSurface: (contextId: number) => NativeCanvas;
|
|
27
|
+
MakeWebGPUCanvasContext: (
|
|
28
|
+
contextId: number,
|
|
29
|
+
width: number,
|
|
30
|
+
height: number,
|
|
31
|
+
) => RNCanvasContext;
|
|
19
32
|
DecodeToUTF8: (buffer: NodeJS.ArrayBufferView | ArrayBuffer) => string;
|
|
20
33
|
createImageBitmap: typeof createImageBitmap;
|
|
21
34
|
};
|
|
@@ -31,9 +44,6 @@ export interface NativeCanvas {
|
|
|
31
44
|
clientHeight: number;
|
|
32
45
|
}
|
|
33
46
|
|
|
34
|
-
global.__WebGPUContextRegistry = {};
|
|
35
|
-
const WebGPUContextRegistry = global.__WebGPUContextRegistry;
|
|
36
|
-
|
|
37
47
|
export type RNCanvasContext = GPUCanvasContext & {
|
|
38
48
|
present: () => void;
|
|
39
49
|
};
|
|
@@ -41,35 +51,89 @@ export type RNCanvasContext = GPUCanvasContext & {
|
|
|
41
51
|
export interface CanvasRef {
|
|
42
52
|
getContext(contextName: "webgpu"): RNCanvasContext | null;
|
|
43
53
|
getNativeSurface: () => NativeCanvas;
|
|
54
|
+
whenReady: (callback: () => void) => void;
|
|
44
55
|
}
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
interface Size {
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
}
|
|
48
61
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
const useSizeFabric = (ref: RefObject<View>) => {
|
|
63
|
+
const [size, setSize] = useState<null | Size>(null);
|
|
64
|
+
useLayoutEffect(() => {
|
|
65
|
+
if (!ref.current) {
|
|
66
|
+
throw new Error("Canvas ref is null");
|
|
67
|
+
}
|
|
68
|
+
ref.current.measureInWindow((_x, _y, width, height) => {
|
|
69
|
+
setSize({ width, height });
|
|
70
|
+
});
|
|
71
|
+
}, [ref]);
|
|
72
|
+
return { size, onLayout: undefined };
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const useSizePaper = (_ref: RefObject<View>) => {
|
|
76
|
+
const [size, setSize] = useState<null | Size>(null);
|
|
77
|
+
const onLayout = useCallback<(event: LayoutChangeEvent) => void>(
|
|
78
|
+
({
|
|
79
|
+
nativeEvent: {
|
|
80
|
+
layout: { width, height },
|
|
81
|
+
},
|
|
82
|
+
}) => {
|
|
83
|
+
if (size === null) {
|
|
84
|
+
setSize({ width, height });
|
|
62
85
|
}
|
|
63
|
-
const ctx = RNWebGPU.MakeWebGPUCanvasContext(nativeSurface);
|
|
64
|
-
return ctx;
|
|
65
86
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
delete WebGPUContextRegistry[contextId];
|
|
71
|
-
};
|
|
72
|
-
}, [contextId]);
|
|
87
|
+
[size],
|
|
88
|
+
);
|
|
89
|
+
return { size, onLayout };
|
|
90
|
+
};
|
|
73
91
|
|
|
74
|
-
|
|
75
|
-
})
|
|
92
|
+
export const Canvas = forwardRef<CanvasRef, ViewProps>(
|
|
93
|
+
({ onLayout: _onLayout, ...props }, ref) => {
|
|
94
|
+
const viewRef = useRef(null);
|
|
95
|
+
const FABRIC = RNWebGPU.fabric;
|
|
96
|
+
const useSize = FABRIC ? useSizeFabric : useSizePaper;
|
|
97
|
+
const [contextId, _] = useState(() => generateContextId());
|
|
98
|
+
const cb = useRef<() => void>();
|
|
99
|
+
const { size, onLayout } = useSize(viewRef);
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (size && cb.current) {
|
|
102
|
+
cb.current();
|
|
103
|
+
}
|
|
104
|
+
}, [size]);
|
|
105
|
+
useImperativeHandle(ref, () => ({
|
|
106
|
+
getNativeSurface: () => {
|
|
107
|
+
if (size === null) {
|
|
108
|
+
throw new Error("[WebGPU] Canvas size is not available yet");
|
|
109
|
+
}
|
|
110
|
+
return RNWebGPU.getNativeSurface(contextId);
|
|
111
|
+
},
|
|
112
|
+
whenReady(callback: () => void) {
|
|
113
|
+
if (size === null) {
|
|
114
|
+
cb.current = callback;
|
|
115
|
+
} else {
|
|
116
|
+
callback();
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
getContext(contextName: "webgpu"): RNCanvasContext | null {
|
|
120
|
+
if (contextName !== "webgpu") {
|
|
121
|
+
throw new Error(`[WebGPU] Unsupported context: ${contextName}`);
|
|
122
|
+
}
|
|
123
|
+
if (size === null) {
|
|
124
|
+
throw new Error("[WebGPU] Canvas size is not available yet");
|
|
125
|
+
}
|
|
126
|
+
return RNWebGPU.MakeWebGPUCanvasContext(
|
|
127
|
+
contextId,
|
|
128
|
+
size.width,
|
|
129
|
+
size.height,
|
|
130
|
+
);
|
|
131
|
+
},
|
|
132
|
+
}));
|
|
133
|
+
return (
|
|
134
|
+
<View ref={viewRef} onLayout={onLayout} {...props}>
|
|
135
|
+
<WebGPUNativeView style={{ flex: 1 }} contextId={contextId} />
|
|
136
|
+
</View>
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
);
|
package/src/Offscreen.ts
CHANGED
|
@@ -33,11 +33,11 @@ export class GPUOffscreenCanvas implements OffscreenCanvas {
|
|
|
33
33
|
contextId: OffscreenRenderingContextId,
|
|
34
34
|
options?: any,
|
|
35
35
|
): OffscreenRenderingContext | null;
|
|
36
|
-
getContext(contextId: "webgpu"):
|
|
36
|
+
getContext(contextId: "webgpu"): GPUOffscreenCanvasContext | null;
|
|
37
37
|
getContext(
|
|
38
38
|
contextId: unknown,
|
|
39
39
|
_options?: any,
|
|
40
|
-
): OffscreenRenderingContext |
|
|
40
|
+
): OffscreenRenderingContext | GPUOffscreenCanvasContext | null {
|
|
41
41
|
if (contextId === "webgpu") {
|
|
42
42
|
return this.context;
|
|
43
43
|
}
|
|
@@ -115,6 +115,10 @@ class GPUOffscreenCanvasContext implements GPUCanvasContext {
|
|
|
115
115
|
this.textureFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
present() {
|
|
119
|
+
// Do nothing
|
|
120
|
+
}
|
|
121
|
+
|
|
118
122
|
getDevice() {
|
|
119
123
|
if (!this.device) {
|
|
120
124
|
throw new Error("Device is not configured.");
|
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useEffect, useRef } from "react";
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
2
|
|
|
4
|
-
import type { CanvasRef } from "./Canvas";
|
|
3
|
+
import type { RNCanvasContext, CanvasRef } from "./Canvas";
|
|
5
4
|
|
|
6
5
|
type Unsubscribe = () => void;
|
|
7
6
|
|
|
@@ -13,30 +12,41 @@ export const warnIfNotHardwareAccelerated = (adapter: GPUAdapter) => {
|
|
|
13
12
|
}
|
|
14
13
|
};
|
|
15
14
|
|
|
15
|
+
export const useGPUContext = () => {
|
|
16
|
+
const [context, setContext] = useState<RNCanvasContext | null>(null);
|
|
17
|
+
const ref = useCanvasEffect(() => {
|
|
18
|
+
const ctx = ref.current!.getContext("webgpu")!;
|
|
19
|
+
setContext(ctx);
|
|
20
|
+
});
|
|
21
|
+
return { ref, context };
|
|
22
|
+
};
|
|
23
|
+
|
|
16
24
|
export const useCanvasEffect = (
|
|
17
|
-
effect: () =>
|
|
18
|
-
|
|
25
|
+
effect: () =>
|
|
26
|
+
| void
|
|
27
|
+
| Unsubscribe
|
|
28
|
+
| Promise<Unsubscribe | void>
|
|
29
|
+
| Promise<void>,
|
|
19
30
|
) => {
|
|
31
|
+
const unsub = useRef<Unsubscribe | null | Promise<Unsubscribe | void>>(null);
|
|
20
32
|
const ref = useRef<CanvasRef>(null);
|
|
21
|
-
const unsubscribe = useRef<Unsubscribe>();
|
|
22
33
|
useEffect(() => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// }
|
|
28
|
-
// const device = await adapter.requestDevice();
|
|
29
|
-
const unsub = await effect();
|
|
30
|
-
if (unsub) {
|
|
31
|
-
unsubscribe.current = unsub;
|
|
34
|
+
ref.current!.whenReady(async () => {
|
|
35
|
+
const sub = effect();
|
|
36
|
+
if (sub) {
|
|
37
|
+
unsub.current = sub;
|
|
32
38
|
}
|
|
33
39
|
});
|
|
34
40
|
return () => {
|
|
35
|
-
if (
|
|
36
|
-
|
|
41
|
+
if (unsub.current) {
|
|
42
|
+
if (unsub.current instanceof Promise) {
|
|
43
|
+
unsub.current.then((sub) => sub && sub());
|
|
44
|
+
} else {
|
|
45
|
+
unsub.current();
|
|
46
|
+
}
|
|
37
47
|
}
|
|
38
48
|
};
|
|
39
49
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
-
},
|
|
50
|
+
}, []);
|
|
41
51
|
return ref;
|
|
42
52
|
};
|