react-native-wgpu 0.1.4 → 0.1.6

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.
Files changed (167) hide show
  1. package/README.md +43 -42
  2. package/android/cpp/AndroidPlatformContext.h +2 -1
  3. package/cpp/jsi/RNFJSIConverter.h +10 -0
  4. package/cpp/rnwgpu/SurfaceRegistry.h +1 -2
  5. package/cpp/rnwgpu/api/Canvas.h +3 -3
  6. package/cpp/rnwgpu/api/GPUBuffer.h +1 -1
  7. package/ios/WebGPUView.mm +14 -1
  8. package/lib/commonjs/Canvas.js.map +1 -1
  9. package/lib/commonjs/utils.js +2 -2
  10. package/lib/commonjs/utils.js.map +1 -1
  11. package/lib/module/Canvas.js.map +1 -1
  12. package/lib/module/utils.js +2 -2
  13. package/lib/module/utils.js.map +1 -1
  14. package/lib/typescript/lib/commonjs/utils.d.ts +1 -1
  15. package/lib/typescript/lib/commonjs/utils.d.ts.map +1 -1
  16. package/lib/typescript/lib/module/utils.d.ts +1 -1
  17. package/lib/typescript/lib/module/utils.d.ts.map +1 -1
  18. package/lib/typescript/src/Canvas.d.ts +3 -2
  19. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  20. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +2 -0
  21. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +1 -0
  22. package/lib/typescript/src/__tests__/Buffer.spec.d.ts +2 -0
  23. package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +1 -0
  24. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +2 -0
  25. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +1 -0
  26. package/lib/typescript/src/__tests__/Constants.spec.d.ts +2 -0
  27. package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +1 -0
  28. package/lib/typescript/src/__tests__/Device.spec.d.ts +2 -0
  29. package/lib/typescript/src/__tests__/Device.spec.d.ts.map +1 -0
  30. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +2 -0
  31. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +1 -0
  32. package/lib/typescript/src/__tests__/GPU.spec.d.ts +2 -0
  33. package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +1 -0
  34. package/lib/typescript/src/__tests__/ImageData.spec.d.ts +2 -0
  35. package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +1 -0
  36. package/lib/typescript/src/__tests__/Shaders.spec.d.ts +2 -0
  37. package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +1 -0
  38. package/lib/typescript/src/__tests__/Texture.spec.d.ts +2 -0
  39. package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +1 -0
  40. package/lib/typescript/src/__tests__/components/DrawingContext.d.ts +12 -0
  41. package/lib/typescript/src/__tests__/components/DrawingContext.d.ts.map +1 -0
  42. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +3 -0
  43. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +1 -0
  44. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +29 -0
  45. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +1 -0
  46. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +5 -0
  47. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +1 -0
  48. package/lib/typescript/src/__tests__/components/cube.d.ts +7 -0
  49. package/lib/typescript/src/__tests__/components/cube.d.ts.map +1 -0
  50. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +22 -0
  51. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +1 -0
  52. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +12 -0
  53. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +1 -0
  54. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +7 -0
  55. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +1 -0
  56. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +6 -0
  57. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +1 -0
  58. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +6 -0
  59. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +1 -0
  60. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +10 -0
  61. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +1 -0
  62. package/lib/typescript/src/__tests__/components/triangle.d.ts +3 -0
  63. package/lib/typescript/src/__tests__/components/triangle.d.ts.map +1 -0
  64. package/lib/typescript/src/__tests__/config.d.ts +3 -0
  65. package/lib/typescript/src/__tests__/config.d.ts.map +1 -0
  66. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +2 -0
  67. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +1 -0
  68. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +2 -0
  69. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +1 -0
  70. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +2 -0
  71. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +1 -0
  72. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +2 -0
  73. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +1 -0
  74. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +2 -0
  75. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +1 -0
  76. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +2 -0
  77. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +1 -0
  78. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +2 -0
  79. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +1 -0
  80. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +2 -0
  81. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +1 -0
  82. package/lib/typescript/src/__tests__/globalSetup.d.ts +10 -0
  83. package/lib/typescript/src/__tests__/globalSetup.d.ts.map +1 -0
  84. package/lib/typescript/src/__tests__/globalTeardown.d.ts +3 -0
  85. package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +1 -0
  86. package/lib/typescript/src/__tests__/setup.d.ts +62 -0
  87. package/lib/typescript/src/__tests__/setup.d.ts.map +1 -0
  88. package/lib/typescript/src/utils.d.ts +2 -1
  89. package/lib/typescript/src/utils.d.ts.map +1 -1
  90. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  91. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  92. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  93. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  94. package/libs/{ios/libwebgpu_dawn.xcframework/ios-arm64 → apple/arm64_iphoneos}/libwebgpu_dawn.a +0 -0
  95. package/libs/{ios → apple}/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  96. package/libs/{ios/libwebgpu_dawn.xcframework/xros-arm64 → apple/arm64_xros}/libwebgpu_dawn.a +0 -0
  97. package/libs/{ios → apple}/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  98. package/libs/{ios → apple}/libwebgpu_dawn.a +0 -0
  99. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +44 -0
  100. package/libs/{ios/arm64_iphoneos → apple/libwebgpu_dawn.xcframework/ios-arm64}/libwebgpu_dawn.a +0 -0
  101. package/libs/{ios → apple}/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  102. package/libs/apple/libwebgpu_dawn_macosx.xcframework/Info.plist +28 -0
  103. package/libs/apple/libwebgpu_dawn_macosx.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  104. package/libs/{ios/libwebgpu_dawn.xcframework/xros-arm64_x86_64-simulator → apple}/libwebgpu_dawn_visionos.a +0 -0
  105. package/libs/{ios/libwebgpu_dawn.xcframework → apple/libwebgpu_dawn_visionos.xcframework}/Info.plist +0 -31
  106. package/libs/{ios/arm64_xros → apple/libwebgpu_dawn_visionos.xcframework/xros-arm64}/libwebgpu_dawn.a +0 -0
  107. package/libs/{ios → apple/libwebgpu_dawn_visionos.xcframework/xros-arm64_x86_64-simulator}/libwebgpu_dawn_visionos.a +0 -0
  108. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  109. package/libs/{ios → apple}/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  110. package/libs/{ios → apple}/x86_64_xrsimulator/libwebgpu_dawn.a +0 -0
  111. package/package.json +24 -24
  112. package/src/Canvas.tsx +4 -2
  113. package/src/__tests__/ArrayBuffer.spec.ts +76 -0
  114. package/src/__tests__/Buffer.spec.ts +357 -0
  115. package/src/__tests__/ComputeShader.spec.ts +375 -0
  116. package/src/__tests__/Constants.spec.ts +91 -0
  117. package/src/__tests__/Device.spec.ts +35 -0
  118. package/src/__tests__/ExternalTexture.spec.ts +284 -0
  119. package/src/__tests__/GPU.spec.ts +229 -0
  120. package/src/__tests__/ImageData.spec.ts +26 -0
  121. package/src/__tests__/Shaders.spec.ts +232 -0
  122. package/src/__tests__/Texture.spec.ts +191 -0
  123. package/src/__tests__/assets/Di-3d.png +0 -0
  124. package/src/__tests__/components/DrawingContext.ts +11 -0
  125. package/src/__tests__/components/Wireframe/Shaders.ts +138 -0
  126. package/src/__tests__/components/Wireframe/models.ts +113 -0
  127. package/src/__tests__/components/Wireframe/utils.ts +22 -0
  128. package/src/__tests__/components/cube.ts +51 -0
  129. package/src/__tests__/components/meshes/mesh.ts +96 -0
  130. package/src/__tests__/components/meshes/sphere.ts +103 -0
  131. package/src/__tests__/components/meshes/stanfordDragon.ts +44 -0
  132. package/src/__tests__/components/meshes/stanfordDragonData.ts +5 -0
  133. package/src/__tests__/components/meshes/teapot.ts +13 -0
  134. package/src/__tests__/components/meshes/utils.ts +235 -0
  135. package/src/__tests__/components/triangle.ts +17 -0
  136. package/src/__tests__/config.ts +2 -0
  137. package/src/__tests__/demos/ABuffer.spec.ts +885 -0
  138. package/src/__tests__/demos/Blur.spec.ts +397 -0
  139. package/src/__tests__/demos/Cube.spec.ts +925 -0
  140. package/src/__tests__/demos/FractalCube.spec.ts +239 -0
  141. package/src/__tests__/demos/OcclusionQuery.spec.ts +376 -0
  142. package/src/__tests__/demos/RenderBundles.spec.ts +579 -0
  143. package/src/__tests__/demos/Triangle.spec.ts +248 -0
  144. package/src/__tests__/demos/Wireframe.spec.ts +190 -0
  145. package/src/__tests__/globalSetup.ts +54 -0
  146. package/src/__tests__/globalTeardown.ts +11 -0
  147. package/src/__tests__/setup.ts +409 -0
  148. package/src/__tests__/snapshots/abuffer.png +0 -0
  149. package/src/__tests__/snapshots/asteroid.png +0 -0
  150. package/src/__tests__/snapshots/blur.png +0 -0
  151. package/src/__tests__/snapshots/buffer.png +0 -0
  152. package/src/__tests__/snapshots/constant-triangle.png +0 -0
  153. package/src/__tests__/snapshots/cube.png +0 -0
  154. package/src/__tests__/snapshots/f.png +0 -0
  155. package/src/__tests__/snapshots/f2.png +0 -0
  156. package/src/__tests__/snapshots/fractal-cubes.png +0 -0
  157. package/src/__tests__/snapshots/instanced-cubes.png +0 -0
  158. package/src/__tests__/snapshots/occlusion-query.png +0 -0
  159. package/src/__tests__/snapshots/ref.png +0 -0
  160. package/src/__tests__/snapshots/texture.png +0 -0
  161. package/src/__tests__/snapshots/textured-cube.png +0 -0
  162. package/src/__tests__/snapshots/triangle-msaa.png +0 -0
  163. package/src/__tests__/snapshots/triangle.png +0 -0
  164. package/src/__tests__/snapshots/two-cube.png +0 -0
  165. package/src/utils.ts +3 -1
  166. package/android/gradle.properties +0 -5
  167. package/react-native-wgpu.podspec +0 -53
