From a185f1c7ac4630c55dfd5f8e1dab5ce07d4b176d Mon Sep 17 00:00:00 2001 From: William Candillon Date: Fri, 21 Aug 2026 14:45:46 +0200 Subject: [PATCH 1/2] :wrench: --- apps/docs/content/api/install-webgpu.mdx | 29 ++++++-- .../content/docs/integrations/worklets.mdx | 2 +- .../src/Diagnostics/WorkletRequestAdapter.tsx | 23 +++++++ packages/webgpu/src/index.tsx | 2 +- packages/webgpu/src/install.ts | 67 ++++++++++++++----- packages/webgpu/src/main/index.tsx | 3 + packages/webgpu/src/mock.ts | 1 - 7 files changed, 104 insertions(+), 23 deletions(-) diff --git a/apps/docs/content/api/install-webgpu.mdx b/apps/docs/content/api/install-webgpu.mdx index 7fc323bfc..84442129d 100644 --- a/apps/docs/content/api/install-webgpu.mdx +++ b/apps/docs/content/api/install-webgpu.mdx @@ -1,10 +1,10 @@ --- title: installWebGPU -description: Install WebGPU flag constants on a worklet runtime. +description: Install navigator.gpu and the WebGPU flag constants on a worklet runtime. --- -On a worklet runtime, the WebGPU constants are not available by default. -Call `installWebGPU()` once at the top of a worklet to install the needed globals for that runtime. +On a worklet runtime, neither `navigator.gpu` nor the WebGPU flag constants are available by default. +Call `installWebGPU()` once at the top of a worklet to install the needed globals for that runtime: `navigator.gpu` plus `GPUBufferUsage`, `GPUTextureUsage`, `GPUShaderStage`, `GPUColorWrite`, and `GPUMapMode`. On the main JS thread these are already installed when the native module loads; calling `installWebGPU()` there is a safe no-op. @@ -72,4 +72,25 @@ const gpuWork = (device: GPUDevice) => { }; runOnRuntime(runtime, gpuWork)(device); -``` \ No newline at end of file +``` + +### navigator.gpu on a worklet runtime + +After `installWebGPU()`, a worklet can request its own adapter and device instead of receiving them from the main thread. The returned promises settle on the calling runtime. + +```tsx twoslash +import { installWebGPU } from "react-native-webgpu"; +import { runOnUI } from "react-native-worklets"; + +runOnUI(() => { + "worklet"; + installWebGPU(); + globalThis.navigator.gpu.requestAdapter().then((adapter) => { + // … + }); +})(); +``` + +Use the `globalThis.` prefix inside worklets: the Worklets babel plugin does not treat a bare `navigator` as a known global, so without the prefix it would capture the main runtime's `navigator` object by closure instead of reading the one installed on the worklet runtime. + +Limitation: spontaneous events (`device.lost`, `uncapturederror`) are only delivered to devices created on the main JS runtime. \ No newline at end of file diff --git a/apps/docs/content/docs/integrations/worklets.mdx b/apps/docs/content/docs/integrations/worklets.mdx index 8cf88c4f3..e7114bd97 100644 --- a/apps/docs/content/docs/integrations/worklets.mdx +++ b/apps/docs/content/docs/integrations/worklets.mdx @@ -18,7 +18,7 @@ Follow the Worklets installation guide for the babel plugin and native setup. We ## installWebGPU -Worklet runtimes start without WebGPU flag globals (`GPUBufferUsage`, `GPUTextureUsage`, etc.). Call [`installWebGPU()`](/api/install-webgpu) once at the top of a worklet: +Worklet runtimes start without the WebGPU globals (`navigator.gpu`, `GPUBufferUsage`, `GPUTextureUsage`, etc.). Call [`installWebGPU()`](/api/install-webgpu) once at the top of a worklet to install all of them for that runtime: ```tsx twoslash import type { RNCanvasContext, CanvasRef } from "react-native-webgpu"; diff --git a/apps/example/src/Diagnostics/WorkletRequestAdapter.tsx b/apps/example/src/Diagnostics/WorkletRequestAdapter.tsx index 3ba989544..fb426a396 100644 --- a/apps/example/src/Diagnostics/WorkletRequestAdapter.tsx +++ b/apps/example/src/Diagnostics/WorkletRequestAdapter.tsx @@ -1,5 +1,6 @@ import React, { useState } from "react"; import { Button, StyleSheet, Text, View } from "react-native"; +import { installWebGPU } from "react-native-webgpu"; import { runOnUI, scheduleOnRN } from "react-native-worklets"; // Repro for a crash when the first WebGPU call happens on a worklet runtime @@ -43,6 +44,24 @@ export const WorkletRequestAdapter = () => { })(); }; + const workletNavigator = () => { + // No WebGPU object crosses explicitly here: installWebGPU() carries the + // GPU instance in its own closure and installs it as navigator.gpu on the + // calling runtime (globalThis. prefix required, see install.ts). + runOnUI(() => { + "worklet"; + installWebGPU(); + globalThis.navigator.gpu.requestAdapter().then((adapter) => { + scheduleOnRN( + append, + `UI (worklet) runtime: installWebGPU() + navigator.gpu -> ${ + adapter ? "GPUAdapter" : "null" + }`, + ); + }); + })(); + }; + return (