-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathutils.ts
More file actions
123 lines (114 loc) · 3.09 KB
/
utils.ts
File metadata and controls
123 lines (114 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { useEffect, useState } from 'react';
import {
runOnUI,
scheduleOnRuntime,
type WorkletRuntime,
} from 'react-native-worklets';
import { WebGPURenderer } from 'three/webgpu';
export function initWebGPU(runtime: WorkletRuntime) {
const navigator = globalThis.navigator as NavigatorGPU;
const GPUBufferUsage = globalThis.GPUBufferUsage;
const GPUColorWrite = globalThis.GPUColorWrite;
const GPUMapMode = globalThis.GPUMapMode;
const GPUShaderStage = globalThis.GPUShaderStage;
const GPUTextureUsage = globalThis.GPUTextureUsage;
scheduleOnRuntime(runtime, () => {
'worklet';
if (globalThis.self) {
return;
}
globalThis.self = globalThis;
globalThis.navigator = { gpu: navigator.gpu } as NavigatorGPU;
globalThis.GPUBufferUsage = GPUBufferUsage;
globalThis.GPUColorWrite = GPUColorWrite;
globalThis.GPUMapMode = GPUMapMode;
globalThis.GPUShaderStage = GPUShaderStage;
globalThis.GPUTextureUsage = GPUTextureUsage;
globalThis.setImmediate =
globalThis.requestAnimationFrame as typeof setImmediate;
});
}
export function makeWebGPURenderer(
context: GPUCanvasContext,
device?: GPUDevice,
{ antialias = true }: { antialias?: boolean } = {},
): WebGPURenderer {
'worklet';
class ReactNativeCanvas {
#canvas: any;
constructor(canvas: any) {
this.#canvas = canvas;
}
get width() {
return this.#canvas.width;
}
set width(width: number) {
this.#canvas.width = width;
}
get height() {
return this.#canvas.height;
}
set height(height: number) {
this.#canvas.height = height;
}
get clientWidth() {
return this.#canvas.width;
}
set clientWidth(width: number) {
this.#canvas.width = width;
}
get clientHeight() {
return this.#canvas.height;
}
set clientHeight(height: number) {
this.#canvas.height = height;
}
addEventListener(_type: any, _listener: any) {}
removeEventListener(_type: any, _listener: any) {}
dispatchEvent(_event: any) {}
setPointerCapture() {}
releasePointerCapture() {}
getContext(type: string): GPUCanvasContext | null {
if (type === 'webgpu') {
return context;
}
return null;
}
}
return new WebGPURenderer({
antialias,
canvas: new ReactNativeCanvas(context.canvas),
context,
device,
});
}
export function useBusyJS() {
const [working, setWorking] = useState(false);
useEffect(() => {
if (!working) {
return;
}
let job = requestAnimationFrame(work);
function work() {
const sleepTime = 250;
const now = performance.now();
while (performance.now() - now < sleepTime) {
// Busy-wait for a short time to simulate work
}
job = requestAnimationFrame(work);
}
return () => {
cancelAnimationFrame(job);
};
}, [working]);
return function toggleWorking() {
setWorking(prev => !prev);
};
}
declare global {
var self: typeof globalThis;
var navigator: NavigatorGPU;
var renderer: WebGPURenderer | null;
var lastFrame: number;
var _WORKLET: boolean | undefined;
}