@@ -0,0 +1,409 @@
1
+ /* eslint-disable max-len */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ /* eslint-disable no-var */
4
+ import fs from "fs";
5
+ import path from "path";
6
+
7
+ import puppeteer from "puppeteer";
8
+ import { PNG } from "pngjs";
9
+ import pixelmatch from "pixelmatch";
10
+ import type { mat4, vec3, mat3 } from "wgpu-matrix";
11
+ import type { Server, WebSocket } from "ws";
12
+ import type { Browser, Page } from "puppeteer";
13
+
14
+ import type { DrawingContext } from "./components/DrawingContext";
15
+ import { cubeVertexArray } from "./components/cube";
16
+ import { redFragWGSL, triangleVertWGSL } from "./components/triangle";
17
+ import { DEBUG, REFERENCE } from "./config";
18
+
19
+ jest.setTimeout(180 * 1000);
20
+
21
+ type TestOS = "ios" | "android" | "web" | "node";
22
+
23
+ declare global {
24
+ var testServer: Server;
25
+ var testClient: WebSocket;
26
+ var testOS: TestOS;
27
+ }
28
+
29
+ interface GPUContext {
30
+ gpu: GPU;
31
+ adapter: GPUAdapter;
32
+ device: GPUDevice;
33
+ shaders: {
34
+ triangleVertWGSL: string;
35
+ redFragWGSL: string;
36
+ };
37
+ urls: {
38
+ fTexture: string;
39
+ };
40
+ assets: {
41
+ cubeVertexArray: Float32Array;
42
+ di3D: ImageData;
43
+ moon: ImageData;
44
+ saturn: ImageData;
45
+ };
46
+ ctx: DrawingContext;
47
+ mat4: typeof mat4;
48
+ vec3: typeof vec3;
49
+ mat3: typeof mat3;
50
+ }
51
+
52
+ type Ctx = Record<string, unknown>;
53
+
54
+ type JSONValue =
55
+ | { [key: string]: JSONValue }
56
+ | JSONValue[]
57
+ | number
58
+ | string
59
+ | boolean
60
+ | null;
61
+
62
+ interface TestingClient {
63
+ eval<C = Ctx, R = JSONValue>(
64
+ fn: (ctx: GPUContext & C) => R | Promise<R>,
65
+ ctx?: C,
66
+ ): Promise<R>;
67
+ OS: TestOS;
68
+ arch: "paper" | "fabric";
69
+ init(): Promise<void>;
70
+ dispose(): Promise<void>;
71
+ }
72
+
73
+ export let client: TestingClient;
74
+
75
+ beforeAll(async () => {
76
+ client = REFERENCE ? new ReferenceTestingClient() : new RemoteTestingClient();
77
+ await client.init();
78
+ });
79
+
80
+ afterAll(async () => {
81
+ await client.dispose();
82
+ });
83
+
84
+ class RemoteTestingClient implements TestingClient {
85
+ readonly OS = global.testOS;
86
+ readonly arch = global.testArch;
87
+
88
+ eval<C = Ctx, R = JSONValue>(
89
+ fn: (ctx: GPUContext & C) => R | Promise<R>,
90
+ context?: C,
91
+ ): Promise<R> {
92
+ const ctx = this.prepareContext(context ?? {});
93
+ const body = { code: fn.toString(), ctx };
94
+ return this.handleResponse<R>(JSON.stringify(body));
95
+ }
96
+
97
+ private handleResponse<R>(body: string): Promise<R> {
98
+ return new Promise((resolve) => {
99
+ this.client.once("message", (raw: Buffer) => {
100
+ resolve(JSON.parse(raw.toString()));
101
+ });
102
+ this.client.send(body);
103
+ });
104
+ }
105
+
106
+ private get client() {
107
+ if (global.testClient === null) {
108
+ throw new Error("Client is not connected. Did you call init?");
109
+ }
110
+ return global.testClient!;
111
+ }
112
+
113
+ private prepareContext<C extends Ctx>(context?: C): C {
114
+ const ctx: any = {};
115
+ if (context) {
116
+ for (const [key, value] of Object.entries(context)) {
117
+ ctx[key] = value;
118
+ }
119
+ }
120
+ return ctx;
121
+ }
122
+ async init() {}
123
+ async dispose() {}
124
+ }
125
+
126
+ class ReferenceTestingClient implements TestingClient {
127
+ readonly OS = "web";
128
+ readonly arch = "paper";
129
+
130
+ private browser: Browser | null = null;
131
+ private page: Page | null = null;
132
+
133
+ async eval<C = Ctx, R = JSONValue>(
134
+ fn: (ctx: GPUContext & C) => R | Promise<R>,
135
+ ctx?: C,
136
+ ): Promise<R> {
137
+ if (!this.page) {
138
+ throw new Error("RemoteSurface not initialized");
139
+ }
140
+ const fTexturePath = path.join(
141
+ __dirname,
142
+ "../../../../apps/paper/src/assets/f.png",
143
+ );
144
+ const fTextureData = fs.readFileSync(fTexturePath);
145
+ const fTextureBase64 = `data:image/png;base64,${fTextureData.toString("base64")}`;
146
+ const source = `(async function Main(){
147
+ var global = window;
148
+ const r = () => {${fs.readFileSync(path.join(__dirname, "../../../../node_modules/wgpu-matrix/dist/3.x/wgpu-matrix.js"), "utf8")} };
149
+ r();
150
+ const { mat4, vec3, mat3 } = window.wgpuMatrix;
151
+ const { device, adapter, gpu, cubeVertexArray, triangleVertWGSL, redFragWGSL, di3D, saturn, moon } = window;
152
+ class DrawingContext {
153
+ constructor(device, width, height) {
154
+ this.device = device;
155
+ this.width = width;
156
+ this.height = height;
157
+ const bytesPerRow = this.width * 4;
158
+ this.texture = device.createTexture({
159
+ size: [width, height],
160
+ format: gpu.getPreferredCanvasFormat(),
161
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
162
+ });
163
+ this.buffer = device.createBuffer({
164
+ size: bytesPerRow * this.height,
165
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
166
+ });
167
+ }
168
+ getCurrentTexture() {
169
+ return this.texture;
170
+ }
171
+ getImageData() {
172
+ const commandEncoder = this.device.createCommandEncoder();
173
+ const bytesPerRow = this.width * 4;
174
+ commandEncoder.copyTextureToBuffer({ texture: this.texture }, { buffer: this.buffer, bytesPerRow }, [this.width, this.height]);
175
+ this.device.queue.submit([commandEncoder.finish()]);
176
+
177
+ return this.buffer.mapAsync(GPUMapMode.READ).then(() => {
178
+ const arrayBuffer = this.buffer.getMappedRange();
179
+ const uint8Array = new Uint8Array(arrayBuffer);
180
+ const data = Array.from(uint8Array);
181
+ this.buffer.unmap();
182
+ return {
183
+ data,
184
+ width: this.width,
185
+ height: this.height,
186
+ format: gpu.getPreferredCanvasFormat(),
187
+ };
188
+ });
189
+ }
190
+ }
191
+
192
+ const ctx = new DrawingContext(device, 1024, 1024);
193
+ return (${fn.toString()})({
194
+ device, adapter, gpu,
195
+ urls: {
196
+ fTexture: "${fTextureBase64}"
197
+ },
198
+ assets: {
199
+ cubeVertexArray,
200
+ di3D,
201
+ moon,
202
+ saturn,
203
+ },
204
+ shaders: {
205
+ triangleVertWGSL,
206
+ redFragWGSL,
207
+ },
208
+ ctx,
209
+ mat4,
210
+ vec3,
211
+ mat3,
212
+ ...${JSON.stringify(ctx || {})}
213
+ });
214
+ })();`;
215
+ const data = await this.page.evaluate(source);
216
+ return data as R;
217
+ }
218
+
219
+ async init() {
220
+ const browser = await puppeteer.launch({
221
+ headless: !DEBUG,
222
+ args: ["--enable-unsafe-webgpu"],
223
+ });
224
+ const page = await browser.newPage();
225
+ page.on("console", (msg) => console.log(msg.text()));
226
+ page.on("pageerror", (error) => {
227
+ console.error(error.message);
228
+ });
229
+ await page
230
+ .goto("chrome://gpu", {
231
+ waitUntil: "networkidle0",
232
+ timeout: 20 * 60 * 1000,
233
+ })
234
+ .catch((e) => console.log(e));
235
+ await page.waitForNetworkIdle();
236
+ const di3D = decodeImage(
237
+ path.join(__dirname, "../../../../apps/paper/src/assets/Di-3d.png"),
238
+ );
239
+ const moon = decodeImage(
240
+ path.join(__dirname, "../../../../apps/paper/src/assets/moon.png"),
241
+ );
242
+ const saturn = decodeImage(
243
+ path.join(__dirname, "../../../../apps/paper/src/assets/saturn.png"),
244
+ );
245
+ await page.evaluate(
246
+ `
247
+ (async () => {
248
+ window.gpu = navigator.gpu;
249
+ if (!gpu) {
250
+ const canvas = document.createElement('canvas');
251
+ const gl = canvas.getContext('webgl');
252
+ throw new Error("WebGPU is not available. WebGL: " + !!(gl && gl instanceof WebGLRenderingContext));
253
+ }
254
+ window.adapter = await gpu.requestAdapter();
255
+ if (!adapter) {
256
+ throw new Error("No adapter");
257
+ }
258
+ window.RNWebGPU = {
259
+ DecodeToUTF8: (data) => {
260
+ return new TextDecoder().decode(data);
261
+ }
262
+ };
263
+ window.device = await adapter.requestDevice();
264
+ window.cubeVertexArray = new Float32Array(${JSON.stringify(Array.from(cubeVertexArray))});
265
+ window.triangleVertWGSL = \`${triangleVertWGSL}\`;
266
+ window.redFragWGSL = \`${redFragWGSL}\`;
267
+ const rawDi3D = ${JSON.stringify(di3D)};
268
+ window.di3D = new ImageData(
269
+ new Uint8ClampedArray(rawDi3D.data),
270
+ rawDi3D.width,
271
+ rawDi3D.height
272
+ );
273
+ const rawMoon = ${JSON.stringify(moon)};
274
+ window.moon = new ImageData(
275
+ new Uint8ClampedArray(rawMoon.data),
276
+ rawMoon.width,
277
+ rawMoon.height
278
+ );
279
+ const rawSaturn = ${JSON.stringify(saturn)};
280
+ window.saturn = new ImageData(
281
+ new Uint8ClampedArray(rawSaturn.data),
282
+ rawSaturn.width,
283
+ rawSaturn.height
284
+ );
285
+ })();
286
+ `,
287
+ );
288
+ this.browser = browser;
289
+ this.page = page;
290
+ }
291
+ async dispose() {
292
+ if (this.browser && !DEBUG) {
293
+ this.browser.close();
294
+ }
295
+ }
296
+ }
297
+
298
+ interface BitmapData {
299
+ data: number[];
300
+ width: number;
301
+ height: number;
302
+ format: string;
303
+ }
304
+
305
+ export const encodeImage = (bitmap: BitmapData) => {
306
+ const { width, height, format } = bitmap;
307
+ let data = new Uint8Array(bitmap.data);
308
+ // Convert BGRA to RGBA if necessary
309
+ if (format === "bgra8unorm") {
310
+ data = new Uint8Array(bitmap.data.length);
311
+ for (let i = 0; i < bitmap.data.length; i += 4) {
312
+ data[i] = bitmap.data[i + 2]; // R
313
+ data[i + 1] = bitmap.data[i + 1]; // G
314
+ data[i + 2] = bitmap.data[i]; // B
315
+ data[i + 3] = bitmap.data[i + 3]; // A
316
+ }
317
+ } else if (format !== "rgba8unorm") {
318
+ throw new Error(`Unsupported format ${format}`);
319
+ }
320
+ // Create a new PNG
321
+ const png = new PNG({
322
+ width: width,
323
+ height: height,
324
+ filterType: -1,
325
+ });
326
+ png.data = Buffer.from(data);
327
+ return png;
328
+ };
329
+
330
+ interface CheckImageOptions {
331
+ maxPixelDiff?: number;
332
+ threshold?: number;
333
+ overwrite?: boolean;
334
+ mute?: boolean;
335
+ shouldFail?: boolean;
336
+ }
337
+
338
+ // On Github Action, the image decoding is slightly different
339
+ // all tests that show the oslo.jpg have small differences but look ok
340
+ const defaultCheckImageOptions = {
341
+ maxPixelDiff: 200,
342
+ threshold: 0.1,
343
+ overwrite: false,
344
+ mute: false,
345
+ shouldFail: false,
346
+ };
347
+
348
+ export const checkImage = (
349
+ toTest: PNG,
350
+ relPath: string,
351
+ opts?: CheckImageOptions,
352
+ ) => {
353
+ const options = { ...defaultCheckImageOptions, ...opts };
354
+ const { overwrite, threshold, mute, maxPixelDiff, shouldFail } = options;
355
+ const p = path.resolve(__dirname, relPath);
356
+ if (fs.existsSync(p) && !overwrite) {
357
+ const ref = fs.readFileSync(p);
358
+ const baseline = PNG.sync.read(ref);
359
+ const diffImage = new PNG({
360
+ width: baseline.width,
361
+ height: baseline.height,
362
+ });
363
+ if (baseline.width !== toTest.width || baseline.height !== toTest.height) {
364
+ throw new Error(
365
+ `Image sizes don't match: ${baseline.width}x${baseline.height} vs ${toTest.width}x${toTest.height}`,
366
+ );
367
+ }
368
+ const diffPixelsCount = pixelmatch(
369
+ baseline.data,
370
+ toTest.data,
371
+ diffImage.data,
372
+ baseline.width,
373
+ baseline.height,
374
+ { threshold },
375
+ );
376
+ if (!mute) {
377
+ if (diffPixelsCount > maxPixelDiff && !shouldFail) {
378
+ console.log(`${p} didn't match`);
379
+ fs.writeFileSync(`${p}.test.png`, PNG.sync.write(toTest));
380
+ fs.writeFileSync(`${p}-diff-test.png`, PNG.sync.write(diffImage));
381
+ }
382
+ if (shouldFail) {
383
+ expect(diffPixelsCount).not.toBeLessThanOrEqual(maxPixelDiff);
384
+ } else {
385
+ expect(diffPixelsCount).toBeLessThanOrEqual(maxPixelDiff);
386
+ }
387
+ }
388
+ return diffPixelsCount;
389
+ } else {
390
+ const buffer = PNG.sync.write(toTest);
391
+ fs.writeFileSync(p, buffer);
392
+ }
393
+ return 0;
394
+ };
395
+
396
+ export const decodeImage = (relPath: string): BitmapData => {
397
+ const p = path.resolve(__dirname, relPath);
398
+ const data = fs.readFileSync(p);
399
+ const png = PNG.sync.read(data);
400
+
401
+ const bitmap: BitmapData = {
402
+ data: Array.from(png.data),
403
+ width: png.width,
404
+ height: png.height,
405
+ format: "rgba8unorm",
406
+ };
407
+
408
+ return bitmap;
409
+ };
Binary file
Binary file
Binary file
Binary file
Binary file
package/src/utils.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { DependencyList } from "react";
1
2
  import { useEffect, useRef } from "react";
2
3
 
3
4
  import type { CanvasRef } from "./Canvas";
@@ -14,6 +15,7 @@ export const warnIfNotHardwareAccelerated = (adapter: GPUAdapter) => {
14
15
 
15
16
  export const useCanvasEffect = (
16
17
  effect: () => void | Unsubscribe | Promise<void | Unsubscribe>,
18
+ deps: DependencyList = [],
17
19
  ) => {
18
20
  const ref = useRef<CanvasRef>(null);
19
21
  const unsubscribe = useRef<Unsubscribe>();
@@ -35,6 +37,6 @@ export const useCanvasEffect = (
35
37
  }
36
38
  };
37
39
  // eslint-disable-next-line react-hooks/exhaustive-deps
38
- }, []);
40
+ }, deps);
39
41
  return ref;
40
42
  };
@@ -1,5 +0,0 @@
1
- Wgpu_kotlinVersion=1.7.0
2
- Wgpu_minSdkVersion=21
3
- Wgpu_targetSdkVersion=31
4
- Wgpu_compileSdkVersion=31
5
- Wgpu_ndkversion=21.4.7075529
@@ -1,53 +0,0 @@
1
- require "json"
2
-
3
- package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
- folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
5
-
6
- Pod::Spec.new do |s|
7
- s.name = "react-native-wgpu"
8
- s.version = package["version"]
9
- s.summary = package["description"]
10
- s.homepage = package["homepage"]
11
- s.license = package["license"]
12
- s.authors = package["author"]
13
-
14
- s.platforms = { :ios => min_ios_version_supported, :visionos => "1.0" }
15
- s.source = { :git => "https://github.com/wcandillon/react-native-webgpu.git", :tag => "#{s.version}" }
16
-
17
- s.source_files = [
18
- "ios/**/*.{h,c,cc,cpp,m,mm,swift}",
19
- "cpp/**/*.{h,cpp}"
20
- ]
21
-
22
- s.ios.vendored_frameworks = [
23
- 'libs/ios/libwebgpu_dawn.xcframework',
24
- ]
25
-
26
- s.pod_target_xcconfig = {
27
- 'HEADER_SEARCH_PATHS' => '$(PODS_TARGET_SRCROOT)/cpp',
28
- }
29
-
30
- # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
31
- # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
32
- if respond_to?(:install_modules_dependencies, true)
33
- install_modules_dependencies(s)
34
- else
35
- s.dependency "React-Core"
36
-
37
- # Don't install the dependencies when we run `pod install` in the old architecture.
38
- if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
39
- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
40
- s.pod_target_xcconfig = {
41
- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
42
- "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
43
- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
44
- }
45
- s.dependency "React-RCTFabric"
46
- s.dependency "React-Codegen"
47
- s.dependency "RCT-Folly"
48
- s.dependency "RCTRequired"
49
- s.dependency "RCTTypeSafety"
50
- s.dependency "ReactCommon/turbomodule/core"
51
- end
52
- end
53
- end