├── .gitignore
├── .gitmodules
├── .yarn
└── releases
│ └── yarn-3.6.4.cjs
├── .yarnrc.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── examples
└── Example
│ ├── .bundle
│ └── config
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc.js
│ ├── .watchmanconfig
│ ├── .yarn
│ └── releases
│ │ └── yarn-3.6.4.cjs
│ ├── .yarnrc.yml
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── README.md
│ ├── android
│ ├── app
│ │ ├── build.gradle
│ │ ├── debug.keystore
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── ic_launcher-playstore.png
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ ├── MainActivity.kt
│ │ │ │ └── MainApplication.kt
│ │ │ └── res
│ │ │ ├── drawable
│ │ │ └── rn_edit_text_material.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ └── values
│ │ │ ├── ic_launcher_background.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
│ ├── app.json
│ ├── babel.config.js
│ ├── babel
│ └── gltf-babel-transformer.js
│ ├── index.js
│ ├── ios
│ ├── .xcode.env
│ ├── Example.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Example.xcscheme
│ ├── Example.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── Example
│ │ ├── AppDelegate.swift
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── dark_60@2x.png
│ │ │ │ ├── dark_60@3x.png
│ │ │ │ ├── icon_60@2x.png
│ │ │ │ ├── icon_60@3x.png
│ │ │ │ ├── tinted_60@2x.png
│ │ │ │ └── tinted_60@3x.png
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── LaunchScreen.storyboard
│ │ └── PrivacyInfo.xcprivacy
│ ├── Podfile
│ └── Podfile.lock
│ ├── jest.config.js
│ ├── metro.config.js
│ ├── myThread.js
│ ├── package.json
│ ├── src
│ ├── App.tsx
│ ├── Components
│ │ ├── ExampleScreen.tsx
│ │ ├── Examples.tsx
│ │ ├── List.tsx
│ │ ├── Root.tsx
│ │ ├── Square.tsx
│ │ ├── controls
│ │ │ ├── dat.gui
│ │ │ │ ├── Controller.ts
│ │ │ │ ├── FunctionController.ts
│ │ │ │ ├── Gui.test.ts
│ │ │ │ ├── Gui.ts
│ │ │ │ ├── NumberController.ts
│ │ │ │ ├── OptionsController.ts
│ │ │ │ ├── SliderController.ts
│ │ │ │ ├── StringController.ts
│ │ │ │ ├── SwitchController.ts
│ │ │ │ ├── incrementingId.test.ts
│ │ │ │ ├── incrementingId.ts
│ │ │ │ └── types.ts
│ │ │ ├── react
│ │ │ │ ├── ControlBackground.tsx
│ │ │ │ ├── ControlButton.tsx
│ │ │ │ ├── ControlFolder.tsx
│ │ │ │ ├── ControlInput.tsx
│ │ │ │ ├── ControlLabel.tsx
│ │ │ │ ├── ControlNumberInput.tsx
│ │ │ │ ├── ControlOptions.tsx
│ │ │ │ ├── ControlSlider.tsx
│ │ │ │ ├── ControlSwitch.tsx
│ │ │ │ ├── ControlTextInput.tsx
│ │ │ │ ├── ControlsContainer.tsx
│ │ │ │ ├── controlsStyles.ts
│ │ │ │ └── useControls.tsx
│ │ │ ├── sliderUtils.test.ts
│ │ │ └── sliderUtils.ts
│ │ ├── globalStyles.ts
│ │ └── stats
│ │ │ ├── HudContainer.tsx
│ │ │ ├── HudLabel.tsx
│ │ │ ├── HudText.tsx
│ │ │ ├── hudStyles.ts
│ │ │ ├── useHudText.tsx
│ │ │ └── useStats.tsx
│ ├── InHouse
│ │ ├── AdapterInfo.tsx
│ │ ├── AnimateCanvas
│ │ │ ├── AnimateCanvas.tsx
│ │ │ └── triangle.wgsl
│ │ ├── CWTriangle
│ │ │ ├── CWTriangle.tsx
│ │ │ └── cw-triangle.wgsl
│ │ ├── ClearBuffer.tsx
│ │ ├── Crop.tsx
│ │ ├── ExceedDeviceLimits.tsx
│ │ ├── FlakesTexture.tsx
│ │ ├── Outlines
│ │ │ ├── Outlines.tsx
│ │ │ ├── cube.gltf
│ │ │ └── outlines.wgsl
│ │ ├── Portal
│ │ │ ├── Portal.tsx
│ │ │ ├── portal.gltf
│ │ │ ├── portal.jpg
│ │ │ └── portal.wgsl
│ │ ├── ResizeCanvas
│ │ │ ├── ResizeCanvas.tsx
│ │ │ ├── runResizeCanvas.ts
│ │ │ └── triangle.wgsl
│ │ ├── Thread.tsx
│ │ └── Video.tsx
│ ├── Three
│ │ ├── Clearcoat
│ │ │ └── Clearcoat.tsx
│ │ ├── Clipping
│ │ │ └── Clipping.tsx
│ │ ├── ComputeGeometry
│ │ │ └── ComputeGeometry.tsx
│ │ ├── ComputeParticles
│ │ │ └── ComputeParticles.tsx
│ │ ├── GLTFLoader
│ │ │ └── GLTFLoader.tsx
│ │ ├── HelloThree
│ │ │ └── HelloThree.tsx
│ │ └── LogarithmicDepthBuffer
│ │ │ └── LogarithmicDepthBuffer.tsx
│ ├── WebGPUSamples
│ │ ├── BasicGraphics
│ │ │ ├── CubeMap
│ │ │ │ ├── CubeMap.tsx
│ │ │ │ └── sampleCubemap.frag.wgsl
│ │ │ ├── FractalCube
│ │ │ │ ├── FractalCube.tsx
│ │ │ │ └── sampleSelf.frag.wgsl
│ │ │ ├── HelloTriangle
│ │ │ │ └── HelloTriangle.tsx
│ │ │ ├── HelloTriangleMSAA
│ │ │ │ └── HelloTriangleMSAA.tsx
│ │ │ ├── InstancedCube
│ │ │ │ ├── InstancedCube.tsx
│ │ │ │ └── instanced.vert.wgsl
│ │ │ ├── RotatingCube
│ │ │ │ └── RotatingCube.tsx
│ │ │ ├── TexturedCube
│ │ │ │ ├── TexturedCube.tsx
│ │ │ │ └── sampleTextureMixColor.frag.wgsl
│ │ │ └── TwoCubes
│ │ │ │ └── TwoCubes.tsx
│ │ ├── GPGPU
│ │ │ ├── BitonicSort
│ │ │ │ ├── BitonicSort.tsx
│ │ │ │ ├── atomicToZero.wgsl
│ │ │ │ ├── bitonicCompute.ts
│ │ │ │ ├── bitonicDisplay.frag.wgsl
│ │ │ │ ├── bitonicDisplay.ts
│ │ │ │ └── utils.ts
│ │ │ ├── ComputeBoids
│ │ │ │ ├── ComputeBoids.tsx
│ │ │ │ ├── sprite.wgsl
│ │ │ │ └── updateSprites.wgsl
│ │ │ └── GameOfLife
│ │ │ │ ├── GameOfLife.tsx
│ │ │ │ ├── compute.wgsl
│ │ │ │ ├── frag.wgsl
│ │ │ │ └── vert.wgsl
│ │ ├── GraphicsTechniques
│ │ │ ├── ABuffer
│ │ │ │ ├── ABuffer.tsx
│ │ │ │ ├── composite.wgsl
│ │ │ │ ├── opaque.wgsl
│ │ │ │ └── translucent.wgsl
│ │ │ ├── Cameras
│ │ │ │ ├── Cameras.tsx
│ │ │ │ ├── camera.ts
│ │ │ │ ├── cube.wgsl
│ │ │ │ └── input.ts
│ │ │ ├── Cornell
│ │ │ │ ├── Cornell.tsx
│ │ │ │ ├── common.ts
│ │ │ │ ├── common.wgsl
│ │ │ │ ├── radiosity.ts
│ │ │ │ ├── radiosity.wgsl
│ │ │ │ ├── rasterizer.ts
│ │ │ │ ├── rasterizer.wgsl
│ │ │ │ ├── raytracer.ts
│ │ │ │ ├── raytracer.wgsl
│ │ │ │ ├── scene.ts
│ │ │ │ ├── tonemapper.ts
│ │ │ │ └── tonemapper.wgsl
│ │ │ ├── DeferredRendering
│ │ │ │ ├── DeferredRendering.tsx
│ │ │ │ ├── fragmentDeferredRendering.wgsl
│ │ │ │ ├── fragmentGBuffersDebugView.wgsl
│ │ │ │ ├── fragmentWriteGBuffers.wgsl
│ │ │ │ ├── lightUpdate.wgsl
│ │ │ │ ├── vertexTextureQuad.wgsl
│ │ │ │ └── vertexWriteGBuffers.wgsl
│ │ │ ├── ImageBlur
│ │ │ │ ├── ImageBlur.tsx
│ │ │ │ └── blur.wgsl
│ │ │ ├── NormalMap
│ │ │ │ ├── NormalMap.tsx
│ │ │ │ ├── normalMap.wgsl
│ │ │ │ └── utils.ts
│ │ │ ├── ParticlesHDR
│ │ │ │ ├── ParticlesHDR.tsx
│ │ │ │ ├── particle.wgsl
│ │ │ │ └── probabilityMap.wgsl
│ │ │ ├── ShadowMapping
│ │ │ │ ├── ShadowMapping.tsx
│ │ │ │ ├── fragment.wgsl
│ │ │ │ ├── vertex.wgsl
│ │ │ │ └── vertexShadow.wgsl
│ │ │ ├── SkinnedMesh
│ │ │ │ ├── SkinnedMesh.tsx
│ │ │ │ ├── glbUtils.ts
│ │ │ │ ├── gltf.ts
│ │ │ │ ├── gltf.wgsl
│ │ │ │ ├── grid.wgsl
│ │ │ │ ├── gridData.ts
│ │ │ │ └── gridUtils.ts
│ │ │ ├── VolumeRendering
│ │ │ │ ├── VolumeRendering.tsx
│ │ │ │ └── volume.wgsl
│ │ │ └── Wireframe
│ │ │ │ ├── Wireframe.tsx
│ │ │ │ ├── models.ts
│ │ │ │ ├── solidColorLit.wgsl
│ │ │ │ ├── utils.ts
│ │ │ │ └── wireframe.wgsl
│ │ ├── WebGPUFeatures
│ │ │ ├── OcclusionQueries
│ │ │ │ ├── OcclusionQueries.tsx
│ │ │ │ └── solidColorLit.wgsl
│ │ │ ├── RenderBundles
│ │ │ │ ├── RenderBundles.tsx
│ │ │ │ └── mesh.wgsl
│ │ │ ├── ReversedZ
│ │ │ │ ├── ReversedZ.tsx
│ │ │ │ ├── fragment.wgsl
│ │ │ │ ├── fragmentPrecisionErrorPass.wgsl
│ │ │ │ ├── fragmentTextureQuad.wgsl
│ │ │ │ ├── vertex.wgsl
│ │ │ │ ├── vertexDepthPrePass.wgsl
│ │ │ │ ├── vertexPrecisionErrorPass.wgsl
│ │ │ │ └── vertexTextureQuad.wgsl
│ │ │ └── SamplerParameters
│ │ │ │ ├── SamplerParameters.tsx
│ │ │ │ ├── showTexture.wgsl
│ │ │ │ └── texturedSquare.wgsl
│ │ ├── assets
│ │ │ └── img
│ │ │ │ ├── Di-3d.png
│ │ │ │ ├── brickwall_albedo.jpg
│ │ │ │ ├── brickwall_height.jpg
│ │ │ │ ├── brickwall_normal.jpg
│ │ │ │ ├── cubemap
│ │ │ │ ├── negx.jpg
│ │ │ │ ├── negy.jpg
│ │ │ │ ├── negz.jpg
│ │ │ │ ├── posx.jpg
│ │ │ │ ├── posy.jpg
│ │ │ │ └── posz.jpg
│ │ │ │ ├── moon.jpg
│ │ │ │ ├── saturn.jpg
│ │ │ │ ├── spiral_height.png
│ │ │ │ ├── spiral_normal.png
│ │ │ │ ├── toybox_height.png
│ │ │ │ ├── toybox_normal.png
│ │ │ │ ├── webgpu.png
│ │ │ │ └── wood_albedo.png
│ │ ├── meshes
│ │ │ ├── box.ts
│ │ │ ├── cube.ts
│ │ │ ├── mesh.ts
│ │ │ ├── sphere.ts
│ │ │ ├── stanfordDragon.ts
│ │ │ ├── stanfordDragonData.ts
│ │ │ ├── teapot.ts
│ │ │ └── utils.ts
│ │ └── shaders
│ │ │ ├── basic.vert.wgsl
│ │ │ ├── fullscreenTexturedQuad.wgsl
│ │ │ ├── red.frag.wgsl
│ │ │ ├── triangle.vert.wgsl
│ │ │ └── vertexPositionColor.frag.wgsl
│ ├── assets
│ │ └── images
│ │ │ └── cropImage.png
│ ├── types
│ │ ├── TextDecoder.d.ts
│ │ ├── gltf.d.ts
│ │ └── navigationTypes.ts
│ └── utils
│ │ ├── FlakesTextureGenerator.ts
│ │ ├── constants.ts
│ │ ├── examplesCallback.ts
│ │ ├── launchArguments.ts
│ │ ├── observable.test.ts
│ │ ├── observable.ts
│ │ └── shaders
│ │ ├── flakesTexture.wgsl
│ │ ├── quad.wgsl
│ │ ├── videoQuad.wgsl
│ │ └── yuv8420torgba8.wgsl
│ └── tsconfig.json
├── package.json
├── packages
├── react-native-webgpu-experimental
│ ├── .clang-format
│ ├── .gitignore
│ ├── .prettierrc.js
│ ├── android
│ │ ├── CMakeLists.txt
│ │ ├── build.gradle
│ │ ├── gradle.properties
│ │ └── src
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── AndroidManifestNew.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── webgpu
│ │ │ │ └── experimental
│ │ │ │ ├── CxxBridge.kt
│ │ │ │ └── WebgpuExperimentalPackage.kt
│ │ │ ├── newarch
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── webgpu
│ │ │ │ └── experimental
│ │ │ │ └── WebgpuExperimentalModule.kt
│ │ │ └── oldarch
│ │ │ └── java
│ │ │ └── com
│ │ │ └── webgpu
│ │ │ └── experimental
│ │ │ └── WebgpuExperimentalModule.kt
│ ├── babel.config.js
│ ├── cxx
│ │ ├── Compression.cpp
│ │ ├── Compression.h
│ │ ├── InstallExperimentalJSI.cpp
│ │ ├── InstallExperimentalJSI.h
│ │ ├── SocketCallback.h
│ │ ├── VideoPlayer.h
│ │ ├── android
│ │ │ ├── NdkVideoPlayer.cpp
│ │ │ ├── NdkVideoPlayer.h
│ │ │ ├── SocketCallback.cpp
│ │ │ ├── VideoPlayer.cpp
│ │ │ ├── WGPUExperimentalJsi.cpp
│ │ │ └── WGPUExperimentalJsi.h
│ │ └── ios
│ │ │ ├── SocketCallback.mm
│ │ │ ├── ThreadManager.h
│ │ │ ├── ThreadManager.mm
│ │ │ ├── VideoPlayer.mm
│ │ │ ├── WGPUExperimentalJsi.h
│ │ │ └── WGPUExperimentalJsi.mm
│ ├── package.json
│ ├── react-native-webgpu-experimental.podspec
│ ├── react-native.config.js
│ ├── src
│ │ ├── ThreadWebGpuView.tsx
│ │ ├── index.ts
│ │ ├── native.ts
│ │ └── specs
│ │ │ ├── NativeWebgpuExperimentalModule.ts
│ │ │ └── index.ts
│ ├── tsconfig.json
│ └── types
│ │ └── globals.d.ts
├── react-native-webgpu-tests
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc.cjs
│ ├── bin
│ │ ├── test-examples
│ │ └── test-package
│ ├── package.json
│ └── src
│ │ ├── examples
│ │ ├── examples-to-test.js
│ │ ├── examples.js
│ │ ├── generate-examples-html.js
│ │ └── socket-listener.js
│ │ ├── index.js
│ │ ├── package
│ │ ├── build-android.js
│ │ ├── build-ios.js
│ │ ├── generate-project.js
│ │ ├── pack.js
│ │ └── package.js
│ │ └── utils
│ │ ├── config.js
│ │ ├── log.js
│ │ ├── prompt-builder.js
│ │ ├── queue.js
│ │ └── shell.js
├── react-native-webgpu-three
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc.js
│ ├── DEV.md
│ ├── LICENSE
│ ├── README.md
│ ├── babel
│ │ ├── index.js
│ │ └── package.json
│ ├── metro
│ │ ├── index.js
│ │ └── package.json
│ ├── package.json
│ ├── src
│ │ ├── CanvasProxy.js
│ │ ├── Image.js
│ │ ├── ThreeWebGpuView.js
│ │ ├── TouchEventsAdapter.js
│ │ ├── constNodePatch.js
│ │ ├── debugLogging.js
│ │ ├── examples
│ │ │ └── jsm
│ │ │ │ ├── capabilities
│ │ │ │ └── WebGPU.js
│ │ │ │ └── nodes
│ │ │ │ └── pmrem
│ │ │ │ └── PMREMNode.js
│ │ ├── index.js
│ │ ├── nodeBuilderPatch.js
│ │ └── rendererPatch.js
│ └── types
│ │ └── index.d.ts
└── react-native-webgpu
│ ├── .clang-format
│ ├── .gitignore
│ ├── .prettierrc.js
│ ├── README.md
│ ├── android
│ ├── CMakeLists.txt
│ ├── build.gradle
│ ├── gradle.properties
│ └── src
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── AndroidManifestNew.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── webgpu
│ │ │ ├── BitmapLoaderFactory.kt
│ │ │ ├── BlobBitmapLoader.kt
│ │ │ ├── CxxBridge.kt
│ │ │ ├── DrawableBitmapLoader.kt
│ │ │ ├── ExceptionHandler.kt
│ │ │ ├── HTTPBitmapLoader.kt
│ │ │ ├── WebGPUView.kt
│ │ │ ├── WebGPUViewManagerImpl.kt
│ │ │ └── WebgpuPackage.kt
│ │ ├── newarch
│ │ └── com
│ │ │ └── webgpu
│ │ │ ├── WebGPUViewManager.kt
│ │ │ └── WebgpuModule.kt
│ │ └── oldarch
│ │ └── com
│ │ └── webgpu
│ │ ├── WebGPUViewManager.kt
│ │ └── WebgpuModule.kt
│ ├── babel.config.js
│ ├── cxx
│ ├── AdapterHostObject.cpp
│ ├── AdapterHostObject.h
│ ├── ArrayBufferUtils.h
│ ├── AutoReleasePool.h
│ ├── BindGroupHostObject.cpp
│ ├── BindGroupHostObject.h
│ ├── BindGroupLayoutHostObject.cpp
│ ├── BindGroupLayoutHostObject.h
│ ├── BufferHostObject.cpp
│ ├── BufferHostObject.h
│ ├── CommandBufferHostObject.cpp
│ ├── CommandBufferHostObject.h
│ ├── CommandEncoderHostObject.cpp
│ ├── CommandEncoderHostObject.h
│ ├── ComputePassEncoderHostObject.cpp
│ ├── ComputePassEncoderHostObject.h
│ ├── ComputePipelineHostObject.cpp
│ ├── ComputePipelineHostObject.h
│ ├── ConstantConversion.cpp
│ ├── ConstantConversion.h
│ ├── ContextHostObject.cpp
│ ├── ContextHostObject.h
│ ├── CreateImageBitmap.h
│ ├── DeviceHostObject.cpp
│ ├── DeviceHostObject.h
│ ├── ErrorHandler.h
│ ├── ExampleHostObject.cpp
│ ├── ExampleHostObject.h
│ ├── ImageBitmapHostObject.cpp
│ ├── ImageBitmapHostObject.h
│ ├── InstallRootJSI.cpp
│ ├── InstallRootJSI.h
│ ├── JSIInstance.cpp
│ ├── JSIInstance.h
│ ├── Mixins.h
│ ├── PipelineLayoutHostObject.cpp
│ ├── PipelineLayoutHostObject.h
│ ├── QuerySetHostObject.cpp
│ ├── QuerySetHostObject.h
│ ├── QueueHostObject.cpp
│ ├── QueueHostObject.h
│ ├── RenderBundleEncoderHostObject.cpp
│ ├── RenderBundleEncoderHostObject.h
│ ├── RenderBundleHostObject.cpp
│ ├── RenderBundleHostObject.h
│ ├── RenderPassEncoderHostObject.cpp
│ ├── RenderPassEncoderHostObject.h
│ ├── RenderPipelineHostObject.cpp
│ ├── RenderPipelineHostObject.h
│ ├── SamplerHostObject.cpp
│ ├── SamplerHostObject.h
│ ├── ShaderModuleHostObject.cpp
│ ├── ShaderModuleHostObject.h
│ ├── Surface.h
│ ├── SurfaceSize.h
│ ├── SurfacesManager.cpp
│ ├── SurfacesManager.h
│ ├── TextureHostObject.cpp
│ ├── TextureHostObject.h
│ ├── TextureViewHostObject.cpp
│ ├── TextureViewHostObject.h
│ ├── Thread.h
│ ├── WGPUContext.cpp
│ ├── WGPUContext.h
│ ├── WGPUConversions.cpp
│ ├── WGPUConversions.h
│ ├── WGPUDefaults.cpp
│ ├── WGPUDefaults.h
│ ├── WGPUJsiUtils.h
│ ├── WGPUPromise.cpp
│ ├── WGPUPromise.h
│ ├── WGPUWrappers.h
│ ├── android
│ │ ├── CreateImageBitmap.cpp
│ │ ├── JNIBitmapLoaderFactory.h
│ │ ├── JNIBlobBitmapLoader.h
│ │ ├── JNIDrawableBitmapLoader.h
│ │ ├── JNIExceptionHandler.h
│ │ ├── JNIHTTPBitmapLoader.h
│ │ ├── Surface.cpp
│ │ ├── Thread.cpp
│ │ ├── WGPUAndroidInstance.cpp
│ │ ├── WGPUAndroidInstance.h
│ │ ├── WGPUJsi.cpp
│ │ ├── WGPUJsi.h
│ │ └── WGPULog.h
│ └── ios
│ │ ├── CreateImageBitmap.mm
│ │ ├── Surface.mm
│ │ ├── Thread.mm
│ │ ├── UIImage+Bitmap.h
│ │ ├── UIImage+Bitmap.mm
│ │ ├── WGPUJsi.h
│ │ ├── WGPUJsi.mm
│ │ ├── WGPULog.h
│ │ ├── WGPUObjCInstance.h
│ │ ├── WGPUObjCInstance.m
│ │ ├── WGPUWebGPUView.h
│ │ ├── WGPUWebGPUView.mm
│ │ └── WGPUWebGPUViewManager.mm
│ ├── metro
│ ├── index.js
│ └── package.json
│ ├── package.json
│ ├── react-native-webgpu.podspec
│ ├── react-native.config.js
│ ├── src
│ ├── WebGpuView.tsx
│ ├── constants.ts
│ ├── index.ts
│ ├── native.ts
│ ├── specs
│ │ ├── NativeWebgpuModule.ts
│ │ ├── WebgpuNativeComponent.ts
│ │ └── index.ts
│ ├── styles.ts
│ └── types.ts
│ ├── tsconfig.json
│ ├── types
│ ├── webGpuTypes.d.ts
│ └── wgsl.d.ts
│ └── wgsl-babel-transformer
│ ├── index.js
│ └── package.json
├── scripts
├── build-android.sh
├── build-ios.sh
├── check-elf-alignment.sh
├── codegen.sh
├── copy-headers.sh
├── copy-types.sh
├── format-cxx.sh
└── zip-libs.sh
├── turbo.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # MacOS
2 | __MACOSX
3 | .DS_Store
4 | *.pem
5 |
6 | # Yarn
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/sdks
12 | !.yarn/versions
13 |
14 | # VSCode
15 | /.vscode
16 |
17 | /.idea
18 | /node_modules
19 | **/react-native-webgpu-*.tgz
20 | /.test*
21 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "submodules/wgpu-native"]
2 | path = submodules/wgpu-native
3 | url = https://github.com/gfx-rs/wgpu-native.git
4 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | yarnPath: .yarn/releases/yarn-3.6.4.cjs
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Sean Henry
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Native WebGPU
2 |
3 | A [WebGPU](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) port for react native to provide direct access to Metal and Vulkan for iOS and Android via the WebGPU api.
4 |
5 | ## Packages
6 |
7 | ### [react-native-webgpu](packages/react-native-webgpu)
8 |
9 | Direct access to the low-level graphics api [WebGPU](https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API) in React Native.
10 |
11 | ### [react-native-webgpu-three](packages/react-native-webgpu-three)
12 |
13 | Coming soon. A small helper library to enable [Three.js](https://threejs.org/) projects on React Native.
14 |
15 | ## Running the examples
16 |
17 | The best way to learn WebGPU is to check out the examples. You can find instructions to run the examples [here](examples/Example).
18 |
--------------------------------------------------------------------------------
/examples/Example/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/examples/Example/.eslintignore:
--------------------------------------------------------------------------------
1 | /.bundle
2 | /.yarn
3 | /android
4 | /ios
5 | /node_modules
6 | /vendor
7 | /babel.config.js
8 | /metro.config.js
9 |
--------------------------------------------------------------------------------
/examples/Example/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native',
4 | rules: {
5 | 'react/react-in-jsx-scope': 'off',
6 | 'no-bitwise': 'off',
7 | 'no-dupe-class-members': 'off',
8 | semi: 'off',
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/examples/Example/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | **/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 | .kotlin/
37 |
38 | # node.js
39 | #
40 | node_modules/
41 | npm-debug.log
42 | yarn-error.log
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | **/fastlane/report.xml
52 | **/fastlane/Preview.html
53 | **/fastlane/screenshots
54 | **/fastlane/test_output
55 |
56 | # Bundle artifact
57 | *.jsbundle
58 |
59 | # Ruby / CocoaPods
60 | **/Pods/
61 | /vendor/bundle/
62 |
63 | # Temporary files created by Metro to check the health of the file watcher
64 | .metro-health-check*
65 |
66 | # testing
67 | /coverage
68 |
69 | # Yarn
70 | .yarn/*
71 | !.yarn/patches
72 | !.yarn/plugins
73 | !.yarn/releases
74 | !.yarn/sdks
75 | !.yarn/versions
76 |
--------------------------------------------------------------------------------
/examples/Example/.prettierignore:
--------------------------------------------------------------------------------
1 | /.bundle
2 | /.yarn
3 | /android
4 | /ios
5 | /node_modules
6 | /vendor
7 |
--------------------------------------------------------------------------------
/examples/Example/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | semi: true,
8 | };
9 |
--------------------------------------------------------------------------------
/examples/Example/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/examples/Example/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | yarnPath: .yarn/releases/yarn-3.6.4.cjs
4 |
--------------------------------------------------------------------------------
/examples/Example/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby "3.3.5"
5 |
6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9 | gem 'xcodeproj', '< 1.26.0'
10 | gem 'concurrent-ruby', '< 1.3.4'
11 |
12 | # Ruby 3.4.0 has removed some libraries from the standard library.
13 | gem 'bigdecimal'
14 | gem 'logger'
15 | gem 'benchmark'
16 | gem 'mutex_m'
17 |
--------------------------------------------------------------------------------
/examples/Example/README.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | You can run the examples using the instructions below.
4 |
5 | 1. Clone the project
6 |
7 | ```bash
8 | git clone https://github.com/seanhenry/react-native-webgpu.git
9 | ```
10 |
11 | 2. Compile workspace packages
12 |
13 | ```bash
14 | cd packages/react-native-webgpu
15 | yarn build
16 | cd ../..
17 |
18 | cd packages/react-native-webgpu-experimental
19 | yarn build
20 | cd ../..
21 | ```
22 |
23 | 3. Install JavaScript dependencies
24 |
25 | ```bash
26 | cd react-native-webgpu/examples/Example
27 | yarn
28 | ```
29 |
30 | 4. Download WebGPU dependencies
31 |
32 | ```bash
33 | wget https://github.com/seanhenry/react-native-webgpu/releases/download/v0.0.0/Bin+Headers.zip
34 | unzip Bin+Headers.zip -d ../../packages/react-native-webgpu
35 | ```
36 |
37 |
38 | Manual instructions
39 |
40 | - Download `Bin+Headers.zip` from the [release page](https://github.com/seanhenry/react-native-webgpu/releases/tag/v0.0.0).
41 | - Unzip and move the `bin` and `include` folders to `../../packages/react-native-webgpu`
42 |
43 |
44 | 5. Install pods (iOS only)
45 |
46 | ```bash
47 | yarn pod:install
48 | ```
49 |
50 | 6. Build and run
51 |
52 | ```bash
53 | yarn ios
54 | yarn android
55 | ```
56 |
--------------------------------------------------------------------------------
/examples/Example/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/debug.keystore
--------------------------------------------------------------------------------
/examples/Example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/java/com/example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example
2 |
3 | import com.facebook.react.ReactActivity
4 | import com.facebook.react.ReactActivityDelegate
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate
7 |
8 | class MainActivity : ReactActivity() {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | override fun getMainComponentName(): String = "Example"
15 |
16 | /**
17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
19 | */
20 | override fun createReactActivityDelegate(): ReactActivityDelegate =
21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
22 | }
23 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Example
3 |
4 |
--------------------------------------------------------------------------------
/examples/Example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/Example/android/build.gradle:
--------------------------------------------------------------------------------
1 | allprojects {
2 | project.pluginManager.withPlugin("com.facebook.react") {
3 | react {
4 | reactNativeDir = rootProject.file("../../../node_modules/react-native/")
5 | }
6 | }
7 | }
8 |
9 | buildscript {
10 | ext {
11 | buildToolsVersion = "35.0.0"
12 | minSdkVersion = 27
13 | compileSdkVersion = 35
14 | targetSdkVersion = 35
15 | ndkVersion = "27.1.12297006"
16 | kotlinVersion = "2.0.21"
17 | }
18 | repositories {
19 | google()
20 | mavenCentral()
21 | }
22 | dependencies {
23 | classpath("com.android.tools.build:gradle")
24 | classpath("com.facebook.react:react-native-gradle-plugin")
25 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
26 | }
27 | }
28 |
29 | apply plugin: "com.facebook.react.rootproject"
30 |
--------------------------------------------------------------------------------
/examples/Example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/examples/Example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/examples/Example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement { includeBuild("../../../node_modules/@react-native/gradle-plugin") }
2 | plugins { id("com.facebook.react.settings") }
3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
4 | rootProject.name = 'Example'
5 | include ':app'
6 | includeBuild('../../../node_modules/@react-native/gradle-plugin')
7 |
--------------------------------------------------------------------------------
/examples/Example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Example",
3 | "displayName": "Example"
4 | }
5 |
--------------------------------------------------------------------------------
/examples/Example/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | plugins: [
4 | ...require('react-native-webgpu-three/babel').plugins,
5 | 'react-native-reanimated/plugin',
6 | ],
7 | };
8 |
--------------------------------------------------------------------------------
/examples/Example/babel/gltf-babel-transformer.js:
--------------------------------------------------------------------------------
1 | const babelTransformer = require('react-native-webgpu/wgsl-babel-transformer');
2 |
3 | module.exports = {...babelTransformer};
4 | module.exports.transform = function (options) {
5 | if (options.filename.endsWith('.gltf')) {
6 | options.src = `const contents = ${options.src};
7 | export default contents;`;
8 | }
9 | return babelTransformer.transform(options);
10 | };
11 |
--------------------------------------------------------------------------------
/examples/Example/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'fast-text-encoding';
6 | import {AppRegistry, Platform} from 'react-native';
7 | import App from './src/App';
8 | import {name as appName} from './app.json';
9 | import {install, Backends, defaultBackends} from 'react-native-webgpu';
10 | import {
11 | ENABLE_THREADS,
12 | install as installExperimental,
13 | } from 'react-native-webgpu-experimental';
14 | import 'react-native-webgpu-three';
15 |
16 | defaultBackends.current =
17 | Platform.OS === 'android' ? Backends.Vulkan : Backends.All;
18 | install();
19 | installExperimental();
20 | if (ENABLE_THREADS) {
21 | global.reactNativeWebGPUThreads.spawn({
22 | bundleId: 'myThread',
23 | threadId: 'myThread-0',
24 | });
25 | }
26 | AppRegistry.registerComponent(appName, () => App);
27 |
--------------------------------------------------------------------------------
/examples/Example/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/examples/Example/ios/Example.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/Example/ios/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/Example/ios/Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import React
3 | import React_RCTAppDelegate
4 | import ReactAppDependencyProvider
5 |
6 | @main
7 | class AppDelegate: UIResponder, UIApplicationDelegate {
8 | var window: UIWindow?
9 |
10 | var reactNativeDelegate: ReactNativeDelegate?
11 | var reactNativeFactory: RCTReactNativeFactory?
12 |
13 | func application(
14 | _ application: UIApplication,
15 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
16 | ) -> Bool {
17 | let delegate = ReactNativeDelegate()
18 | let factory = RCTReactNativeFactory(delegate: delegate)
19 | delegate.dependencyProvider = RCTAppDependencyProvider()
20 |
21 | reactNativeDelegate = delegate
22 | reactNativeFactory = factory
23 |
24 | window = UIWindow(frame: UIScreen.main.bounds)
25 |
26 | factory.startReactNative(
27 | withModuleName: "Example",
28 | in: window,
29 | launchOptions: launchOptions
30 | )
31 |
32 | return true
33 | }
34 | }
35 |
36 | class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
37 | override func sourceURL(for bridge: RCTBridge) -> URL? {
38 | self.bundleURL()
39 | }
40 |
41 | override func bundleURL() -> URL? {
42 | #if DEBUG
43 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
44 | #else
45 | Bundle.main.url(forResource: "main", withExtension: "jsbundle")
46 | #endif
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/dark_60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/dark_60@2x.png
--------------------------------------------------------------------------------
/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/dark_60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/dark_60@3x.png
--------------------------------------------------------------------------------
/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/icon_60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/icon_60@2x.png
--------------------------------------------------------------------------------
/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/icon_60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/icon_60@3x.png
--------------------------------------------------------------------------------
/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/tinted_60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/tinted_60@2x.png
--------------------------------------------------------------------------------
/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/tinted_60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/ios/Example/Images.xcassets/AppIcon.appiconset/tinted_60@3x.png
--------------------------------------------------------------------------------
/examples/Example/ios/Example/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/examples/Example/ios/Example/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryFileTimestamp
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | C617.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryUserDefaults
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | CA92.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategorySystemBootTime
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | 35F9.1
29 |
30 |
31 |
32 | NSPrivacyAccessedAPIType
33 | NSPrivacyAccessedAPICategoryDiskSpace
34 | NSPrivacyAccessedAPITypeReasons
35 |
36 | 85F4.1
37 |
38 |
39 |
40 | NSPrivacyCollectedDataTypes
41 |
42 | NSPrivacyTracking
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/examples/Example/ios/Podfile:
--------------------------------------------------------------------------------
1 | $WGPUEnableThreads = true
2 |
3 | # Resolve react_native_pods.rb with node to allow for hoisting
4 | require Pod::Executable.execute_command('node', ['-p',
5 | 'require.resolve(
6 | "react-native/scripts/react_native_pods.rb",
7 | {paths: [process.argv[1]]},
8 | )', __dir__]).strip
9 |
10 | platform :ios, min_ios_version_supported
11 | prepare_react_native_project!
12 |
13 | linkage = ENV['USE_FRAMEWORKS']
14 | if linkage != nil
15 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
16 | use_frameworks! :linkage => linkage.to_sym
17 | end
18 |
19 | target 'Example' do
20 | config = use_native_modules!
21 |
22 | use_react_native!(
23 | :path => config[:reactNativePath],
24 | # An absolute path to your application root.
25 | :app_path => "#{Pod::Config.instance.installation_root}/.."
26 | )
27 |
28 | post_install do |installer|
29 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
30 | react_native_post_install(
31 | installer,
32 | config[:reactNativePath],
33 | :mac_catalyst_enabled => false,
34 | # :ccache_enabled => true
35 | )
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/examples/Example/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'react-native',
3 | };
4 |
--------------------------------------------------------------------------------
/examples/Example/metro.config.js:
--------------------------------------------------------------------------------
1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2 | const path = require('path');
3 | const webGpuConfig = require('react-native-webgpu/metro');
4 | const threeConfig = require('react-native-webgpu-three/metro');
5 |
6 | const root = path.resolve(__dirname, '../..');
7 | const defaultConfig = getDefaultConfig(__dirname);
8 |
9 | /**
10 | * Metro configuration
11 | * https://reactnative.dev/docs/metro
12 | *
13 | * @type {import('@react-native/metro-config').MetroConfig}
14 | */
15 | const config = {
16 | watchFolders: [root],
17 | resolver: {
18 | resolveRequest: threeConfig.resolver.resolveRequest,
19 | unstable_enablePackageExports: true,
20 | sourceExts: [
21 | ...defaultConfig.resolver.sourceExts,
22 | ...webGpuConfig.resolver.sourceExts,
23 | 'gltf',
24 | ],
25 | },
26 | transformer: {
27 | babelTransformerPath: require.resolve('./babel/gltf-babel-transformer'),
28 | },
29 | };
30 |
31 | module.exports = mergeConfig(defaultConfig, config);
32 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/Root.tsx:
--------------------------------------------------------------------------------
1 | import {List} from './List';
2 | import {type NavigationProp, useNavigation} from '@react-navigation/native';
3 | import type {Routes} from '../types/navigationTypes';
4 | import {Examples} from './ExampleScreen';
5 | import {useSafeAreaInsets} from 'react-native-safe-area-context';
6 |
7 | export function Root() {
8 | const navigation = useNavigation>();
9 | const insets = useSafeAreaInsets();
10 |
11 | return (
12 |
13 | insets={insets}
14 | onPressItem={item => navigation.navigate('examples', {name: item.title})}
15 | sections={[
16 | {
17 | title: 'Examples',
18 | data: [
19 | {title: 'WebGPUSamples'},
20 | {title: 'Three'},
21 | {title: 'InHouse'},
22 | ],
23 | },
24 | ]}
25 | />
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/Square.tsx:
--------------------------------------------------------------------------------
1 | import {Keyboard, StyleSheet, View} from 'react-native';
2 | import type {ReactNode} from 'react';
3 |
4 | export const Square = ({children}: {children: ReactNode}) => (
5 |
6 | {children}
7 |
8 | );
9 |
10 | const styles = StyleSheet.create({
11 | container: {
12 | width: '100%',
13 | aspectRatio: 1,
14 | },
15 | });
16 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/FunctionController.ts:
--------------------------------------------------------------------------------
1 | import {Controller} from './Controller';
2 | import {ControlComponent} from './types';
3 |
4 | type Fn = () => void;
5 |
6 | export class FunctionController extends Controller {
7 | constructor(object: T, property: keyof T, label?: string) {
8 | super(object, property);
9 | this.name(label ?? String(property));
10 | }
11 |
12 | fire() {
13 | this.change();
14 | this.value.call(this.object);
15 | this.finishChange();
16 | }
17 |
18 | override render(): ControlComponent<'function'> {
19 | return {
20 | type: 'function',
21 | props: {
22 | key: this.key,
23 | title: this.getName(),
24 | disabled: this.disabled,
25 | onPress: () => this.fire(),
26 | },
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/NumberController.ts:
--------------------------------------------------------------------------------
1 | import {Controller} from './Controller';
2 | import {ControlComponent} from './types';
3 |
4 | export class NumberController extends Controller {
5 | constructor(
6 | object: T,
7 | property: keyof T,
8 | private min: unknown,
9 | private max: unknown,
10 | ) {
11 | super(object, property);
12 | }
13 |
14 | render(): ControlComponent<'number'> {
15 | return {
16 | type: 'number',
17 | props: {
18 | key: this.key,
19 | title: this.getName(),
20 | disabled: this.disabled,
21 | min: typeof this.min === 'number' ? this.min : undefined,
22 | max: typeof this.max === 'number' ? this.max : undefined,
23 | initialValue: this.value,
24 | observable: this.observable,
25 | onChange: value =>
26 | this.setValue(
27 | value,
28 | true, // true because the TextInput is controlled by this.value
29 | ),
30 | onFinishChange: () => this.finishChange(),
31 | },
32 | };
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/OptionsController.ts:
--------------------------------------------------------------------------------
1 | import {Controller} from './Controller';
2 | import {ControlComponent} from './types';
3 |
4 | export class OptionsController extends Controller {
5 | private options: Record;
6 | constructor(object: T, property: keyof T, options: object) {
7 | super(object, property);
8 | if (Array.isArray(options)) {
9 | this.options = {};
10 | options.forEach(opt => {
11 | this.options[String(opt)] = opt;
12 | });
13 | } else {
14 | this.options = options as Record;
15 | }
16 | }
17 |
18 | override setValue(value: unknown, notifyObservers?: boolean) {
19 | const result = super.setValue(value, notifyObservers);
20 | this.finishChange();
21 | return result;
22 | }
23 |
24 | render(): ControlComponent<'options'> {
25 | return {
26 | type: 'options',
27 | props: {
28 | key: this.key,
29 | title: this.getName(),
30 | disabled: this.disabled,
31 | initialValue: String(this.value),
32 | options: Object.entries(this.options).map(([key, value]) => ({
33 | key,
34 | title: key,
35 | onPress: () => this.setValue(value, false),
36 | })),
37 | observable: this.observable,
38 | },
39 | };
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/SliderController.ts:
--------------------------------------------------------------------------------
1 | import {Controller} from './Controller';
2 | import {ControlComponent} from './types';
3 | import {calculateStep} from '../sliderUtils';
4 |
5 | export class SliderController extends Controller {
6 | constructor(
7 | object: T,
8 | property: keyof T,
9 | private min: number,
10 | private max: number,
11 | private _step: unknown,
12 | ) {
13 | super(object, property);
14 | }
15 |
16 | render(): ControlComponent<'slider'> {
17 | return {
18 | type: 'slider',
19 | props: {
20 | key: this.key,
21 | title: this.getName(),
22 | disabled: this.disabled,
23 | min: this.min,
24 | max: this.max,
25 | step:
26 | typeof this._step === 'number'
27 | ? this._step
28 | : calculateStep(this.value),
29 | initialValue: this.value,
30 | observable: this.observable,
31 | onChange: value => this.setValue(value, false),
32 | onFinishChange: () => this.finishChange(),
33 | },
34 | };
35 | }
36 |
37 | step(step: number) {
38 | this._step = step;
39 | return this;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/StringController.ts:
--------------------------------------------------------------------------------
1 | import {Controller} from './Controller';
2 | import {ControlComponent} from './types';
3 |
4 | export class StringController extends Controller {
5 | render(): ControlComponent<'string'> {
6 | return {
7 | type: 'string',
8 | props: {
9 | key: this.key,
10 | title: this.getName(),
11 | disabled: this.disabled,
12 | initialValue: this.value,
13 | observable: this.observable,
14 | onChange: value =>
15 | this.setValue(
16 | value,
17 | true, // true because the TextInput is controlled by this.value
18 | ),
19 | onFinishChange: () => this.finishChange(),
20 | },
21 | };
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/SwitchController.ts:
--------------------------------------------------------------------------------
1 | import {Controller} from './Controller';
2 | import {ControlComponent} from './types';
3 |
4 | export class SwitchController extends Controller {
5 | override setValue(value: boolean, notifyObservers: boolean) {
6 | const result = super.setValue(value, notifyObservers);
7 | this.finishChange();
8 | return result;
9 | }
10 |
11 | render(): ControlComponent<'switch'> {
12 | return {
13 | type: 'switch',
14 | props: {
15 | key: this.key,
16 | title: this.getName(),
17 | disabled: this.disabled,
18 | initialValue: Boolean(this.value),
19 | onChange: value => this.setValue(value, false),
20 | observable: this.observable,
21 | },
22 | };
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/incrementingId.test.ts:
--------------------------------------------------------------------------------
1 | import {__resetIds, getId} from './incrementingId';
2 |
3 | describe('getId', () => {
4 | beforeEach(() => {
5 | __resetIds();
6 | });
7 |
8 | it('gets id', () => {
9 | expect(getId('test')).toBe(0);
10 | expect(getId('test')).toBe(1);
11 | __resetIds();
12 | expect(getId('test')).toBe(0);
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/dat.gui/incrementingId.ts:
--------------------------------------------------------------------------------
1 | let ids: Record = {};
2 |
3 | export const __resetIds = () => {
4 | ids = {};
5 | };
6 |
7 | export const getId = (key: string) => {
8 | ids[key] ??= 0;
9 | const id = ids[key];
10 | ids[key] += 1;
11 | return id;
12 | };
13 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/ControlBackground.tsx:
--------------------------------------------------------------------------------
1 | import {PropsWithChildren} from 'react';
2 | import {View} from 'react-native';
3 | import {controlsStyles} from './controlsStyles';
4 |
5 | type ControlBackgroundProps = PropsWithChildren<{dark?: boolean}>;
6 |
7 | export const ControlBackground = ({children, dark}: ControlBackgroundProps) => {
8 | return (
9 |
15 | {children}
16 |
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/ControlButton.tsx:
--------------------------------------------------------------------------------
1 | import {Button, ButtonProps} from 'react-native';
2 | import {controlForegroundColor} from './controlsStyles';
3 |
4 | type ControlButtonProps = Pick;
5 |
6 | export const ControlButton = ({
7 | title,
8 | onPress,
9 | disabled,
10 | }: ControlButtonProps) => {
11 | return (
12 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/ControlFolder.tsx:
--------------------------------------------------------------------------------
1 | import {PropsWithChildren, useState} from 'react';
2 | import {Pressable, View} from 'react-native';
3 | import {globalStyles} from '../../globalStyles';
4 | import {controlsStyles} from './controlsStyles';
5 | import {ControlBackground} from './ControlBackground';
6 | import {ControlLabel} from './ControlLabel';
7 | import {ControlInput} from './ControlInput';
8 |
9 | type ControlFolderProps = PropsWithChildren<{
10 | title: string;
11 | initialExpanded?: boolean;
12 | disabled: boolean;
13 | }>;
14 |
15 | export const ControlFolder = ({
16 | title,
17 | children,
18 | disabled,
19 | initialExpanded = false,
20 | }: ControlFolderProps) => {
21 | const [expanded, setExpanded] = useState(initialExpanded);
22 | const caret = expanded ? 'v ' : '> ';
23 | return (
24 | <>
25 | setExpanded(!expanded)} disabled={disabled}>
26 | {({pressed}) => (
27 |
28 |
29 |
30 |
31 |
32 |
33 | )}
34 |
35 |
36 | {expanded ? children : null}
37 |
38 | >
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/ControlInput.tsx:
--------------------------------------------------------------------------------
1 | import {PropsWithChildren} from 'react';
2 | import {View} from 'react-native';
3 | import {controlsStyles} from './controlsStyles';
4 |
5 | type ControlInputProps = PropsWithChildren;
6 |
7 | export const ControlInput = ({children}: ControlInputProps) => {
8 | return {children};
9 | };
10 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/ControlLabel.tsx:
--------------------------------------------------------------------------------
1 | import {Text} from 'react-native';
2 | import {controlsStyles} from './controlsStyles';
3 |
4 | type ControlLabelProps = {
5 | text: string;
6 | };
7 |
8 | export const ControlLabel = ({text}: ControlLabelProps) => {
9 | return {text};
10 | };
11 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/ControlSwitch.tsx:
--------------------------------------------------------------------------------
1 | import {Switch} from 'react-native';
2 | import {useEffect, useState} from 'react';
3 | import {Observable} from '../../../utils/observable';
4 | import {ControlBackground} from './ControlBackground';
5 | import {ControlLabel} from './ControlLabel';
6 | import {ControlInput} from './ControlInput';
7 | import {controlForegroundColor} from './controlsStyles';
8 |
9 | type ControlSwitchProps = {
10 | onChange: (value: boolean) => void;
11 | initialValue?: boolean;
12 | title: string;
13 | disabled: boolean;
14 | observable: Observable;
15 | };
16 |
17 | export const ControlSwitch = ({
18 | onChange,
19 | initialValue,
20 | title,
21 | disabled,
22 | observable,
23 | }: ControlSwitchProps) => {
24 | const [value, setValue] = useState(!!initialValue);
25 | useEffect(() => observable.add(setValue), [observable]);
26 |
27 | return (
28 |
29 |
30 |
31 | {
35 | setValue(val);
36 | onChange(val);
37 | }}
38 | trackColor={{true: controlForegroundColor}}
39 | />
40 |
41 |
42 | );
43 | };
44 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/ControlsContainer.tsx:
--------------------------------------------------------------------------------
1 | import {PropsWithChildren} from 'react';
2 | import {Keyboard, ScrollView, StyleSheet} from 'react-native';
3 | import {useSafeAreaInsets} from 'react-native-safe-area-context';
4 | import {controlGroupBackgroundColor} from './controlsStyles';
5 |
6 | export const ControlsContainer = ({children}: PropsWithChildren) => {
7 | const insets = useSafeAreaInsets();
8 | return (
9 |
14 | {children}
15 |
16 | );
17 | };
18 |
19 | const styles = StyleSheet.create({
20 | scrollView: {
21 | flex: 1,
22 | backgroundColor: controlGroupBackgroundColor,
23 | },
24 | });
25 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/react/controlsStyles.ts:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native';
2 |
3 | export const controlGroupBackgroundColor = '#000000';
4 | export const controlBackgroundColor = '#303030';
5 | export const controlForegroundColor = '#2FA1D6';
6 | export const controlsStyles = StyleSheet.create({
7 | text: {
8 | flex: 1,
9 | color: '#FFF',
10 | paddingVertical: 2,
11 | },
12 | background: {
13 | flexDirection: 'row',
14 | gap: 4,
15 | paddingHorizontal: 4,
16 | paddingVertical: 2,
17 | },
18 | input: {
19 | flex: 2,
20 | flexDirection: 'row',
21 | gap: 4,
22 | },
23 | controlsBackgroundColor: {
24 | backgroundColor: '#1a1a1a',
25 | },
26 | controlsBackgroundColorDark: {
27 | backgroundColor: controlGroupBackgroundColor,
28 | },
29 | });
30 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/controls/sliderUtils.ts:
--------------------------------------------------------------------------------
1 | export const calculateStep = (initialValue: number) => {
2 | if (initialValue === 0) {
3 | return 1;
4 | } else {
5 | return (
6 | Math.pow(10, Math.floor(Math.log(Math.abs(initialValue)) / Math.LN10)) /
7 | 10
8 | );
9 | }
10 | };
11 |
12 | export const clamp = (value: number, min: number, max: number) => {
13 | 'worklet';
14 | return Math.max(min, Math.min(max, value));
15 | };
16 |
17 | export const formatSteppedNumber = (value: number, step: number) => {
18 | 'worklet';
19 | let numDecimals = 0;
20 | const stringStep = `${step}`;
21 | const i = stringStep.indexOf('.');
22 | if (i > -1) {
23 | numDecimals = stringStep.length - i - 1;
24 | }
25 |
26 | const tenTo = Math.pow(10, numDecimals);
27 | return `${Math.round(value * tenTo) / tenTo}`;
28 | };
29 |
30 | export const normalizedBetween = (value: number, min: number, max: number) => {
31 | 'worklet';
32 | if (max === min) {
33 | return min;
34 | }
35 | return clamp((value - min) / (max - min), 0, 1);
36 | };
37 |
38 | export const lerpWithStep = (
39 | value: number,
40 | min: number,
41 | max: number,
42 | step: number,
43 | ) => {
44 | 'worklet';
45 | const unnormalized = value * (max - min);
46 | if (step === 0) {
47 | throw new Error('Step cannot be zero');
48 | }
49 | const stepped = step * Math.round(unnormalized / step);
50 | return clamp(min + stepped, min, max);
51 | };
52 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/globalStyles.ts:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native';
2 |
3 | export const globalStyles = StyleSheet.create({
4 | fill: {
5 | width: '100%',
6 | height: '100%',
7 | },
8 | pressed: {
9 | opacity: 0.6,
10 | },
11 | centerContents: {
12 | justifyContent: 'center',
13 | alignItems: 'center',
14 | },
15 | });
16 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/stats/HudContainer.tsx:
--------------------------------------------------------------------------------
1 | import {PropsWithChildren} from 'react';
2 | import {View} from 'react-native';
3 | import {hudStyles} from './hudStyles';
4 |
5 | type HudContainerProps = PropsWithChildren;
6 |
7 | export const HudContainer = ({children}: HudContainerProps) => {
8 | return {children};
9 | };
10 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/stats/HudLabel.tsx:
--------------------------------------------------------------------------------
1 | import {Text} from 'react-native';
2 | import {hudStyles} from './hudStyles';
3 |
4 | type HudLabelProps = {
5 | text: string;
6 | };
7 |
8 | export const HudLabel = ({text}: HudLabelProps) => (
9 | {text}
10 | );
11 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/stats/HudText.tsx:
--------------------------------------------------------------------------------
1 | import {forwardRef} from 'react';
2 | import {TextInput, TextInputProps} from 'react-native';
3 | import {hudStyles} from './hudStyles';
4 |
5 | export const HudText = forwardRef(
6 | ({style, ...props}, ref) => (
7 |
14 | ),
15 | );
16 | HudText.displayName = 'HudText';
17 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/stats/hudStyles.ts:
--------------------------------------------------------------------------------
1 | import {StyleSheet} from 'react-native';
2 |
3 | export const hudStyles = StyleSheet.create({
4 | container: {
5 | ...StyleSheet.absoluteFillObject,
6 | bottom: undefined,
7 | backgroundColor: '#00000080',
8 | paddingVertical: 2,
9 | paddingHorizontal: 4,
10 | gap: 2,
11 | },
12 | text: {
13 | padding: 0,
14 | margin: 0,
15 | color: '#FFF',
16 | flex: 1,
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/stats/useHudText.tsx:
--------------------------------------------------------------------------------
1 | import {useCallback, useRef, useState} from 'react';
2 | import {HudText} from './HudText';
3 |
4 | type SetText = (text: string) => void;
5 |
6 | export const useHudText = () => {
7 | const setTextRef = useRef(null);
8 | const Component = () => {
9 | // Using state because `setNativeProps` doesn't trigger a layout
10 | const [text, setText] = useState('');
11 | setTextRef.current = setText;
12 | return ;
13 | };
14 | Component.displayName = 'HudText';
15 | const setText = useCallback((text: string) => {
16 | setTextRef.current?.(text);
17 | }, []);
18 | return {
19 | setText,
20 | HudText: Component,
21 | };
22 | };
23 |
--------------------------------------------------------------------------------
/examples/Example/src/Components/stats/useStats.tsx:
--------------------------------------------------------------------------------
1 | import {useRef, useState} from 'react';
2 | import {HudText} from './HudText';
3 |
4 | export const useStats = () => {
5 | const setTextRef = useRef((_text: string) => {});
6 | const statsRef = useRef({
7 | frameDurations: [] as number[],
8 | current: -1,
9 | now() {
10 | return performance.now();
11 | },
12 | begin() {
13 | this.current = this.now();
14 | },
15 | end() {
16 | if (this.current === -1) {
17 | console.warn('Stats.begin() was not called');
18 | return;
19 | }
20 | this.frameDurations.push(this.now() - this.current);
21 | this.current = -1;
22 |
23 | const SAMPLE_INTERVAL = 30;
24 | if (this.frameDurations.length === SAMPLE_INTERVAL) {
25 | const mean =
26 | this.frameDurations.reduce((acc, t) => acc + t, 0) / SAMPLE_INTERVAL;
27 | this.frameDurations = [];
28 | setTextRef.current(`FPS: ${Math.round(1000 / mean)}`);
29 | }
30 | },
31 | });
32 |
33 | const Component = () => {
34 | const [text, setText] = useState('FPS:');
35 | setTextRef.current = setText;
36 | return ;
37 | };
38 | Component.displayName = 'Stats';
39 | return {
40 | stats: statsRef.current,
41 | Stats: Component,
42 | };
43 | };
44 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/AnimateCanvas/AnimateCanvas.tsx:
--------------------------------------------------------------------------------
1 | import {WebGpuView} from 'react-native-webgpu';
2 | import {
3 | Animated,
4 | Easing,
5 | StyleSheet,
6 | useAnimatedValue,
7 | useWindowDimensions,
8 | } from 'react-native';
9 | import {useEffect} from 'react';
10 | import {runResizeCanvas} from '../ResizeCanvas/runResizeCanvas';
11 |
12 | export function AnimateCanvas() {
13 | const window = useWindowDimensions();
14 | const bottom = useAnimatedValue(0);
15 |
16 | useEffect(() => {
17 | Animated.loop(
18 | Animated.sequence([
19 | Animated.timing(bottom, {
20 | toValue: window.height * 0.5,
21 | duration: 2000,
22 | useNativeDriver: false,
23 | easing: Easing.linear,
24 | }),
25 | Animated.timing(bottom, {
26 | toValue: 0,
27 | duration: 2000,
28 | useNativeDriver: false,
29 | easing: Easing.linear,
30 | }),
31 | ]),
32 | ).start();
33 | }, [bottom, window.height]);
34 |
35 | return (
36 |
37 |
38 |
39 | );
40 | }
41 |
42 | const styles = StyleSheet.create({
43 | view: {
44 | position: 'absolute',
45 | top: 0,
46 | left: 0,
47 | right: 0,
48 | },
49 | });
50 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/AnimateCanvas/triangle.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | ortho: mat4x4f,
3 | }
4 |
5 | @group(0) @binding(0) var uniforms: Uniforms;
6 |
7 | @vertex
8 | fn v_main(
9 | @location(0) position: vec4f,
10 | ) -> @builtin(position) vec4f {
11 | return uniforms.ortho * position;
12 | }
13 |
14 | @fragment
15 | fn f_main() -> @location(0) vec4f {
16 | return vec4f(0.0, 1.0, 0.0, 1.0);
17 | }
18 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/CWTriangle/cw-triangle.wgsl:
--------------------------------------------------------------------------------
1 | @vertex
2 | fn v_main(
3 | @builtin(vertex_index) VertexIndex : u32
4 | ) -> @builtin(position) vec4f {
5 | var pos = array( // triangle is drawn clockwise
6 | vec2(0.0, 0.5),
7 | vec2(0.5, -0.5),
8 | vec2(-0.5, -0.5)
9 | );
10 |
11 | return vec4f(pos[VertexIndex], 0.0, 1.0);
12 | }
13 |
14 | @fragment
15 | fn f_main() -> @location(0) vec4f {
16 | return vec4f(1.0, 1.0, 0.0, 1.0);
17 | }
18 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/Outlines/outlines.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | viewProjectionMat: mat4x4f,
3 | }
4 |
5 | struct VertexOut {
6 | @builtin(position) position: vec4f,
7 | }
8 |
9 | @group(0) @binding(0) var uniforms: Uniforms;
10 |
11 | @vertex
12 | fn v_main(@location(0) position: vec3f) -> VertexOut {
13 | var out: VertexOut;
14 | out.position = uniforms.viewProjectionMat * vec4f(position, 1.0);
15 | return out;
16 | }
17 |
18 | @fragment
19 | fn f_cube() -> @location(0) vec4f {
20 | return vec4f(1.0, 0.0, 0.0, 1.0);
21 | }
22 |
23 | @fragment
24 | fn f_outline() -> @location(0) vec4f {
25 | return vec4f(1.0, 1.0, 1.0, 1.0);
26 | }
27 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/Portal/portal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/InHouse/Portal/portal.jpg
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/Portal/portal.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | viewProjectionMat: mat4x4f,
3 | }
4 |
5 | struct VertexOut {
6 | @builtin(position) position: vec4f,
7 | @location(0) uv: vec2f,
8 | }
9 |
10 | @group(0) @binding(0) var uniforms: Uniforms;
11 |
12 | @vertex
13 | fn v_main(@location(0) position: vec3f, @location(1) uv: vec2f) -> VertexOut {
14 | var out: VertexOut;
15 | out.position = uniforms.viewProjectionMat * vec4f(position, 1.0);
16 | out.uv = uv;
17 | return out;
18 | }
19 |
20 | @group(1) @binding(0) var texSampler: sampler;
21 | @group(1) @binding(1) var tex: texture_2d;
22 |
23 | @fragment
24 | fn f_main(@location(0) uv: vec2f) -> @location(0) vec4f {
25 | return textureSample(tex, texSampler, uv);
26 | }
27 |
28 | @vertex
29 | fn v_portal(@location(0) position: vec3f) -> VertexOut {
30 | var out: VertexOut;
31 | out.position = uniforms.viewProjectionMat * vec4f(position, 1.0);
32 | return out;
33 | }
34 |
35 | @fragment
36 | fn f_portal() -> @location(0) vec4f {
37 | return vec4f(1.0, 0.0, 0.0, 1.0);
38 | }
39 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/ResizeCanvas/ResizeCanvas.tsx:
--------------------------------------------------------------------------------
1 | import {WebGpuView} from 'react-native-webgpu';
2 | import {useWindowDimensions} from 'react-native';
3 | import {useEffect, useState} from 'react';
4 | import {runResizeCanvas} from './runResizeCanvas';
5 |
6 | export function ResizeCanvas() {
7 | const window = useWindowDimensions();
8 | const [height, setHeight] = useState(window.height * 0.2);
9 |
10 | useEffect(() => {
11 | let count = 1;
12 | const interval = setInterval(() => {
13 | const heightPercentage = 0.2 * (1 + (count % 4));
14 | setHeight(heightPercentage * window.height);
15 | count += 1;
16 | }, 500);
17 | return () => clearInterval(interval);
18 | }, [window.height]);
19 |
20 | return ;
21 | }
22 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/ResizeCanvas/triangle.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | ortho: mat4x4f,
3 | }
4 |
5 | @group(0) @binding(0) var uniforms: Uniforms;
6 |
7 | @vertex
8 | fn v_main(
9 | @location(0) position: vec4f,
10 | ) -> @builtin(position) vec4f {
11 | return uniforms.ortho * position;
12 | }
13 |
14 | @fragment
15 | fn f_main() -> @location(0) vec4f {
16 | return vec4f(0.0, 1.0, 0.0, 1.0);
17 | }
18 |
--------------------------------------------------------------------------------
/examples/Example/src/InHouse/Thread.tsx:
--------------------------------------------------------------------------------
1 | import {ThreadWebGpuView} from 'react-native-webgpu-experimental';
2 | import {globalStyles} from '../Components/globalStyles';
3 | import {Square} from '../Components/Square';
4 |
5 | export const Thread = () => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/BasicGraphics/CubeMap/sampleCubemap.frag.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(1) var mySampler: sampler;
2 | @group(0) @binding(2) var myTexture: texture_cube;
3 |
4 | @fragment
5 | fn main(
6 | @location(0) fragUV: vec2f,
7 | @location(1) fragPosition: vec4f
8 | ) -> @location(0) vec4f {
9 | // Our camera and the skybox cube are both centered at (0, 0, 0)
10 | // so we can use the cube geometry position to get viewing vector to sample
11 | // the cube texture. The magnitude of the vector doesn't matter.
12 | var cubemapVec = fragPosition.xyz - vec3(0.5);
13 | // When viewed from the inside, cubemaps are left-handed (z away from viewer),
14 | // but common camera matrix convention results in a right-handed world space
15 | // (z toward viewer), so we have to flip it.
16 | cubemapVec.z *= -1.0;
17 | return textureSample(myTexture, mySampler, cubemapVec);
18 | }
19 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/BasicGraphics/FractalCube/sampleSelf.frag.wgsl:
--------------------------------------------------------------------------------
1 | @binding(1) @group(0) var mySampler: sampler;
2 | @binding(2) @group(0) var myTexture: texture_2d;
3 |
4 | @fragment
5 | fn main(
6 | @location(0) fragUV: vec2f,
7 | @location(1) fragPosition: vec4f
8 | ) -> @location(0) vec4f {
9 | let texColor = textureSample(myTexture, mySampler, fragUV * 0.8 + vec2(0.1));
10 | let f = select(1.0, 0.0, length(texColor.rgb - vec3(0.5)) < 0.01);
11 | return f * texColor + (1.0 - f) * fragPosition;
12 | }
13 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/BasicGraphics/InstancedCube/instanced.vert.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | modelViewProjectionMatrix : array,
3 | }
4 |
5 | @binding(0) @group(0) var uniforms : Uniforms;
6 |
7 | struct VertexOutput {
8 | @builtin(position) Position : vec4f,
9 | @location(0) fragUV : vec2f,
10 | @location(1) fragPosition: vec4f,
11 | }
12 |
13 | @vertex
14 | fn main(
15 | @builtin(instance_index) instanceIdx : u32,
16 | @location(0) position : vec4f,
17 | @location(1) uv : vec2f
18 | ) -> VertexOutput {
19 | var output : VertexOutput;
20 | output.Position = uniforms.modelViewProjectionMatrix[instanceIdx] * position;
21 | output.fragUV = uv;
22 | output.fragPosition = 0.5 * (position + vec4(1.0));
23 | return output;
24 | }
25 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/BasicGraphics/TexturedCube/sampleTextureMixColor.frag.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(1) var mySampler: sampler;
2 | @group(0) @binding(2) var myTexture: texture_2d;
3 |
4 | @fragment
5 | fn main(
6 | @location(0) fragUV: vec2f,
7 | @location(1) fragPosition: vec4f
8 | ) -> @location(0) vec4f {
9 | return textureSample(myTexture, mySampler, fragUV) * fragPosition;
10 | }
11 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GPGPU/BitonicSort/atomicToZero.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(3) var counter: atomic;
2 |
3 | @compute @workgroup_size(1, 1, 1)
4 | fn atomicToZero() {
5 | let counterValue = atomicLoad(&counter);
6 | atomicSub(&counter, counterValue);
7 | }
8 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GPGPU/ComputeBoids/sprite.wgsl:
--------------------------------------------------------------------------------
1 | struct VertexOutput {
2 | @builtin(position) position : vec4f,
3 | @location(4) color : vec4f,
4 | }
5 |
6 | @vertex
7 | fn vert_main(
8 | @location(0) a_particlePos : vec2f,
9 | @location(1) a_particleVel : vec2f,
10 | @location(2) a_pos : vec2f
11 | ) -> VertexOutput {
12 | let angle = -atan2(a_particleVel.x, a_particleVel.y);
13 | let pos = vec2(
14 | (a_pos.x * cos(angle)) - (a_pos.y * sin(angle)),
15 | (a_pos.x * sin(angle)) + (a_pos.y * cos(angle))
16 | );
17 |
18 | var output : VertexOutput;
19 | output.position = vec4(pos + a_particlePos, 0.0, 1.0);
20 | output.color = vec4(
21 | 1.0 - sin(angle + 1.0) - a_particleVel.y,
22 | pos.x * 100.0 - a_particleVel.y + 0.1,
23 | a_particleVel.x + cos(angle + 0.5),
24 | 1.0);
25 | return output;
26 | }
27 |
28 | @fragment
29 | fn frag_main(@location(4) color : vec4f) -> @location(0) vec4f {
30 | return color;
31 | }
32 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GPGPU/GameOfLife/compute.wgsl:
--------------------------------------------------------------------------------
1 | @binding(0) @group(0) var size: vec2u;
2 | @binding(1) @group(0) var current: array;
3 | @binding(2) @group(0) var next: array;
4 |
5 | // TODO: not supported for some reason (iOS)
6 | //override blockSize = 8;
7 | const blockSize = 8;
8 |
9 | fn getIndex(x: u32, y: u32) -> u32 {
10 | let h = size.y;
11 | let w = size.x;
12 |
13 | return (y % h) * w + (x % w);
14 | }
15 |
16 | fn getCell(x: u32, y: u32) -> u32 {
17 | return current[getIndex(x, y)];
18 | }
19 |
20 | fn countNeighbors(x: u32, y: u32) -> u32 {
21 | return getCell(x - 1, y - 1) + getCell(x, y - 1) + getCell(x + 1, y - 1) +
22 | getCell(x - 1, y) + getCell(x + 1, y) +
23 | getCell(x - 1, y + 1) + getCell(x, y + 1) + getCell(x + 1, y + 1);
24 | }
25 |
26 | @compute @workgroup_size(blockSize, blockSize)
27 | fn main(@builtin(global_invocation_id) grid: vec3u) {
28 | let x = grid.x;
29 | let y = grid.y;
30 | let n = countNeighbors(x, y);
31 | next[getIndex(x, y)] = select(u32(n == 3u), u32(n == 2u || n == 3u), getCell(x, y) == 1u);
32 | }
33 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GPGPU/GameOfLife/frag.wgsl:
--------------------------------------------------------------------------------
1 | @fragment
2 | fn main(@location(0) cell: f32) -> @location(0) vec4f {
3 | return vec4f(cell, cell, cell, 1.);
4 | }
5 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GPGPU/GameOfLife/vert.wgsl:
--------------------------------------------------------------------------------
1 | struct Out {
2 | @builtin(position) pos: vec4f,
3 | @location(0) cell: f32,
4 | }
5 |
6 | @binding(0) @group(0) var size: vec2u;
7 |
8 | @vertex
9 | fn main(@builtin(instance_index) i: u32, @location(0) cell: u32, @location(1) pos: vec2u) -> Out {
10 | let w = size.x;
11 | let h = size.y;
12 | let x = (f32(i % w + pos.x) / f32(w) - 0.5) * 2. * f32(w) / f32(max(w, h));
13 | let y = (f32((i - (i % w)) / w + pos.y) / f32(h) - 0.5) * 2. * f32(h) / f32(max(w, h));
14 |
15 | return Out(vec4f(x, y, 0., 1.), f32(cell));
16 | }
17 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/Cameras/cube.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | modelViewProjectionMatrix : mat4x4f,
3 | }
4 |
5 | @group(0) @binding(0) var uniforms : Uniforms;
6 | @group(0) @binding(1) var mySampler: sampler;
7 | @group(0) @binding(2) var myTexture: texture_2d;
8 |
9 | struct VertexOutput {
10 | @builtin(position) Position : vec4f,
11 | @location(0) fragUV : vec2f,
12 | }
13 |
14 | @vertex
15 | fn vertex_main(
16 | @location(0) position : vec4f,
17 | @location(1) uv : vec2f
18 | ) -> VertexOutput {
19 | return VertexOutput(uniforms.modelViewProjectionMatrix * position, uv);
20 | }
21 |
22 | @fragment
23 | fn fragment_main(@location(0) fragUV: vec2f) -> @location(0) vec4f {
24 | return textureSample(myTexture, mySampler, fragUV);
25 | }
26 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/Cornell/rasterizer.wgsl:
--------------------------------------------------------------------------------
1 | // The lightmap data
2 | @group(1) @binding(0) var lightmap : texture_2d_array;
3 |
4 | // The sampler used to sample the lightmap
5 | @group(1) @binding(1) var smpl : sampler;
6 |
7 | // Vertex shader input data
8 | struct VertexIn {
9 | @location(0) position : vec4f,
10 | @location(1) uv : vec3f,
11 | @location(2) emissive : vec3f,
12 | }
13 |
14 | // Vertex shader output data
15 | struct VertexOut {
16 | @builtin(position) position : vec4f,
17 | @location(0) uv : vec2f,
18 | @location(1) emissive : vec3f,
19 | @interpolate(flat)
20 | @location(2) quad : u32,
21 | }
22 |
23 | @vertex
24 | fn vs_main(input : VertexIn) -> VertexOut {
25 | var output : VertexOut;
26 | output.position = common_uniforms.mvp * input.position;
27 | output.uv = input.uv.xy;
28 | output.quad = u32(input.uv.z + 0.5);
29 | output.emissive = input.emissive;
30 | return output;
31 | }
32 |
33 | @fragment
34 | fn fs_main(vertex_out : VertexOut) -> @location(0) vec4f {
35 | return textureSample(lightmap, smpl, vertex_out.uv, vertex_out.quad) + vec4f(vertex_out.emissive, 1);
36 | }
37 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/Cornell/tonemapper.wgsl:
--------------------------------------------------------------------------------
1 | // The linear-light input framebuffer
2 | @group(0) @binding(0) var input : texture_2d;
3 |
4 | // The tonemapped, gamma-corrected output framebuffer
5 | @group(0) @binding(1) var output : texture_storage_2d<{OUTPUT_FORMAT}, write>;
6 |
7 | const TonemapExposure = 0.5;
8 |
9 | const Gamma = 2.2;
10 |
11 | //override WorkgroupSizeX : u32;
12 | //override WorkgroupSizeY : u32;
13 | const WorkgroupSizeX : u32 = 16;
14 | const WorkgroupSizeY : u32 = 16;
15 |
16 | @compute @workgroup_size(WorkgroupSizeX, WorkgroupSizeY)
17 | fn main(@builtin(global_invocation_id) invocation_id : vec3u) {
18 | let color = textureLoad(input, invocation_id.xy, 0).rgb;
19 | let tonemapped = reinhard_tonemap(color);
20 | textureStore(output, invocation_id.xy, vec4f(tonemapped, 1));
21 | }
22 |
23 | fn reinhard_tonemap(linearColor: vec3f) -> vec3f {
24 | let color = linearColor * TonemapExposure;
25 | let mapped = color / (1+color);
26 | return pow(mapped, vec3f(1 / Gamma));
27 | }
28 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/DeferredRendering/fragmentGBuffersDebugView.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(0) var gBufferNormal: texture_2d;
2 | @group(0) @binding(1) var gBufferAlbedo: texture_2d;
3 | @group(0) @binding(2) var gBufferDepth: texture_depth_2d;
4 |
5 | override canvasSizeWidth: f32;
6 | override canvasSizeHeight: f32;
7 |
8 | @fragment
9 | fn main(
10 | @builtin(position) coord : vec4f
11 | ) -> @location(0) vec4f {
12 | var result : vec4f;
13 | let c = coord.xy / vec2f(canvasSizeWidth, canvasSizeHeight);
14 | if (c.x < 0.33333) {
15 | let rawDepth = textureLoad(
16 | gBufferDepth,
17 | vec2i(floor(coord.xy)),
18 | 0
19 | );
20 | // remap depth into something a bit more visible
21 | let depth = (1.0 - rawDepth) * 50.0;
22 | result = vec4(depth);
23 | } else if (c.x < 0.66667) {
24 | result = textureLoad(
25 | gBufferNormal,
26 | vec2i(floor(coord.xy)),
27 | 0
28 | );
29 | result.x = (result.x + 1.0) * 0.5;
30 | result.y = (result.y + 1.0) * 0.5;
31 | result.z = (result.z + 1.0) * 0.5;
32 | } else {
33 | result = textureLoad(
34 | gBufferAlbedo,
35 | vec2i(floor(coord.xy)),
36 | 0
37 | );
38 | }
39 | return result;
40 | }
41 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/DeferredRendering/fragmentWriteGBuffers.wgsl:
--------------------------------------------------------------------------------
1 | struct GBufferOutput {
2 | @location(0) normal : vec4f,
3 |
4 | // Textures: diffuse color, specular color, smoothness, emissive etc. could go here
5 | @location(1) albedo : vec4f,
6 | }
7 |
8 | @fragment
9 | fn main(
10 | @location(0) fragNormal: vec3f,
11 | @location(1) fragUV : vec2f
12 | ) -> GBufferOutput {
13 | // faking some kind of checkerboard texture
14 | let uv = floor(30.0 * fragUV);
15 | let c = 0.2 + 0.5 * ((uv.x + uv.y) - 2.0 * floor((uv.x + uv.y) / 2.0));
16 |
17 | var output : GBufferOutput;
18 | output.normal = vec4(normalize(fragNormal), 1.0);
19 | output.albedo = vec4(c, c, c, 1.0);
20 |
21 | return output;
22 | }
23 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/DeferredRendering/lightUpdate.wgsl:
--------------------------------------------------------------------------------
1 | struct LightData {
2 | position : vec4f,
3 | color : vec3f,
4 | radius : f32,
5 | }
6 | struct LightsBuffer {
7 | lights: array,
8 | }
9 | @group(0) @binding(0) var lightsBuffer: LightsBuffer;
10 |
11 | struct Config {
12 | numLights : u32,
13 | }
14 | @group(0) @binding(1) var config: Config;
15 |
16 | struct LightExtent {
17 | min : vec4f,
18 | max : vec4f,
19 | }
20 | @group(0) @binding(2) var lightExtent: LightExtent;
21 |
22 | @compute @workgroup_size(64, 1, 1)
23 | fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3u) {
24 | var index = GlobalInvocationID.x;
25 | if (index >= config.numLights) {
26 | return;
27 | }
28 |
29 | lightsBuffer.lights[index].position.y = lightsBuffer.lights[index].position.y - 0.5 - 0.003 * (f32(index) - 64.0 * floor(f32(index) / 64.0));
30 |
31 | if (lightsBuffer.lights[index].position.y < lightExtent.min.y) {
32 | lightsBuffer.lights[index].position.y = lightExtent.max.y;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/DeferredRendering/vertexTextureQuad.wgsl:
--------------------------------------------------------------------------------
1 | @vertex
2 | fn main(
3 | @builtin(vertex_index) VertexIndex : u32
4 | ) -> @builtin(position) vec4f {
5 | var pos = array(
6 | vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0),
7 | vec2(-1.0, 1.0), vec2(1.0, -1.0), vec2(1.0, 1.0),
8 | );
9 |
10 | return vec4f(pos[VertexIndex], 0.0, 1.0);
11 | }
12 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/DeferredRendering/vertexWriteGBuffers.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | modelMatrix : mat4x4f,
3 | normalModelMatrix : mat4x4f,
4 | }
5 | struct Camera {
6 | viewProjectionMatrix : mat4x4f,
7 | invViewProjectionMatrix : mat4x4f,
8 | }
9 | @group(0) @binding(0) var uniforms : Uniforms;
10 | @group(0) @binding(1) var camera : Camera;
11 |
12 | struct VertexOutput {
13 | @builtin(position) Position : vec4f,
14 | @location(0) fragNormal: vec3f, // normal in world space
15 | @location(1) fragUV: vec2f,
16 | }
17 |
18 | @vertex
19 | fn main(
20 | @location(0) position : vec3f,
21 | @location(1) normal : vec3f,
22 | @location(2) uv : vec2f
23 | ) -> VertexOutput {
24 | var output : VertexOutput;
25 | let worldPosition = (uniforms.modelMatrix * vec4(position, 1.0)).xyz;
26 | output.Position = camera.viewProjectionMatrix * vec4(worldPosition, 1.0);
27 | output.fragNormal = normalize((uniforms.normalModelMatrix * vec4(normal, 1.0)).xyz);
28 | output.fragUV = uv;
29 | return output;
30 | }
31 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/ShadowMapping/vertex.wgsl:
--------------------------------------------------------------------------------
1 | struct Scene {
2 | lightViewProjMatrix: mat4x4f,
3 | cameraViewProjMatrix: mat4x4f,
4 | lightPos: vec3f,
5 | }
6 |
7 | struct Model {
8 | modelMatrix: mat4x4f,
9 | }
10 |
11 | @group(0) @binding(0) var scene : Scene;
12 | @group(1) @binding(0) var model : Model;
13 |
14 | struct VertexOutput {
15 | @location(0) shadowPos: vec3f,
16 | @location(1) fragPos: vec3f,
17 | @location(2) fragNorm: vec3f,
18 |
19 | @builtin(position) Position: vec4f,
20 | }
21 |
22 | @vertex
23 | fn main(
24 | @location(0) position: vec3f,
25 | @location(1) normal: vec3f
26 | ) -> VertexOutput {
27 | var output : VertexOutput;
28 |
29 | // XY is in (-1, 1) space, Z is in (0, 1) space
30 | let posFromLight = scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
31 |
32 | // Convert XY to (0, 1)
33 | // Y is flipped because texture coords are Y-down.
34 | output.shadowPos = vec3(
35 | posFromLight.xy * vec2(0.5, -0.5) + vec2(0.5),
36 | posFromLight.z
37 | );
38 |
39 | output.Position = scene.cameraViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
40 | output.fragPos = output.Position.xyz;
41 | output.fragNorm = normal;
42 | return output;
43 | }
44 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/ShadowMapping/vertexShadow.wgsl:
--------------------------------------------------------------------------------
1 | struct Scene {
2 | lightViewProjMatrix: mat4x4f,
3 | cameraViewProjMatrix: mat4x4f,
4 | lightPos: vec3f,
5 | }
6 |
7 | struct Model {
8 | modelMatrix: mat4x4f,
9 | }
10 |
11 | @group(0) @binding(0) var scene : Scene;
12 | @group(1) @binding(0) var model : Model;
13 |
14 | @vertex
15 | fn main(
16 | @location(0) position: vec3f
17 | ) -> @builtin(position) vec4f {
18 | return scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
19 | }
20 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/Wireframe/solidColorLit.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | worldViewProjectionMatrix: mat4x4f,
3 | worldMatrix: mat4x4f,
4 | color: vec4f,
5 | };
6 |
7 | struct Vertex {
8 | @location(0) position: vec4f,
9 | @location(1) normal: vec3f,
10 | };
11 |
12 | struct VSOut {
13 | @builtin(position) position: vec4f,
14 | @location(0) normal: vec3f,
15 | };
16 |
17 | @group(0) @binding(0) var uni: Uniforms;
18 |
19 | @vertex fn vs(vin: Vertex) -> VSOut {
20 | var vOut: VSOut;
21 | vOut.position = uni.worldViewProjectionMatrix * vin.position;
22 | vOut.normal = (uni.worldMatrix * vec4f(vin.normal, 0)).xyz;
23 | return vOut;
24 | }
25 |
26 | @fragment fn fs(vin: VSOut) -> @location(0) vec4f {
27 | let lightDirection = normalize(vec3f(4, 10, 6));
28 | let light = dot(normalize(vin.normal), lightDirection) * 0.5 + 0.5;
29 | return vec4f(uni.color.rgb * light, uni.color.a);
30 | }
31 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/GraphicsTechniques/Wireframe/utils.ts:
--------------------------------------------------------------------------------
1 | export function rand(min?: number, max?: number) {
2 | if (min === undefined) {
3 | max = 1;
4 | min = 0;
5 | } else if (max === undefined) {
6 | max = min;
7 | min = 0;
8 | }
9 | return Math.random() * (max - min) + min;
10 | }
11 |
12 | export function randInt(min: number, max?: number) {
13 | return Math.floor(rand(min, max));
14 | }
15 |
16 | export function randColor() {
17 | return [rand(), rand(), rand(), 1];
18 | }
19 |
20 | export function randElement(arr: T[]): T {
21 | return arr[randInt(arr.length)];
22 | }
23 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/OcclusionQueries/solidColorLit.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | worldViewProjectionMatrix: mat4x4f,
3 | worldMatrix: mat4x4f,
4 | color: vec4f,
5 | };
6 |
7 | struct Vertex {
8 | @location(0) position: vec4f,
9 | @location(1) normal: vec3f,
10 | };
11 |
12 | struct VSOut {
13 | @builtin(position) position: vec4f,
14 | @location(0) normal: vec3f,
15 | };
16 |
17 | @group(0) @binding(0) var uni: Uniforms;
18 |
19 | @vertex fn vs(vin: Vertex) -> VSOut {
20 | var vOut: VSOut;
21 | vOut.position = uni.worldViewProjectionMatrix * vin.position;
22 | vOut.normal = (uni.worldMatrix * vec4f(vin.normal, 0)).xyz;
23 | return vOut;
24 | }
25 |
26 | @fragment fn fs(vin: VSOut) -> @location(0) vec4f {
27 | let lightDirection = normalize(vec3f(4, 10, 6));
28 | let light = dot(normalize(vin.normal), lightDirection) * 0.5 + 0.5;
29 | return vec4f(uni.color.rgb * light, uni.color.a);
30 | }
31 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/ReversedZ/fragment.wgsl:
--------------------------------------------------------------------------------
1 | @fragment
2 | fn main(
3 | @location(0) fragColor: vec4f
4 | ) -> @location(0) vec4f {
5 | return fragColor;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/ReversedZ/fragmentPrecisionErrorPass.wgsl:
--------------------------------------------------------------------------------
1 | @group(1) @binding(0) var depthTexture: texture_depth_2d;
2 |
3 | @fragment
4 | fn main(
5 | @builtin(position) coord: vec4f,
6 | @location(0) clipPos: vec4f
7 | ) -> @location(0) vec4f {
8 | let depthValue = textureLoad(depthTexture, vec2i(floor(coord.xy)), 0);
9 | let v : f32 = abs(clipPos.z / clipPos.w - depthValue) * 2000000.0;
10 | return vec4f(v, v, v, 1.0);
11 | }
12 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/ReversedZ/fragmentTextureQuad.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(0) var depthTexture: texture_depth_2d;
2 |
3 | @fragment
4 | fn main(
5 | @builtin(position) coord : vec4f
6 | ) -> @location(0) vec4f {
7 | let depthValue = textureLoad(depthTexture, vec2i(floor(coord.xy)), 0);
8 | return vec4f(depthValue, depthValue, depthValue, 1.0);
9 | }
10 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/ReversedZ/vertex.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | modelMatrix : array,
3 | }
4 | struct Camera {
5 | viewProjectionMatrix : mat4x4f,
6 | }
7 |
8 | @binding(0) @group(0) var uniforms : Uniforms;
9 | @binding(1) @group(0) var camera : Camera;
10 |
11 | struct VertexOutput {
12 | @builtin(position) Position : vec4f,
13 | @location(0) fragColor : vec4f,
14 | }
15 |
16 | @vertex
17 | fn main(
18 | @builtin(instance_index) instanceIdx : u32,
19 | @location(0) position : vec4f,
20 | @location(1) color : vec4f
21 | ) -> VertexOutput {
22 | var output : VertexOutput;
23 | output.Position = camera.viewProjectionMatrix * uniforms.modelMatrix[instanceIdx] * position;
24 | output.fragColor = color;
25 | return output;
26 | }
27 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/ReversedZ/vertexDepthPrePass.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | modelMatrix : array,
3 | }
4 | struct Camera {
5 | viewProjectionMatrix : mat4x4f,
6 | }
7 |
8 | @binding(0) @group(0) var uniforms : Uniforms;
9 | @binding(1) @group(0) var camera : Camera;
10 |
11 | @vertex
12 | fn main(
13 | @builtin(instance_index) instanceIdx : u32,
14 | @location(0) position : vec4f
15 | ) -> @builtin(position) vec4f {
16 | return camera.viewProjectionMatrix * uniforms.modelMatrix[instanceIdx] * position;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/ReversedZ/vertexPrecisionErrorPass.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | modelMatrix : array,
3 | }
4 | struct Camera {
5 | viewProjectionMatrix : mat4x4f,
6 | }
7 |
8 | @binding(0) @group(0) var uniforms : Uniforms;
9 | @binding(1) @group(0) var camera : Camera;
10 |
11 | struct VertexOutput {
12 | @builtin(position) Position : vec4f,
13 | @location(0) clipPos : vec4f,
14 | }
15 |
16 | @vertex
17 | fn main(
18 | @builtin(instance_index) instanceIdx : u32,
19 | @location(0) position : vec4f
20 | ) -> VertexOutput {
21 | var output : VertexOutput;
22 | output.Position = camera.viewProjectionMatrix * uniforms.modelMatrix[instanceIdx] * position;
23 | output.clipPos = output.Position;
24 | return output;
25 | }
26 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/ReversedZ/vertexTextureQuad.wgsl:
--------------------------------------------------------------------------------
1 | @vertex
2 | fn main(
3 | @builtin(vertex_index) VertexIndex : u32
4 | ) -> @builtin(position) vec4f {
5 | var pos = array(
6 | vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0),
7 | vec2(-1.0, 1.0), vec2(1.0, -1.0), vec2(1.0, 1.0)
8 | );
9 |
10 | return vec4(pos[VertexIndex], 0.0, 1.0);
11 | }
12 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/WebGPUFeatures/SamplerParameters/showTexture.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(0) var tex: texture_2d;
2 |
3 | struct Varying {
4 | @builtin(position) pos: vec4f,
5 | @location(0) texelCoord: vec2f,
6 | @location(1) mipLevel: f32,
7 | }
8 |
9 | const kMipLevels: u32 = 4;
10 | const baseMipSize: u32 = 16;
11 |
12 | @vertex
13 | fn vmain(
14 | @builtin(instance_index) instance_index: u32, // used as mipLevel
15 | @builtin(vertex_index) vertex_index: u32,
16 | ) -> Varying {
17 | var square = array(
18 | vec2f(0, 0), vec2f(0, 1), vec2f(1, 0),
19 | vec2f(1, 0), vec2f(0, 1), vec2f(1, 1),
20 | );
21 | let uv = square[vertex_index];
22 | let pos = vec4(uv * 2 - vec2(1, 1), 0.0, 1.0);
23 |
24 | let mipLevel = instance_index;
25 | let mipSize = f32(u32(1) << (kMipLevels - mipLevel));
26 | let texelCoord = uv * mipSize;
27 | return Varying(pos, texelCoord, f32(mipLevel));
28 | }
29 |
30 | @fragment
31 | fn fmain(vary: Varying) -> @location(0) vec4f {
32 | return textureLoad(tex, vec2u(vary.texelCoord), i32(vary.mipLevel));
33 | }
34 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/Di-3d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/Di-3d.png
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/brickwall_albedo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/brickwall_albedo.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/brickwall_height.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/brickwall_height.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/brickwall_normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/brickwall_normal.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/cubemap/negx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/cubemap/negx.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/cubemap/negy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/cubemap/negy.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/cubemap/negz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/cubemap/negz.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/cubemap/posx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/cubemap/posx.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/cubemap/posy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/cubemap/posy.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/cubemap/posz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/cubemap/posz.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/moon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/moon.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/saturn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/saturn.jpg
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/spiral_height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/spiral_height.png
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/spiral_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/spiral_normal.png
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/toybox_height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/toybox_height.png
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/toybox_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/toybox_normal.png
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/webgpu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/webgpu.png
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/assets/img/wood_albedo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/WebGPUSamples/assets/img/wood_albedo.png
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/meshes/stanfordDragon.ts:
--------------------------------------------------------------------------------
1 | import dragonRawData from './stanfordDragonData';
2 | import {computeProjectedPlaneUVs, generateNormals} from './utils';
3 |
4 | const {positions, normals, triangles} = generateNormals(
5 | Math.PI,
6 | dragonRawData.positions as [number, number, number][],
7 | dragonRawData.cells as [number, number, number][],
8 | );
9 |
10 | const uvs = computeProjectedPlaneUVs(positions, 'xy');
11 |
12 | // Push indices for an additional ground plane
13 | triangles.push(
14 | [positions.length, positions.length + 2, positions.length + 1],
15 | [positions.length, positions.length + 1, positions.length + 3],
16 | );
17 |
18 | // Push vertex attributes for an additional ground plane
19 | // prettier-ignore
20 | positions.push(
21 | [-100, 20, -100], //
22 | [ 100, 20, 100], //
23 | [-100, 20, 100], //
24 | [ 100, 20, -100],
25 | );
26 | normals.push(
27 | [0, 1, 0], //
28 | [0, 1, 0], //
29 | [0, 1, 0], //
30 | [0, 1, 0],
31 | );
32 | uvs.push(
33 | [0, 0], //
34 | [1, 1], //
35 | [0, 1], //
36 | [1, 0],
37 | );
38 |
39 | export const mesh = {
40 | positions,
41 | triangles,
42 | normals,
43 | uvs,
44 | };
45 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/meshes/teapot.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error implicit any, missing declaration file
2 | import teapotData from 'teapot';
3 | import {computeSurfaceNormals} from './utils';
4 |
5 | export const mesh = {
6 | positions: teapotData.positions as [number, number, number][],
7 | triangles: teapotData.cells as [number, number, number][],
8 | normals: [] as [number, number, number][],
9 | };
10 |
11 | // Compute surface normals
12 | mesh.normals = computeSurfaceNormals(mesh.positions, mesh.triangles);
13 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/shaders/basic.vert.wgsl:
--------------------------------------------------------------------------------
1 | struct Uniforms {
2 | modelViewProjectionMatrix : mat4x4f,
3 | }
4 | @binding(0) @group(0) var uniforms : Uniforms;
5 |
6 | struct VertexOutput {
7 | @builtin(position) Position : vec4f,
8 | @location(0) fragUV : vec2f,
9 | @location(1) fragPosition: vec4f,
10 | }
11 |
12 | @vertex
13 | fn main(
14 | @location(0) position : vec4f,
15 | @location(1) uv : vec2f
16 | ) -> VertexOutput {
17 | var output : VertexOutput;
18 | output.Position = uniforms.modelViewProjectionMatrix * position;
19 | output.fragUV = uv;
20 | output.fragPosition = 0.5 * (position + vec4(1.0, 1.0, 1.0, 1.0));
21 | return output;
22 | }
23 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/shaders/fullscreenTexturedQuad.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(0) var mySampler : sampler;
2 | @group(0) @binding(1) var myTexture : texture_2d;
3 |
4 | struct VertexOutput {
5 | @builtin(position) Position : vec4f,
6 | @location(0) fragUV : vec2f,
7 | }
8 |
9 | @vertex
10 | fn vert_main(@builtin(vertex_index) VertexIndex : u32) -> VertexOutput {
11 | var pos = array(
12 | vec2( 1.0, 1.0),
13 | vec2( 1.0, -1.0),
14 | vec2(-1.0, -1.0),
15 | vec2( 1.0, 1.0),
16 | vec2(-1.0, -1.0),
17 | vec2(-1.0, 1.0)
18 | );
19 |
20 | var uv = array(
21 | vec2(1.0, 0.0),
22 | vec2(1.0, 1.0),
23 | vec2(0.0, 1.0),
24 | vec2(1.0, 0.0),
25 | vec2(0.0, 1.0),
26 | vec2(0.0, 0.0)
27 | );
28 |
29 | var output : VertexOutput;
30 | output.Position = vec4(pos[VertexIndex], 0.0, 1.0);
31 | output.fragUV = uv[VertexIndex];
32 | return output;
33 | }
34 |
35 | @fragment
36 | fn frag_main(@location(0) fragUV : vec2f) -> @location(0) vec4f {
37 | return textureSample(myTexture, mySampler, fragUV);
38 | }
39 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/shaders/red.frag.wgsl:
--------------------------------------------------------------------------------
1 | @fragment
2 | fn main() -> @location(0) vec4f {
3 | return vec4(1.0, 0.0, 0.0, 1.0);
4 | }
5 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/shaders/triangle.vert.wgsl:
--------------------------------------------------------------------------------
1 | @vertex
2 | fn main(
3 | @builtin(vertex_index) VertexIndex : u32
4 | ) -> @builtin(position) vec4f {
5 | var pos = array(
6 | vec2(0.0, 0.5),
7 | vec2(-0.5, -0.5),
8 | vec2(0.5, -0.5)
9 | );
10 |
11 | return vec4f(pos[VertexIndex], 0.0, 1.0);
12 | }
13 |
--------------------------------------------------------------------------------
/examples/Example/src/WebGPUSamples/shaders/vertexPositionColor.frag.wgsl:
--------------------------------------------------------------------------------
1 | @fragment
2 | fn main(
3 | @location(0) fragUV: vec2f,
4 | @location(1) fragPosition: vec4f
5 | ) -> @location(0) vec4f {
6 | return fragPosition;
7 | }
8 |
--------------------------------------------------------------------------------
/examples/Example/src/assets/images/cropImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seanhenry/react-native-webgpu/f2403751a626a86180ee410f5d89fa61545d79f7/examples/Example/src/assets/images/cropImage.png
--------------------------------------------------------------------------------
/examples/Example/src/types/TextDecoder.d.ts:
--------------------------------------------------------------------------------
1 | type TypedArray =
2 | | Int8Array
3 | | Uint8Array
4 | | Uint8ClampedArray
5 | | Int16Array
6 | | Uint16Array
7 | | Int32Array
8 | | Uint32Array
9 | | Float16Array
10 | | Float32Array
11 | | Float64Array
12 | | BigInt64Array
13 | | BigUint64Array;
14 |
15 | interface TextDecoderInterface {
16 | decode(buffer: ArrayBuffer | TypedArray | DataView): string;
17 | }
18 |
19 | declare var TextDecoder: {
20 | prototype: TextDecoderInterface;
21 | new (encoding: string): TextDecoderInterface;
22 | };
23 |
--------------------------------------------------------------------------------
/examples/Example/src/types/gltf.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.gltf' {
2 | import {GLTF} from '@gltf-transform/core';
3 | var value: GLTF.IGLTF;
4 | export default value;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/Example/src/types/navigationTypes.ts:
--------------------------------------------------------------------------------
1 | import type {Examples, Example} from '../Components/ExampleScreen';
2 |
3 | export type Routes = {
4 | root: undefined;
5 | examples: {
6 | name: Examples;
7 | };
8 | example: {
9 | name: Example;
10 | };
11 | };
12 |
--------------------------------------------------------------------------------
/examples/Example/src/utils/constants.ts:
--------------------------------------------------------------------------------
1 | export const THREE_EXAMPLES_BASE_URL = 'https://threejs.org/examples';
2 | export const WEB_GPU_SAMPLES_BASE_URL =
3 | 'https://webgpu.github.io/webgpu-samples';
4 |
--------------------------------------------------------------------------------
/examples/Example/src/utils/examplesCallback.ts:
--------------------------------------------------------------------------------
1 | import {launchArguments} from './launchArguments';
2 |
3 | let once = false;
4 |
5 | export function examplesCallback(queue?: GPUQueue) {
6 | const {example, callbackid} = launchArguments;
7 | if (!example || !callbackid || once) {
8 | return;
9 | }
10 | once = true;
11 | const message = `${example}-${callbackid}`;
12 | if (!queue) {
13 | reactNativeWebGPUExperimental.socketCallback(message);
14 | return;
15 | }
16 | queue.onSubmittedWorkDone().then(() => {
17 | reactNativeWebGPUExperimental.socketCallback(message);
18 | });
19 | }
20 |
--------------------------------------------------------------------------------
/examples/Example/src/utils/launchArguments.ts:
--------------------------------------------------------------------------------
1 | import {LaunchArguments as RNLaunchArguments} from 'react-native-launch-arguments';
2 |
3 | interface LaunchArguments {
4 | example?: string;
5 | callbackid?: string;
6 | }
7 |
8 | export const launchArguments = RNLaunchArguments.value();
9 |
--------------------------------------------------------------------------------
/examples/Example/src/utils/shaders/flakesTexture.wgsl:
--------------------------------------------------------------------------------
1 | struct VertexOutput {
2 | @builtin(position) position : vec4f,
3 | @location(0) color : vec3f,
4 | }
5 |
6 | const circlePoints: f32 = 10.0;
7 |
8 | @vertex
9 | fn v_main(
10 | @builtin(vertex_index) vertexIndex : u32,
11 | @location(0) radius: f32,
12 | @location(1) position: vec2,
13 | @location(2) color: vec3
14 | ) -> VertexOutput {
15 | var step = vertexIndex / 3;
16 | var remainder = vertexIndex % 3;
17 | var dAngle = radians(360.0) / circlePoints;
18 | var pos = vec4(position, 0.0, 1.0);
19 |
20 | if (remainder == 1) {
21 | var angle = f32(step) * dAngle;
22 | pos.x += radius * cos(angle);
23 | pos.y += radius * sin(angle);
24 | } else if (remainder == 2) {
25 | var angle = f32(step+1) * dAngle;
26 | pos.x += radius * cos(angle);
27 | pos.y += radius * sin(angle);
28 | }
29 |
30 | var out: VertexOutput;
31 | out.position = pos;
32 | out.color = color;
33 | return out;
34 | }
35 |
36 | @fragment
37 | fn f_main(@location(0) color: vec3f) -> @location(0) vec4f {
38 | return vec4(color, 1.0);
39 | }
40 |
--------------------------------------------------------------------------------
/examples/Example/src/utils/shaders/quad.wgsl:
--------------------------------------------------------------------------------
1 | struct VertexOut {
2 | @builtin(position) position: vec4f,
3 | @location(0) uvs: vec2f,
4 | }
5 |
6 | @vertex
7 | fn v_main(@builtin(vertex_index) index: u32) -> VertexOut {
8 | var points = array(
9 | vec2(-1.0, -1.0),
10 | vec2(1.0, 1.0),
11 | vec2(-1.0, 1.0),
12 | vec2(1.0, 1.0),
13 | vec2(-1.0, -1.0),
14 | vec2(1.0, -1.0)
15 | );
16 | var uvs = array(
17 | vec2(0.0, 0.0),
18 | vec2(1.0, 1.0),
19 | vec2(0.0, 1.0),
20 | vec2(1.0, 1.0),
21 | vec2(0.0, 0.0),
22 | vec2(1.0, 0.0)
23 | );
24 |
25 | var out: VertexOut;
26 | out.position = vec4f(points[index], 0.0, 1.0);
27 | out.uvs = uvs[index];
28 | return out;
29 | }
30 |
31 | @group(0) @binding(0) var mySampler: sampler;
32 | @group(0) @binding(1) var myTexture: texture_2d;
33 |
34 | @fragment
35 | fn f_main(in: VertexOut) -> @location(0) vec4f {
36 | return textureSample(myTexture, mySampler, in.uvs);
37 | }
38 |
--------------------------------------------------------------------------------
/examples/Example/src/utils/shaders/videoQuad.wgsl:
--------------------------------------------------------------------------------
1 | @group(0) @binding(0) var texSampler: sampler;
2 | @group(0) @binding(1) var texture: texture_2d;
3 |
4 | struct VertexOutput {
5 | @builtin(position) position : vec4f,
6 | @location(0) uv : vec2f,
7 | }
8 |
9 | @vertex
10 | fn v_main(
11 | @builtin(vertex_index) vertexIndex : u32,
12 | ) -> VertexOutput {
13 | var pos = array(
14 | vec2(1.0, 1.0),
15 | vec2(-1.0, -1.0),
16 | vec2(-1.0, 1.0),
17 | vec2(1.0, 1.0),
18 | vec2(-1.0, -1.0),
19 | vec2(1.0, -1.0)
20 | );
21 | var uvs = array(
22 | vec2(1.0, 1.0),
23 | vec2(0.0, 0.0),
24 | vec2(0.0, 1.0),
25 | vec2(1.0, 1.0),
26 | vec2(0.0, 0.0),
27 | vec2(1.0, 0.0)
28 | );
29 | var out: VertexOutput;
30 | out.position = vec4f(pos[vertexIndex], 0.0, 1.0);
31 | out.uv = uvs[vertexIndex];
32 | return out;
33 | }
34 |
35 |
36 | @fragment
37 | fn f_main(@location(0) uv: vec2f) -> @location(0) vec4f {
38 | return textureSample(texture, texSampler, uv);
39 | }
40 |
--------------------------------------------------------------------------------
/examples/Example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@react-native/typescript-config/tsconfig.json",
3 | "include": [
4 | "**/*",
5 | "../../node_modules/react-native-webgpu/lib/typescript/react-native-webgpu.d.ts",
6 | "../../node_modules/react-native-webgpu-experimental/types/globals.d.ts"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: Google
2 | IndentWidth: 2
3 | ContinuationIndentWidth: 2
4 | ObjCBlockIndentWidth: 2
5 | BracedInitializerIndentWidth: 2
6 | ConstructorInitializerIndentWidth: 2
7 | PPIndentWidth: 2
8 | UseTab: Never
9 | ColumnLimit: 120
10 | LambdaBodyIndentation: OuterScope
11 | Macros:
12 | - WGPU_FUNC_FROM_HOST_FUNC(x, y, z)=fn([]()
13 | - RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(x, y)=- (x)y
14 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | semi: true,
8 | };
9 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/android/gradle.properties:
--------------------------------------------------------------------------------
1 | WebgpuExperimental_kotlinVersion=1.7.0
2 | WebgpuExperimental_minSdkVersion=27
3 | WebgpuExperimental_targetSdkVersion=31
4 | WebgpuExperimental_compileSdkVersion=31
5 | WebgpuExperimental_ndkversion=21.4.7075529
6 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/android/src/main/AndroidManifestNew.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/android/src/main/java/com/webgpu/experimental/CxxBridge.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu.experimental
2 |
3 | import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder
4 |
5 | class CxxBridge {
6 | companion object {
7 | init {
8 | System.loadLibrary("react-native-webgpu-experimental")
9 | }
10 |
11 | external fun installJsi(threadId: String, jsiRuntimeRef: Long, jsCallInvokerHolder: CallInvokerHolder): Boolean
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/android/src/main/java/com/webgpu/experimental/WebgpuExperimentalPackage.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu.experimental
2 |
3 | import com.facebook.react.ReactPackage
4 | import com.facebook.react.bridge.NativeModule
5 | import com.facebook.react.bridge.ReactApplicationContext
6 | import com.facebook.react.uimanager.ViewManager
7 |
8 |
9 | class WebgpuExperimentalPackage : ReactPackage {
10 | override fun createNativeModules(reactContext: ReactApplicationContext): List {
11 | return listOf(WebgpuExperimentalModule(reactContext))
12 | }
13 |
14 | override fun createViewManagers(reactContext: ReactApplicationContext): List> {
15 | return emptyList()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/android/src/newarch/java/com/webgpu/experimental/WebgpuExperimentalModule.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu.experimental
2 |
3 | import com.facebook.react.bridge.ReactApplicationContext
4 |
5 | class WebgpuExperimentalModule(reactContext: ReactApplicationContext): NativeWebgpuExperimentalModuleSpec(reactContext) {
6 | override fun getTypedExportedConstants(): MutableMap {
7 | TODO("Implemented in c++")
8 | }
9 |
10 | override fun installWithThreadId(threadId: String?): Boolean {
11 | TODO("Implemented in c++")
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/cxx/Compression.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | using namespace facebook::jsi;
6 |
7 | namespace wgpu {
8 | Value inflate(Runtime &runtime);
9 | }
10 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/cxx/InstallExperimentalJSI.cpp:
--------------------------------------------------------------------------------
1 | #include "InstallExperimentalJSI.h"
2 |
3 | #include "Compression.h"
4 | #include "SocketCallback.h"
5 | #include "VideoPlayer.h"
6 |
7 | namespace wgpu {
8 | void installExperimentalJSI(Runtime& runtime, std::shared_ptr jsiInstance) {
9 | auto experimental = Object(runtime);
10 | experimental.setProperty(runtime, "inflate", inflate(runtime));
11 | experimental.setProperty(runtime, "makeVideoPlayer", VideoPlayer::factory(runtime));
12 | experimental.setProperty(runtime, "socketCallback", socketCallback(runtime));
13 | runtime.global().setProperty(runtime, "reactNativeWebGPUExperimental", std::move(experimental));
14 | }
15 | } // namespace wgpu
16 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/cxx/InstallExperimentalJSI.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | #include "JSIInstance.h"
6 |
7 | using namespace facebook::jsi;
8 |
9 | namespace wgpu {
10 | void installExperimentalJSI(Runtime& runtime, std::shared_ptr jsiInstance);
11 | }
12 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/cxx/SocketCallback.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | using namespace facebook::jsi;
6 |
7 | namespace wgpu {
8 | Value socketCallback(Runtime &runtime);
9 | }
10 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/cxx/VideoPlayer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 |
7 | #include "WGPUJsiUtils.h"
8 |
9 | using namespace facebook::jsi;
10 |
11 | namespace wgpu {
12 |
13 | class VideoPlayer : public HostObject {
14 | public:
15 | static Object factory(Runtime &runtime) {
16 | return WGPU_FUNC_FROM_HOST_FUNC(makeVideoPlayer, 1, []) {
17 | auto url = arguments[0].asString(runtime).utf8(runtime);
18 | return Object::createFromHostObject(runtime, std::make_shared(url));
19 | });
20 | }
21 | explicit VideoPlayer(const std::string &url);
22 | ~VideoPlayer();
23 | void release();
24 | std::vector getPropertyNames(Runtime &runtime) override;
25 | Value get(Runtime &runtime, const PropNameID &name) override;
26 |
27 | private:
28 | void *videoPlayer = nullptr;
29 | };
30 |
31 | } // namespace wgpu
32 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/cxx/android/WGPUExperimentalJsi.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | using namespace facebook::jsi;
6 |
7 | namespace facebook::react {
8 |
9 | class WGPUExperimentalJsi : public NativeWebgpuExperimentalModuleCxxSpec {
10 | public:
11 | WGPUExperimentalJsi(std::shared_ptr jsInvoker);
12 |
13 | Object getConstants(Runtime &rt);
14 | bool installWithThreadId(Runtime &rt, String threadId);
15 | };
16 | } // namespace facebook::react
17 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/cxx/ios/WGPUExperimentalJsi.h:
--------------------------------------------------------------------------------
1 | #ifdef RCT_NEW_ARCH_ENABLED
2 |
3 | #import
4 |
5 | @interface WGPUExperimentalJsi : NSObject
6 | #else
7 | #import
8 |
9 | @interface WGPUExperimentalJsi : NSObject
10 | #endif
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/react-native.config.js:
--------------------------------------------------------------------------------
1 | // WARNING: Android builds cache these values so delete build directories when changing these values.
2 | // `rm -rf android/build android/app/build`
3 | // See android/build/generated/autolinking/autolinking.json for cached information about cxx
4 | // See android/app/build/generated/autolinking/.../PackageList.java for cached information about java
5 | module.exports = {
6 | dependency: {
7 | platforms: {
8 | android: {
9 | packageImportPath:
10 | 'import com.webgpu.experimental.WebgpuExperimentalPackage;',
11 | packageInstance: 'new WebgpuExperimentalPackage()',
12 | // CMakeLists.txt for our cxx code
13 | cxxModuleCMakeListsPath: './CMakeLists.txt',
14 | // The same name as add_library in CMakeLists.txt
15 | cxxModuleCMakeListsModuleName: 'react-native-webgpu-experimental',
16 | // WGPUExperimentalJsi.h is imported from autolinking.cpp
17 | cxxModuleHeaderName: 'WGPUExperimentalJsi',
18 | },
19 | },
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './ThreadWebGpuView';
2 | export { ENABLE_THREADS, install, installWithThreadId } from './native';
3 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/src/native.ts:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 | import { NativeWebgpuExperimentalModule } from './specs';
3 | import { WebgpuNativeComponent } from 'react-native-webgpu';
4 |
5 | const LINKING_ERROR =
6 | `The package 'react-native-webgpu-experimental' doesn't seem to be linked. Make sure: \n\n` +
7 | Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
8 | '- You rebuilt the app after installing the package\n' +
9 | '- You are not using Expo Go\n';
10 |
11 | if (!NativeWebgpuExperimentalModule) {
12 | throw new Error(LINKING_ERROR);
13 | }
14 |
15 | export const WGPUWebGPUView = WebgpuNativeComponent;
16 |
17 | if (!WGPUWebGPUView) {
18 | throw new Error(LINKING_ERROR);
19 | }
20 |
21 | export const installWithThreadId = (threadId: string) => {
22 | if (!NativeWebgpuExperimentalModule.installWithThreadId(threadId)) {
23 | throw new Error('Failed to install JSI');
24 | }
25 | };
26 |
27 | export const install = () => installWithThreadId('__js');
28 |
29 | export const { ENABLE_THREADS } = NativeWebgpuExperimentalModule.getConstants();
30 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/src/specs/NativeWebgpuExperimentalModule.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import type { TurboModule } from 'react-native';
3 | import { TurboModuleRegistry } from 'react-native';
4 |
5 | interface Spec extends TurboModule {
6 | readonly getConstants: () => { ENABLE_THREADS: boolean };
7 |
8 | installWithThreadId(threadId: string): boolean;
9 | }
10 |
11 | export default TurboModuleRegistry.get('WGPUExperimentalJsi');
12 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/src/specs/index.ts:
--------------------------------------------------------------------------------
1 | export const NativeWebgpuExperimentalModule =
2 | require('./NativeWebgpuExperimentalModule').default;
3 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": ".",
4 | "outDir": "lib",
5 | "declaration": true,
6 | "declarationDir": "lib/typescript",
7 | "allowUnreachableCode": false,
8 | "allowUnusedLabels": false,
9 | "esModuleInterop": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "jsx": "react-jsx",
12 | "lib": ["esnext"],
13 | "module": "esnext",
14 | "moduleResolution": "node",
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitReturns": true,
17 | "noImplicitUseStrict": false,
18 | "noStrictGenericChecks": false,
19 | "noUncheckedIndexedAccess": true,
20 | "noUnusedLocals": true,
21 | "noUnusedParameters": true,
22 | "resolveJsonModule": true,
23 | "skipLibCheck": true,
24 | "strict": true,
25 | "target": "esnext",
26 | "verbatimModuleSyntax": true
27 | },
28 | "include": ["src/**/*.ts", "src/**/*.tsx", "types/*.ts", "../react-native-webgpu/types/*.ts"],
29 | "exclude": ["node_modules"]
30 | }
31 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-experimental/types/globals.d.ts:
--------------------------------------------------------------------------------
1 | declare global {
2 | var reactNativeWebGPUExperimental: {
3 | inflate(arrayBuffer: ArrayBuffer): ArrayBuffer;
4 | makeVideoPlayer(url: string): VideoPlayer;
5 | socketCallback(message: string): void;
6 | };
7 |
8 | var reactNativeWebGPUThreads: {
9 | spawn(input: ThreadInput): void;
10 | attachSurface(input: AttachSurfaceInput): void;
11 | };
12 |
13 | var reactNativeWebGPUThreadsInstance: {
14 | onAttachSurface?: OnAttachSurfacePayload | null;
15 | getContext(): ThreadInstanceContext;
16 | };
17 | }
18 |
19 | type ThreadInput = {
20 | bundleId: string;
21 | threadId: string;
22 | };
23 |
24 | type AttachSurfaceInput = {
25 | uuid: string;
26 | threadId: string;
27 | };
28 |
29 | type OnAttachSurfacePayload = {
30 | uuid: string;
31 | };
32 |
33 | type ThreadInstanceContext = {
34 | threadId: string;
35 | };
36 |
37 | export interface VideoPlayer {
38 | nextPixelBuffer(): PixelBuffer | null;
39 | seek(position: number): void;
40 | play(): void;
41 | release(): void;
42 | }
43 |
44 | export interface PixelBuffer {
45 | planeCount: number;
46 | isInterleaved: boolean;
47 | getWidthOfPlane(index: number): number;
48 | getHeightOfPlane(index: number): number;
49 | getArrayBufferOfPlane(index: number): ArrayBuffer;
50 | getBytesPerRowOfPlane(index: number): number;
51 | width: number;
52 | height: number;
53 | release(): void;
54 | }
55 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /.test*
3 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/.prettierignore:
--------------------------------------------------------------------------------
1 | /.test
2 | /node_modules
3 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/.prettierrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | semi: true,
8 | };
9 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/bin/test-examples:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
4 | cd "$SCRIPT_DIR/.."
5 | node src/index.js examples
6 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/bin/test-package:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
4 | cd "$SCRIPT_DIR/.."
5 | [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
6 | rvm use 3.3.5
7 | node src/index.js package
8 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-webgpu-tests",
3 | "main": "src/index.js",
4 | "engines": {
5 | "node": "20"
6 | },
7 | "type": "module",
8 | "scripts": {
9 | "run:package": "./bin/test-package",
10 | "run:examples": "./bin/test-examples",
11 | "format": "prettier -w .",
12 | "test": "jest"
13 | },
14 | "devDependencies": {
15 | "@inquirer/checkbox": "^4.1.3",
16 | "@inquirer/prompts": "^7.3.3",
17 | "@inquirer/select": "^4.0.10",
18 | "jest": "*",
19 | "prettier": "*"
20 | },
21 | "dependencies": {
22 | "chalk": "^5.4.1"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/src/examples/examples-to-test.js:
--------------------------------------------------------------------------------
1 | export const EXAMPLES_TO_TEST = [
2 | 'HelloTriangle',
3 | 'HelloTriangleMSAA',
4 | 'RotatingCube',
5 | 'TwoCubes',
6 | 'TexturedCube',
7 | 'InstancedCube',
8 | 'FractalCube',
9 | 'CubeMap',
10 | // GPGPU
11 | 'ComputeBoids',
12 | 'GameOfLife',
13 | 'BitonicSort',
14 | // WebGPUFeatures
15 | 'SamplerParameters',
16 | 'ReversedZ',
17 | 'RenderBundles',
18 | 'OcclusionQueries',
19 | // GraphicsTechniques
20 | 'Cameras',
21 | 'NormalMap',
22 | 'ShadowMapping',
23 | 'DeferredRendering',
24 | 'ParticlesHDR',
25 | 'ImageBlur',
26 | 'Cornell',
27 | 'ABuffer',
28 | 'SkinnedMesh',
29 | 'VolumeRendering',
30 | 'Wireframe',
31 | // InHouse
32 | 'FlakesTexture',
33 | 'Crop',
34 | 'Video',
35 | 'Outlines',
36 | 'Portal',
37 | 'CWTriangle',
38 | 'ClearBuffer',
39 | 'ResizeCanvas',
40 | 'AnimateCanvas',
41 | ];
42 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/src/index.js:
--------------------------------------------------------------------------------
1 | if (process.argv.includes('package')) {
2 | await import('./package/package.js');
3 | } else if (process.argv.includes('examples')) {
4 | await import('./examples/examples.js');
5 | }
6 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/src/package/pack.js:
--------------------------------------------------------------------------------
1 | import {exec, rm} from '../utils/shell.js';
2 | import {
3 | WEBGPU_DIR,
4 | WEBGPU_EXPERIMENTAL_DIR,
5 | WEBGPU_THREE_DIR,
6 | WEBGPU_VERSION,
7 | } from '../utils/config.js';
8 | import path from 'node:path';
9 |
10 | export async function pack() {
11 | await clearCache();
12 | await packLibrary('react-native-webgpu', WEBGPU_VERSION, WEBGPU_DIR);
13 | await Promise.all([
14 | packLibrary('react-native-webgpu-three', '0.0.1', WEBGPU_THREE_DIR),
15 | packLibrary(
16 | 'react-native-webgpu-experimental',
17 | '0.0.1',
18 | WEBGPU_EXPERIMENTAL_DIR,
19 | ),
20 | ]);
21 | }
22 |
23 | async function clearCache() {
24 | console.log('Clearing webgpu packages from yarn caches');
25 | await Promise.all([
26 | exec(`rm -f "$(yarn config get cacheFolder)"/react-native-webgpu*`),
27 | exec(`rm -f "$(yarn config get globalFolder)"/cache/react-native-webgpu*`),
28 | ]);
29 | }
30 |
31 | async function packLibrary(name, version, directory) {
32 | console.log(`Packing ${name}`);
33 | await rm('f', path.join(directory, `${name}-${version}.tgz`));
34 | await exec(`npm pack`, {cwd: directory});
35 | }
36 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/src/utils/log.js:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs';
2 | import path from 'node:path';
3 | import {LOGS_DIR} from './config.js';
4 |
5 | /*
6 | Provides a prefixed print function for printing to console and fd/stdio to stream stdio logs to file, specified by fileName.
7 | */
8 | export async function withLog(fileName, prefix, task) {
9 | const fd = fs.openSync(path.join(LOGS_DIR, fileName), 'w');
10 | try {
11 | const print = (...message) => console.log(prefix, ...message);
12 | await task({print, fd, stdio: ['inherit', fd, fd]});
13 | } finally {
14 | fs.close(fd);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-tests/src/utils/queue.js:
--------------------------------------------------------------------------------
1 | export class Queue {
2 | _tasks = [];
3 | push(task) {
4 | this._tasks.push(task);
5 | }
6 |
7 | async execute() {
8 | while (true) {
9 | const [task] = this._tasks.splice(0, 1);
10 | if (!task) {
11 | break;
12 | }
13 | await task();
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/.prettierignore:
--------------------------------------------------------------------------------
1 | src/examples/jsm/capabilities/WebGPU.js
2 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | semi: true,
8 | };
9 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Sean Henry
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/babel/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-export-namespace-from'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/babel/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-webgpu-three-babel",
3 | "version": "1.0.0",
4 | "private": true,
5 | "main": "index"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/metro/index.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const threeRoot = path.resolve(require.resolve('three'), '../..');
3 | const rnThreeRoot = path.resolve(
4 | require.resolve('react-native-webgpu-three'),
5 | '../..',
6 | );
7 |
8 | module.exports = {
9 | resolver: {
10 | resolveRequest: (context, moduleName, platform) => {
11 | const resolved = context.resolveRequest(context, moduleName, platform);
12 | if (
13 | resolved.filePath?.endsWith(
14 | 'three/examples/jsm/capabilities/WebGPU.js',
15 | ) ||
16 | resolved.filePath?.endsWith(
17 | 'three/examples/jsm/nodes/pmrem/PMREMNode.js',
18 | )
19 | ) {
20 | resolved.filePath = path.join(
21 | rnThreeRoot,
22 | resolved.filePath.replace(/^.*\/three\//, 'src/'),
23 | );
24 | } else if (moduleName.startsWith('three/addons/')) {
25 | resolved.filePath = moduleName.replace(
26 | 'three/addons/',
27 | path.resolve(threeRoot, 'examples/jsm') + '/',
28 | );
29 | }
30 | return resolved;
31 | },
32 | },
33 | };
34 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/metro/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-webgpu-three-metro",
3 | "version": "1.0.0",
4 | "private": true,
5 | "main": "index"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-webgpu-three",
3 | "version": "0.0.1",
4 | "description": "Coming soon. Aims to provide support to run [Three.js](https://threejs.org) natively, in React Native.",
5 | "main": "src/index.js",
6 | "types": "types/index.d.ts",
7 | "files": [
8 | "babel",
9 | "metro",
10 | "src",
11 | "types"
12 | ],
13 | "scripts": {
14 | "test": "echo \"Error: no test specified\" && exit 1"
15 | },
16 | "author": "Sean Henry ",
17 | "license": "MIT",
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/seanhenry/react-native-webgpu.git"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/seanhenry/react-native-webgpu/issues"
24 | },
25 | "homepage": "https://github.com/seanhenry/react-native-webgpu/tree/main/packages/react-native-webgpu-three",
26 | "publishConfig": {
27 | "registry": "https://registry.npmjs.org/"
28 | },
29 | "peerDependencies": {
30 | "@babel/plugin-transform-export-namespace-from": "^7.24.7",
31 | "fast-text-encoding": "^1.0.6",
32 | "react-native-webgpu": "*",
33 | "three": "0.166.1"
34 | },
35 | "devDependencies": {
36 | "@babel/plugin-transform-export-namespace-from": "^7.25.9",
37 | "fast-text-encoding": "^1.0.6",
38 | "prettier": "^3.3.3",
39 | "react-native-webgpu": "workspace:*"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/src/Image.js:
--------------------------------------------------------------------------------
1 | import {EventDispatcher} from 'three';
2 |
3 | export class Image extends EventDispatcher {
4 | constructor() {
5 | super();
6 | this._threeImageBitmap = null;
7 | }
8 | set src(src) {
9 | reactNativeWebGPU
10 | .createImageBitmap({uri: src})
11 | .then(image => {
12 | this._threeImageBitmap = image;
13 | this.dispatchEvent({type: 'load'});
14 | })
15 | .catch(() => this.dispatchEvent({type: 'error'}));
16 | }
17 |
18 | get data() {
19 | return this._threeImageBitmap;
20 | }
21 |
22 | get width() {
23 | return this.data?.width;
24 | }
25 |
26 | get height() {
27 | return this.data?.height;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/src/constNodePatch.js:
--------------------------------------------------------------------------------
1 | import ConstNode from 'three/examples/jsm/nodes/core/ConstNode';
2 |
3 | ConstNode.prototype.generate = function (builder, output) {
4 | const type = this.getNodeType(builder);
5 |
6 | if (type === 'float' && ['int', 'uint'].includes(output)) {
7 | return `${Math.round(parseFloat(this.generateConst(builder)))}`;
8 | }
9 |
10 | return builder.format(this.generateConst(builder), type, output);
11 | };
12 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/src/debugLogging.js:
--------------------------------------------------------------------------------
1 | export let debugLogging = false;
2 |
3 | export const enableDebugLogging = enable => {
4 | debugLogging = enable;
5 | };
6 |
7 | export const makeLoggingProxy = (target, propNames) =>
8 | new Proxy(target, {
9 | apply: (target, thisArg, argArray) => {
10 | if (debugLogging) {
11 | console.log(
12 | `>> [react-native-webgpu-three] apply: ${propNames.join('.')}(`,
13 | ...argArray,
14 | ')',
15 | );
16 | }
17 | return Reflect.apply(target, thisArg, argArray);
18 | },
19 | get(target, propName, receiver) {
20 | if (debugLogging) {
21 | console.log(
22 | `>> [react-native-webgpu-three] get: ${propNames.join('.')}.${propName.description ?? propName}`,
23 | );
24 | }
25 | return Reflect.get(target, propName, receiver);
26 | },
27 | set(target, propName, value, receiver) {
28 | if (debugLogging) {
29 | console.log(
30 | `>> [react-native-webgpu-three] set: ${propNames.join('.')}.${propName.description ?? propName} = ${value}`,
31 | );
32 | }
33 | return Reflect.set(target, propName, value, receiver);
34 | },
35 | });
36 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/src/index.js:
--------------------------------------------------------------------------------
1 | import 'three/examples/jsm/nodes/math/MathNode';
2 | import './nodeBuilderPatch';
3 | import './constNodePatch';
4 | import './rendererPatch';
5 | import 'fast-text-encoding';
6 | import {makeLoggingProxy} from './debugLogging';
7 | import {Image} from './Image';
8 |
9 | export {ThreeWebGpuView} from './ThreeWebGpuView';
10 | export {enableDebugLogging} from './debugLogging';
11 |
12 | global.document = makeLoggingProxy(
13 | {
14 | createElementNS: makeLoggingProxy(
15 | (ns, name) => {
16 | if (name === 'img') {
17 | return new Image();
18 | }
19 | },
20 | ['document', 'createElementNS'],
21 | ),
22 | addEventListener: makeLoggingProxy(() => {}, [
23 | 'document',
24 | 'addEventListener',
25 | ]),
26 | },
27 | ['document'],
28 | );
29 |
30 | // GLTFLoader.js:2589
31 | global.navigator = makeLoggingProxy(
32 | {
33 | userAgent: 'ReactNative',
34 | scheduling: undefined,
35 | },
36 | ['navigator'],
37 | );
38 |
39 | // CacheNode.js:26
40 | global.parent = makeLoggingProxy({}, ['parent']);
41 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/src/nodeBuilderPatch.js:
--------------------------------------------------------------------------------
1 | import NodeBuilder from 'three/examples/jsm/nodes/core/NodeBuilder.js';
2 | import ParameterNode from 'three/examples/jsm/nodes/core/ParameterNode.js';
3 |
4 | // See DEV.md
5 | // Original code is commented out
6 | NodeBuilder.prototype.flowShaderNode = function (shaderNode) {
7 | const layout = shaderNode.layout;
8 |
9 | let inputs;
10 |
11 | // if ( shaderNode.isArrayInput ) {
12 |
13 | inputs = [];
14 |
15 | for (const input of layout.inputs) {
16 | inputs.push(new ParameterNode(input.type, input.name));
17 | }
18 |
19 | // } else {
20 | //
21 | // inputs = {};
22 |
23 | for (const input of layout.inputs) {
24 | inputs[input.name] = new ParameterNode(input.type, input.name);
25 | }
26 |
27 | // }
28 |
29 | //
30 |
31 | shaderNode.layout = null;
32 |
33 | const callNode = shaderNode.call(inputs);
34 | const flowData = this.flowStagesNode(callNode, layout.type);
35 |
36 | shaderNode.layout = layout;
37 |
38 | return flowData;
39 | };
40 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/src/rendererPatch.js:
--------------------------------------------------------------------------------
1 | import WebGPURenderer from 'three/examples/jsm/renderers/webgpu/WebGPURenderer';
2 |
3 | const superDispose = WebGPURenderer.prototype.dispose;
4 | WebGPURenderer.prototype.dispose = function () {
5 | superDispose.call(this);
6 | this.backend.colorBuffer = null;
7 | if (this.backend.textureUtils) {
8 | this.backend.textureUtils.colorBuffer = null;
9 | }
10 | this.backend.defaultRenderPassdescriptor = null;
11 | this.backend.device = null;
12 | this.backend.parameters = null;
13 | this.backend.context = null;
14 | this.backend.data = null;
15 | };
16 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu-three/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | WebGpuViewProps,
3 | OnCreateSurfacePayload,
4 | } from 'react-native-webgpu';
5 | import type {FC} from 'react';
6 | import type {EventDispatcher} from '@types/three';
7 |
8 | export declare const enableDebugLogging: (enable: boolean) => void;
9 |
10 | interface ThreeOnCreateSurfacePayload extends OnCreateSurfacePayload {
11 | adapter: GPUAdapter;
12 | device: GPUDevice;
13 | rendererParameters: object;
14 | eventsAdapter: EventDispatcher<{
15 | pointerdown: PointerEvent;
16 | pointermove: PointerEvent;
17 | pointerup: PointerEvent;
18 | pointercancel: PointerEvent;
19 | }>;
20 | }
21 |
22 | interface PointerEvent {
23 | pointerId: string;
24 | pointerType: 'touch';
25 | pageX: number;
26 | pageY: number;
27 | clientX: number;
28 | clientY: number;
29 | }
30 |
31 | interface ThreeWebGpuViewProps
32 | extends Omit {
33 | onCreateSurface(payload: ThreeOnCreateSurfacePayload): void;
34 | }
35 |
36 | export declare const ThreeWebGpuView: FC;
37 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: Google
2 | IndentWidth: 2
3 | ContinuationIndentWidth: 2
4 | ObjCBlockIndentWidth: 2
5 | BracedInitializerIndentWidth: 2
6 | ConstructorInitializerIndentWidth: 2
7 | PPIndentWidth: 2
8 | UseTab: Never
9 | ColumnLimit: 120
10 | LambdaBodyIndentation: OuterScope
11 | Macros:
12 | - WGPU_FUNC_FROM_HOST_FUNC(x, y, z)=fn([]()
13 | - RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(x, y)=- (x)y
14 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | semi: true,
8 | };
9 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/gradle.properties:
--------------------------------------------------------------------------------
1 | Webgpu_kotlinVersion=1.7.0
2 | Webgpu_minSdkVersion=27
3 | Webgpu_targetSdkVersion=31
4 | Webgpu_compileSdkVersion=31
5 | Webgpu_ndkversion=21.4.7075529
6 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/AndroidManifestNew.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/java/com/webgpu/BitmapLoaderFactory.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import com.facebook.proguard.annotations.DoNotStrip
4 | import com.facebook.react.bridge.ReactApplicationContext
5 | import com.facebook.react.modules.blob.BlobModule
6 |
7 | @DoNotStrip
8 | class BitmapLoaderFactory(val blobModule: BlobModule?, val context: ReactApplicationContext) {
9 | @DoNotStrip
10 | fun makeHttpBitmapLoader(uri: String): HTTPBitmapLoader {
11 | return HTTPBitmapLoader(uri)
12 | }
13 |
14 | @DoNotStrip
15 | fun makeDrawableBitmapLoader(uri: String): DrawableBitmapLoader {
16 | return DrawableBitmapLoader(uri, context)
17 | }
18 |
19 | @DoNotStrip
20 | fun makeBlobBitmapLoader(): BlobBitmapLoader? {
21 | return blobModule?.let { BlobBitmapLoader(it) }
22 | }
23 | }
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/java/com/webgpu/BlobBitmapLoader.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import android.graphics.BitmapFactory
4 | import android.os.SharedMemory
5 | import android.system.OsConstants
6 | import com.facebook.proguard.annotations.DoNotStrip
7 | import com.facebook.react.modules.blob.BlobModule
8 |
9 | @DoNotStrip
10 | class BlobBitmapLoader(val blobModule: BlobModule) {
11 | @DoNotStrip
12 | var sharedMemory: SharedMemory? = null
13 | private set
14 | @DoNotStrip
15 | var width = 0
16 | private set
17 |
18 | @DoNotStrip
19 | var height = 0
20 | private set
21 |
22 | @DoNotStrip
23 | fun loadBitmap(blobId: String, offset: Int, size: Int): Int {
24 | val blob = blobModule.resolve(blobId, offset, size) ?: return 1
25 | val bitmap = BitmapFactory.decodeByteArray(blob, 0, blob.size)
26 | this.sharedMemory = SharedMemory.create(blobId, bitmap.width * bitmap.height * 4).apply {
27 | bitmap.copyPixelsToBuffer(mapReadWrite())
28 | setProtect(OsConstants.PROT_READ)
29 | }
30 | width = bitmap.width
31 | height = bitmap.height
32 | return 0
33 | }
34 | }
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/java/com/webgpu/CxxBridge.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import android.view.Surface
4 | import com.facebook.react.bridge.queue.QueueThreadExceptionHandler
5 | import com.facebook.react.modules.blob.BlobModule
6 | import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder
7 |
8 | class CxxBridge {
9 | companion object {
10 | init {
11 | System.loadLibrary("react-native-webgpu")
12 | }
13 |
14 | external fun installJsi(threadId: String, jsiRuntimeRef: Long, jsCallInvokerHolder: CallInvokerHolder): Boolean
15 | external fun onSurfaceCreated(surface: Surface, uuid: String, density: Float, backends: Int): Boolean
16 | external fun onSurfaceDestroyed(uuid: String)
17 | external fun setJavaModules(factory: BitmapLoaderFactory?, exceptionHandler: ExceptionHandler)
18 | }
19 | }
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/java/com/webgpu/ExceptionHandler.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import com.facebook.proguard.annotations.DoNotStrip
4 | import com.facebook.react.bridge.ReactApplicationContext
5 | import com.facebook.react.common.JavascriptException
6 |
7 | @DoNotStrip
8 | class ExceptionHandler(val context: ReactApplicationContext) {
9 | @DoNotStrip
10 | fun handleException(message: String) {
11 | context.handleException(JavascriptException(message))
12 | }
13 | }
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/java/com/webgpu/HTTPBitmapLoader.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import android.graphics.BitmapFactory
4 | import android.os.SharedMemory
5 | import android.system.OsConstants
6 | import com.facebook.proguard.annotations.DoNotStrip
7 | import java.io.BufferedInputStream
8 | import java.net.HttpURLConnection
9 | import java.net.URL
10 |
11 | @DoNotStrip
12 | class HTTPBitmapLoader(private val url: String) {
13 | @DoNotStrip
14 | var sharedMemory: SharedMemory? = null
15 | private set
16 | @DoNotStrip
17 | var errorMessage: String? = null
18 | private set
19 | @DoNotStrip
20 | var width = 0
21 | private set
22 | @DoNotStrip
23 | var height = 0
24 | private set
25 |
26 | @DoNotStrip
27 | fun fetchBitmap() {
28 | val connection = URL(url).openConnection() as HttpURLConnection
29 | try {
30 | val inStream = BufferedInputStream(connection.inputStream)
31 | val bitmap = BitmapFactory.decodeStream(inStream)
32 | this.sharedMemory = SharedMemory.create(url, bitmap.width * bitmap.height * 4).apply {
33 | bitmap.copyPixelsToBuffer(mapReadWrite())
34 | setProtect(OsConstants.PROT_READ)
35 | }
36 | width = bitmap.width
37 | height = bitmap.height
38 | } catch (exception: Exception) {
39 | errorMessage = exception.localizedMessage
40 | } finally {
41 | connection.disconnect()
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/java/com/webgpu/WebGPUViewManagerImpl.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import com.facebook.react.uimanager.ThemedReactContext
4 |
5 | object WebGPUViewManagerImpl {
6 | const val NAME = "WGPUWebGPUView"
7 | fun createViewInstance(context: ThemedReactContext) = WebGPUView(context)
8 | fun getExportedCustomBubblingEventTypeConstants(): Map {
9 | return mapOf(
10 | "onCreateSurface" to mapOf(
11 | "phasedRegistrationNames" to mapOf(
12 | "bubbled" to "onCreateSurface"
13 | )
14 | )
15 | )
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/main/java/com/webgpu/WebgpuPackage.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import com.facebook.react.ReactPackage
4 | import com.facebook.react.bridge.NativeModule
5 | import com.facebook.react.bridge.ReactApplicationContext
6 | import com.facebook.react.uimanager.ViewManager
7 |
8 |
9 | class WebgpuPackage : ReactPackage {
10 | override fun createNativeModules(reactContext: ReactApplicationContext): List {
11 | return listOf(WebgpuModule(reactContext))
12 | }
13 |
14 | override fun createViewManagers(reactContext: ReactApplicationContext): List> {
15 | return listOf(WebGPUViewManager(reactContext))
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/newarch/com/webgpu/WebgpuModule.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import com.facebook.react.bridge.ReactApplicationContext
4 | import com.facebook.react.modules.blob.BlobModule
5 |
6 | class WebgpuModule(reactContext: ReactApplicationContext) :
7 | NativeWebgpuModuleSpec(reactContext) {
8 | private val exceptionHandler = ExceptionHandler(reactContext)
9 |
10 | init {
11 | val blobModule = reactContext.getNativeModule(BlobModule::class.java)
12 | val factory = BitmapLoaderFactory(blobModule, reactContext)
13 | CxxBridge.setJavaModules(factory, exceptionHandler)
14 | }
15 |
16 | override fun installWithThreadId(threadId: String): Boolean {
17 | // Turbo module is run from c++
18 | return false
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/android/src/oldarch/com/webgpu/WebGPUViewManager.kt:
--------------------------------------------------------------------------------
1 | package com.webgpu
2 |
3 | import com.facebook.react.bridge.ReactApplicationContext
4 | import com.facebook.react.uimanager.SimpleViewManager
5 | import com.facebook.react.uimanager.ThemedReactContext
6 | import com.facebook.react.uimanager.annotations.ReactProp
7 |
8 | class WebGPUViewManager(
9 | private val callerContext: ReactApplicationContext
10 | ) : SimpleViewManager() {
11 | override fun getName() = WebGPUViewManagerImpl.NAME
12 | override fun createViewInstance(context: ThemedReactContext) = WebGPUViewManagerImpl.createViewInstance(context)
13 | override fun getExportedCustomBubblingEventTypeConstants(): Map {
14 | return WebGPUViewManagerImpl.getExportedCustomBubblingEventTypeConstants()
15 | }
16 | @ReactProp(name = "pollSize")
17 | fun setPollSize(view: WebGPUView, pollSize: Boolean) {
18 | // no-op for Android
19 | }
20 | @ReactProp(name = "backends")
21 | fun setBackends(view: WebGPUView, backends: Int?) {
22 | view.backends = backends
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/AdapterHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "JSIInstance.h"
6 | #include "WGPUWrappers.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class AdapterHostObject : public HostObject {
13 | public:
14 | explicit AdapterHostObject(std::shared_ptr adapter, std::shared_ptr jsiInstance)
15 | : _adapter(adapter), _jsiInstance(jsiInstance) {}
16 | ~AdapterHostObject() {}
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | std::shared_ptr _adapter;
20 |
21 | private:
22 | std::shared_ptr _jsiInstance;
23 | };
24 |
25 | } // namespace wgpu
26 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/AutoReleasePool.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | using namespace facebook::jsi;
6 |
7 | namespace wgpu {
8 |
9 | class AutoReleasePool {
10 | public:
11 | AutoReleasePool() = default;
12 |
13 | template
14 | void add(std::shared_ptr ptr) {
15 | pool.push_back(ptr);
16 | }
17 |
18 | std::shared_ptr addString(Runtime &runtime, const Value &value) {
19 | auto str = std::make_shared(value.asString(runtime).utf8(runtime));
20 | pool.push_back(str);
21 | return str;
22 | }
23 |
24 | void clear() { pool.clear(); }
25 |
26 | ~AutoReleasePool() { pool.clear(); }
27 |
28 | private:
29 | std::vector> pool;
30 | };
31 |
32 | } // namespace wgpu
33 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/BindGroupHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "BindGroupHostObject.h"
2 |
3 | #include "Mixins.h"
4 | #include "WGPUContext.h"
5 | #include "WGPUJsiUtils.h"
6 |
7 | using namespace facebook::jsi;
8 | using namespace wgpu;
9 |
10 | Value BindGroupHostObject::get(Runtime &runtime, const PropNameID &propName) {
11 | auto name = propName.utf8(runtime);
12 |
13 | WGPU_LOG_GET_PROP;
14 |
15 | WGPU_GET_LABEL()
16 |
17 | WGPU_GET_BRAND(GPUBindGroup)
18 |
19 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
20 |
21 | return Value::undefined();
22 | }
23 |
24 | std::vector BindGroupHostObject::getPropertyNames(Runtime &runtime) {
25 | return PropNameID::names(runtime, "label", "__brand");
26 | }
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/BindGroupHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class BindGroupHostObject : public HostObject {
13 | public:
14 | explicit BindGroupHostObject(WGPUBindGroup value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~BindGroupHostObject() { wgpuBindGroupRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUBindGroup getValue() { return _value; }
20 |
21 | private:
22 | WGPUBindGroup _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/BindGroupLayoutHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "BindGroupLayoutHostObject.h"
2 |
3 | #include "Mixins.h"
4 | #include "WGPUContext.h"
5 | #include "WGPUJsiUtils.h"
6 |
7 | using namespace facebook::jsi;
8 | using namespace wgpu;
9 |
10 | Value BindGroupLayoutHostObject::get(Runtime &runtime, const PropNameID &propName) {
11 | auto name = propName.utf8(runtime);
12 |
13 | WGPU_LOG_GET_PROP;
14 |
15 | WGPU_GET_LABEL()
16 |
17 | WGPU_GET_BRAND(GPUBindGroupLayout)
18 |
19 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
20 |
21 | return Value::undefined();
22 | }
23 |
24 | std::vector BindGroupLayoutHostObject::getPropertyNames(Runtime &runtime) {
25 | return PropNameID::names(runtime, "label", "__brand");
26 | }
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/BindGroupLayoutHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class BindGroupLayoutHostObject : public HostObject {
13 | public:
14 | explicit BindGroupLayoutHostObject(WGPUBindGroupLayout value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~BindGroupLayoutHostObject() { wgpuBindGroupLayoutRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUBindGroupLayout getValue() { return _value; }
20 |
21 | private:
22 | WGPUBindGroupLayout _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/BufferHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class BufferHostObject : public HostObject {
13 | public:
14 | explicit BufferHostObject(WGPUBuffer value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~BufferHostObject() { wgpuBufferRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUBuffer getValue() { return _value; }
20 |
21 | private:
22 | WGPUBuffer _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/CommandBufferHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "CommandBufferHostObject.h"
2 |
3 | #include "Mixins.h"
4 | #include "WGPUContext.h"
5 | #include "WGPUJsiUtils.h"
6 |
7 | using namespace facebook::jsi;
8 | using namespace wgpu;
9 |
10 | Value CommandBufferHostObject::get(Runtime &runtime, const PropNameID &propName) {
11 | auto name = propName.utf8(runtime);
12 |
13 | WGPU_LOG_GET_PROP;
14 |
15 | WGPU_GET_LABEL()
16 |
17 | WGPU_GET_BRAND(GPUCommandBuffer)
18 |
19 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
20 |
21 | return Value::undefined();
22 | }
23 |
24 | std::vector CommandBufferHostObject::getPropertyNames(Runtime &runtime) {
25 | return PropNameID::names(runtime, "label", "__brand");
26 | }
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/CommandBufferHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class CommandBufferHostObject : public HostObject {
13 | public:
14 | explicit CommandBufferHostObject(WGPUCommandBuffer value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~CommandBufferHostObject() { wgpuCommandBufferRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUCommandBuffer getValue() { return _value; }
20 |
21 | private:
22 | WGPUCommandBuffer _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/CommandEncoderHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class CommandEncoderHostObject : public HostObject {
13 | public:
14 | explicit CommandEncoderHostObject(WGPUCommandEncoder value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~CommandEncoderHostObject() { wgpuCommandEncoderRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 |
20 | private:
21 | WGPUCommandEncoder _value;
22 | std::shared_ptr _context;
23 | std::string _label;
24 | };
25 |
26 | } // namespace wgpu
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ComputePassEncoderHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class ComputePassEncoderHostObject : public HostObject {
13 | public:
14 | explicit ComputePassEncoderHostObject(WGPUComputePassEncoder value, std::shared_ptr context,
15 | std::string label)
16 | : _value(value), _context(context), _label(label) {}
17 | ~ComputePassEncoderHostObject() { release(); }
18 | std::vector getPropertyNames(Runtime &runtime) override;
19 | Value get(Runtime &runtime, const PropNameID &name) override;
20 | void release() {
21 | if (_value != nullptr) {
22 | wgpuComputePassEncoderRelease(_value);
23 | _value = nullptr;
24 | }
25 | }
26 |
27 | private:
28 | WGPUComputePassEncoder _value;
29 | std::shared_ptr _context;
30 | std::string _label;
31 | };
32 |
33 | } // namespace wgpu
34 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ComputePipelineHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "ComputePipelineHostObject.h"
2 |
3 | #include "BindGroupLayoutHostObject.h"
4 | #include "Mixins.h"
5 | #include "WGPUContext.h"
6 | #include "WGPUJsiUtils.h"
7 |
8 | using namespace facebook::jsi;
9 | using namespace wgpu;
10 |
11 | Value ComputePipelineHostObject::get(Runtime &runtime, const PropNameID &propName) {
12 | auto name = propName.utf8(runtime);
13 |
14 | WGPU_LOG_GET_PROP;
15 |
16 | if (name == "getBindGroupLayout") {
17 | return WGPU_FUNC_FROM_HOST_FUNC(getBindGroupLayout, 1, [this]) {
18 | WGPU_LOG_FUNC_ARGS(getBindGroupLayout);
19 | auto index = (uint32_t)arguments[0].asNumber();
20 | auto layout = wgpuComputePipelineGetBindGroupLayout(_value, index);
21 | _context->getErrorHandler()->throwPendingJSIError();
22 | return Object::createFromHostObject(runtime, std::make_shared(layout, _context, ""));
23 | });
24 | }
25 |
26 | WGPU_GET_LABEL()
27 |
28 | WGPU_GET_BRAND(GPUComputePipeline)
29 |
30 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
31 |
32 | return Value::undefined();
33 | }
34 |
35 | std::vector ComputePipelineHostObject::getPropertyNames(Runtime &runtime) {
36 | return PropNameID::names(runtime, "getBindGroupLayout", "label", "__brand");
37 | }
38 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ComputePipelineHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class ComputePipelineHostObject : public HostObject {
13 | public:
14 | explicit ComputePipelineHostObject(WGPUComputePipeline value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~ComputePipelineHostObject() { wgpuComputePipelineRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUComputePipeline getValue() { return _value; }
20 |
21 | private:
22 | WGPUComputePipeline _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ContextHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "Surface.h"
6 | #include "WGPUContext.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class ContextHostObject : public HostObject {
13 | public:
14 | explicit ContextHostObject(std::weak_ptr surface) : _surface(surface) {}
15 | ~ContextHostObject() {}
16 | std::vector getPropertyNames(Runtime &runtime) override;
17 | Value get(Runtime &runtime, const PropNameID &name) override;
18 | inline bool isSurfaceConfigured() { return _configuredContext != nullptr; }
19 | void throwPendingJSIError();
20 |
21 | private:
22 | std::weak_ptr _surface;
23 | std::shared_ptr _strongSurface;
24 | std::shared_ptr _configuredContext;
25 | WGPUTexture _texture = nullptr;
26 | };
27 |
28 | } // namespace wgpu
29 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/CreateImageBitmap.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "JSIInstance.h"
6 |
7 | using namespace facebook::jsi;
8 |
9 | namespace wgpu {
10 |
11 | Function createImageBitmap(Runtime &runtime, std::shared_ptr jsiInstance);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/DeviceHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #import "webgpu.h"
7 | #import "wgpu.h"
8 |
9 | using namespace facebook::jsi;
10 |
11 | namespace wgpu {
12 |
13 | class DeviceHostObject : public HostObject {
14 | public:
15 | explicit DeviceHostObject(std::shared_ptr value, std::shared_ptr context)
16 | : _value(value), _context(context) {}
17 | ~DeviceHostObject() {}
18 | std::vector getPropertyNames(Runtime &runtime) override;
19 | Value get(Runtime &runtime, const PropNameID &name) override;
20 | inline WGPUAdapter getAdapter() { return _context->getAdapter(); }
21 | inline WGPUDevice getValue() { return _value->_device; }
22 | inline std::shared_ptr getContext() { return _context; }
23 |
24 | private:
25 | std::shared_ptr _value;
26 | std::shared_ptr _context;
27 | };
28 |
29 | } // namespace wgpu
30 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ErrorHandler.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | #include "webgpu.h"
10 |
11 | using namespace facebook::jsi;
12 |
13 | namespace wgpu {
14 |
15 | typedef struct Error {
16 | WGPUErrorType type;
17 | std::string message;
18 | } Error;
19 |
20 | class ErrorHandler {
21 | public:
22 | explicit ErrorHandler() {}
23 | void pushError(WGPUErrorType type, char const *message) {
24 | _errors.push({
25 | .type = type,
26 | .message = std::string(message),
27 | });
28 | }
29 | bool hasError() { return !_errors.empty(); }
30 | Error popError() {
31 | auto error = std::move(_errors.front());
32 | _errors.pop();
33 | return error;
34 | }
35 | void throwPendingJSIError() {
36 | if (hasError()) {
37 | auto error = popError();
38 | throw JSINativeException(error.message.data());
39 | }
40 | }
41 |
42 | private:
43 | std::queue _errors;
44 | };
45 |
46 | } // namespace wgpu
47 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ExampleHostObject.cpp:
--------------------------------------------------------------------------------
1 | // #include "ExampleHostObject.h"
2 | // #include "Mixins.h"
3 | // #include "WGPUJsiUtils.h"
4 | // #include "WGPUContext.h"
5 | //
6 | // using namespace facebook::jsi;
7 | // using namespace wgpu;
8 | //
9 | // Value ExampleHostObject::get(Runtime &runtime, const PropNameID &propName) {
10 | // auto name = propName.utf8(runtime);
11 | //
12 | // WGPU_LOG_GET_PROP;
13 | //
14 | // WGPU_GET_LABEL()
15 | // WGPU_GET_BRAND(GPUExample)
16 | //
17 | // WGPU_LOG_UNIMPLEMENTED_GET_PROP;
18 | //
19 | // return Value::undefined();
20 | // }
21 | //
22 | // std::vector ExampleHostObject::getPropertyNames(Runtime& runtime) {
23 | // return PropNameID::names(runtime, "label", "__brand");
24 | // }
25 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ExampleHostObject.h:
--------------------------------------------------------------------------------
1 | // #pragma once
2 | //
3 | // #include
4 | // #include "WGPUContext.h"
5 | // #include "webgpu.h"
6 | //
7 | // using namespace facebook::jsi;
8 | //
9 | // namespace wgpu {
10 | //
11 | // class ExampleHostObject : public HostObject {
12 | // public:
13 | // explicit ExampleHostObject(WGPUExample value, std::shared_ptr context,
14 | // std::string label): _value(value), _context(context), _label(label) {} ~ExampleHostObject() {
15 | // wgpuExampleRelease(_value); } std::vector getPropertyNames(Runtime& runtime)
16 | // override; Value get(Runtime &runtime, const PropNameID &name) override; WGPUExample _value;
17 | // std::shared_ptr _context;
18 | // std::string _label;
19 | // };
20 | //
21 | // }
22 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ImageBitmapHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "ImageBitmapHostObject.h"
2 |
3 | #include "WGPUJsiUtils.h"
4 |
5 | using namespace facebook::jsi;
6 | using namespace wgpu;
7 |
8 | Value ImageBitmapHostObject::get(Runtime &runtime, const PropNameID &propName) {
9 | auto name = propName.utf8(runtime);
10 |
11 | WGPU_LOG_GET_PROP;
12 |
13 | if (name == "width") {
14 | return Value((int)_width);
15 | }
16 |
17 | if (name == "height") {
18 | return Value((int)_height);
19 | }
20 |
21 | if (name == "close") {
22 | return WGPU_FUNC_FROM_HOST_FUNC(close, 0, [this]) {
23 | WGPU_LOG_FUNC_ARGS(close);
24 | this->destroy();
25 | return Value::undefined();
26 | });
27 | }
28 |
29 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
30 |
31 | return Value::undefined();
32 | }
33 |
34 | std::vector ImageBitmapHostObject::getPropertyNames(Runtime &runtime) {
35 | return PropNameID::names(runtime, "width", "height", "close");
36 | }
37 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ImageBitmapHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | using namespace facebook::jsi;
6 |
7 | namespace wgpu {
8 |
9 | class ImageBitmapHostObject : public HostObject {
10 | public:
11 | explicit ImageBitmapHostObject(uint8_t *data, size_t size, uint32_t width, uint32_t height)
12 | : _data(data), _size(size), _width(width), _height(height) {}
13 |
14 | ~ImageBitmapHostObject() { destroy(); }
15 |
16 | std::vector getPropertyNames(Runtime &runtime) override;
17 | Value get(Runtime &runtime, const PropNameID &name) override;
18 |
19 | void destroy() {
20 | if (_data != nullptr) {
21 | free(_data);
22 | _data = nullptr;
23 | }
24 | }
25 |
26 | uint8_t *_data = nullptr;
27 | size_t _size;
28 | uint32_t _width;
29 | uint32_t _height;
30 | };
31 |
32 | } // namespace wgpu
33 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/InstallRootJSI.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #include "Surface.h"
5 |
6 | using namespace facebook::jsi;
7 |
8 | namespace wgpu {
9 |
10 | void installRootJSI(Runtime& runtime, std::shared_ptr jsiInstance);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/JSIInstance.cpp:
--------------------------------------------------------------------------------
1 | #include "JSIInstance.h"
2 |
3 | using namespace facebook::jsi;
4 | using namespace wgpu;
5 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/JSIInstance.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 |
7 | #include "Thread.h"
8 |
9 | using namespace facebook::jsi;
10 | using namespace wgpu;
11 |
12 | namespace wgpu {
13 |
14 | class JSIInstance {
15 | public:
16 | explicit JSIInstance(Runtime &rt, std::shared_ptr thread) : runtime(rt), jsThread(std::move(thread)) {}
17 | Runtime &runtime;
18 | std::shared_ptr jsThread;
19 | };
20 |
21 | } // namespace wgpu
22 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/PipelineLayoutHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "PipelineLayoutHostObject.h"
2 |
3 | #include "Mixins.h"
4 | #include "WGPUContext.h"
5 | #include "WGPUJsiUtils.h"
6 |
7 | using namespace facebook::jsi;
8 | using namespace wgpu;
9 |
10 | Value PipelineLayoutHostObject::get(Runtime &runtime, const PropNameID &propName) {
11 | auto name = propName.utf8(runtime);
12 |
13 | WGPU_LOG_GET_PROP;
14 |
15 | WGPU_GET_LABEL()
16 |
17 | WGPU_GET_BRAND(GPUPipelineLayout)
18 |
19 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
20 |
21 | return Value::undefined();
22 | }
23 |
24 | std::vector PipelineLayoutHostObject::getPropertyNames(Runtime &runtime) {
25 | return PropNameID::names(runtime, "label", "__brand");
26 | }
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/PipelineLayoutHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class PipelineLayoutHostObject : public HostObject {
13 | public:
14 | explicit PipelineLayoutHostObject(WGPUPipelineLayout value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~PipelineLayoutHostObject() { wgpuPipelineLayoutRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUPipelineLayout getValue() { return _value; }
20 |
21 | private:
22 | WGPUPipelineLayout _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/QuerySetHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "QuerySetHostObject.h"
2 |
3 | #include "ConstantConversion.h"
4 | #include "Mixins.h"
5 | #include "WGPUContext.h"
6 | #include "WGPUJsiUtils.h"
7 |
8 | using namespace facebook::jsi;
9 | using namespace wgpu;
10 |
11 | Value QuerySetHostObject::get(Runtime &runtime, const PropNameID &propName) {
12 | auto name = propName.utf8(runtime);
13 |
14 | WGPU_LOG_GET_PROP;
15 |
16 | if (name == "destroy") {
17 | return WGPU_FUNC_FROM_HOST_FUNC(destroy, 0, [this]) {
18 | WGPU_LOG_FUNC_ARGS(destroy);
19 | wgpuQuerySetDestroy(_value);
20 | _context->getErrorHandler()->throwPendingJSIError();
21 | return Value::undefined();
22 | });
23 | }
24 |
25 | if (name == "type") {
26 | return String::createFromUtf8(runtime, WGPUQuerySetToString(wgpuQuerySetGetType(_value)));
27 | }
28 |
29 | if (name == "count") {
30 | return Value((int)wgpuQuerySetGetCount(_value));
31 | }
32 |
33 | WGPU_GET_LABEL()
34 |
35 | WGPU_GET_BRAND(GPUQuerySet)
36 |
37 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
38 |
39 | return Value::undefined();
40 | }
41 |
42 | std::vector QuerySetHostObject::getPropertyNames(Runtime &runtime) {
43 | return PropNameID::names(runtime, "destroy", "type", "count", "label", "__brand");
44 | }
45 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/QuerySetHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class QuerySetHostObject : public HostObject {
13 | public:
14 | explicit QuerySetHostObject(WGPUQuerySet value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~QuerySetHostObject() { wgpuQuerySetRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUQuerySet getValue() { return _value; }
20 |
21 | private:
22 | WGPUQuerySet _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/QueueHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class QueueHostObject : public HostObject {
13 | public:
14 | explicit QueueHostObject(WGPUQueue value, std::shared_ptr context) : _value(value), _context(context) {}
15 | ~QueueHostObject() { wgpuQueueRelease(_value); }
16 | std::vector getPropertyNames(Runtime &runtime) override;
17 | Value get(Runtime &runtime, const PropNameID &name) override;
18 |
19 | private:
20 | WGPUQueue _value;
21 | std::shared_ptr _context;
22 | };
23 |
24 | } // namespace wgpu
25 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/RenderBundleEncoderHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 |
7 | #include "WGPUContext.h"
8 | #include "webgpu.h"
9 |
10 | using namespace facebook::jsi;
11 |
12 | namespace wgpu {
13 |
14 | class RenderBundleEncoderHostObject : public HostObject {
15 | public:
16 | explicit RenderBundleEncoderHostObject(WGPURenderBundleEncoder value, std::shared_ptr context,
17 | std::string label)
18 | : _value(value), _context(context), _label(label) {}
19 | ~RenderBundleEncoderHostObject() { wgpuRenderBundleEncoderRelease(_value); }
20 | std::vector getPropertyNames(Runtime &runtime) override;
21 | Value get(Runtime &runtime, const PropNameID &name) override;
22 | WGPURenderBundleEncoder getValue() { return _value; }
23 |
24 | private:
25 | WGPURenderBundleEncoder _value;
26 | std::shared_ptr _context;
27 | std::string _label;
28 | };
29 |
30 | } // namespace wgpu
31 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/RenderBundleHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "RenderBundleHostObject.h"
2 |
3 | #include "Mixins.h"
4 | #include "WGPUContext.h"
5 | #include "WGPUJsiUtils.h"
6 |
7 | using namespace facebook::jsi;
8 | using namespace wgpu;
9 |
10 | Value RenderBundleHostObject::get(Runtime &runtime, const PropNameID &propName) {
11 | auto name = propName.utf8(runtime);
12 |
13 | WGPU_LOG_GET_PROP;
14 |
15 | WGPU_GET_LABEL()
16 |
17 | WGPU_GET_BRAND(GPURenderBundle)
18 |
19 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
20 |
21 | return Value::undefined();
22 | }
23 |
24 | std::vector RenderBundleHostObject::getPropertyNames(Runtime &runtime) {
25 | return PropNameID::names(runtime, "label", "__brand");
26 | }
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/RenderBundleHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 |
7 | #include "WGPUContext.h"
8 | #include "webgpu.h"
9 |
10 | using namespace facebook::jsi;
11 |
12 | namespace wgpu {
13 |
14 | class RenderBundleHostObject : public HostObject {
15 | public:
16 | explicit RenderBundleHostObject(WGPURenderBundle value, std::shared_ptr context, std::string label)
17 | : _value(value), _context(context), _label(label) {}
18 | ~RenderBundleHostObject() { wgpuRenderBundleRelease(_value); }
19 | std::vector getPropertyNames(Runtime &runtime) override;
20 | Value get(Runtime &runtime, const PropNameID &name) override;
21 | WGPURenderBundle getValue() { return _value; }
22 |
23 | private:
24 | WGPURenderBundle _value;
25 | std::shared_ptr _context;
26 | std::string _label;
27 | };
28 |
29 | } // namespace wgpu
30 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/RenderPassEncoderHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class RenderPassEncoderHostObject : public HostObject {
13 | public:
14 | explicit RenderPassEncoderHostObject(WGPURenderPassEncoder value, std::shared_ptr context,
15 | std::string label)
16 | : _value(value), _context(context), _label(label) {}
17 | ~RenderPassEncoderHostObject() { release(); }
18 | std::vector getPropertyNames(Runtime &runtime) override;
19 | Value get(Runtime &runtime, const PropNameID &name) override;
20 | void release() {
21 | if (_value != nullptr) {
22 | wgpuRenderPassEncoderRelease(_value);
23 | _value = nullptr;
24 | }
25 | }
26 |
27 | private:
28 | WGPURenderPassEncoder _value;
29 | std::shared_ptr _context;
30 | std::string _label;
31 | };
32 |
33 | } // namespace wgpu
34 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/RenderPipelineHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "RenderPipelineHostObject.h"
2 |
3 | #include "BindGroupLayoutHostObject.h"
4 | #include "Mixins.h"
5 | #include "WGPUContext.h"
6 | #include "WGPUJsiUtils.h"
7 |
8 | using namespace facebook::jsi;
9 | using namespace wgpu;
10 |
11 | Value RenderPipelineHostObject::get(Runtime &runtime, const PropNameID &propName) {
12 | auto name = propName.utf8(runtime);
13 |
14 | WGPU_LOG_GET_PROP;
15 |
16 | if (name == "getBindGroupLayout") {
17 | return WGPU_FUNC_FROM_HOST_FUNC(getBindGroupLayout, 1, [this]) {
18 | WGPU_LOG_FUNC_ARGS(getBindGroupLayout);
19 | auto index = (uint32_t)arguments[0].asNumber();
20 | auto layout = wgpuRenderPipelineGetBindGroupLayout(_value, index);
21 | _context->getErrorHandler()->throwPendingJSIError();
22 | return Object::createFromHostObject(runtime, std::make_shared(layout, _context, ""));
23 | });
24 | }
25 |
26 | WGPU_GET_LABEL()
27 |
28 | WGPU_GET_BRAND(GPURenderPipeline)
29 |
30 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
31 |
32 | return Value::undefined();
33 | }
34 |
35 | std::vector RenderPipelineHostObject::getPropertyNames(Runtime &runtime) {
36 | return PropNameID::names(runtime, "getBindGroupLayout", "label", "__brand");
37 | }
38 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/RenderPipelineHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class RenderPipelineHostObject : public HostObject {
13 | public:
14 | explicit RenderPipelineHostObject(WGPURenderPipeline value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~RenderPipelineHostObject() { wgpuRenderPipelineRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPURenderPipeline getValue() { return _value; }
20 |
21 | private:
22 | WGPURenderPipeline _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/SamplerHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "SamplerHostObject.h"
2 |
3 | #include "Mixins.h"
4 | #include "WGPUContext.h"
5 | #include "WGPUJsiUtils.h"
6 |
7 | using namespace facebook::jsi;
8 | using namespace wgpu;
9 |
10 | Value SamplerHostObject::get(Runtime &runtime, const PropNameID &propName) {
11 | auto name = propName.utf8(runtime);
12 |
13 | WGPU_LOG_GET_PROP;
14 |
15 | WGPU_GET_LABEL()
16 |
17 | WGPU_GET_BRAND(GPUSampler)
18 |
19 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
20 |
21 | return Value::undefined();
22 | }
23 |
24 | std::vector SamplerHostObject::getPropertyNames(Runtime &runtime) {
25 | return PropNameID::names(runtime, "label", "__brand");
26 | }
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/SamplerHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class SamplerHostObject : public HostObject {
13 | public:
14 | explicit SamplerHostObject(WGPUSampler value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~SamplerHostObject() { wgpuSamplerRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUSampler getValue() { return _value; }
20 |
21 | private:
22 | WGPUSampler _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/ShaderModuleHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class ShaderModuleHostObject : public HostObject {
13 | public:
14 | explicit ShaderModuleHostObject(WGPUShaderModule value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~ShaderModuleHostObject() { wgpuShaderModuleRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUShaderModule getValue() { return _value; }
20 |
21 | private:
22 | WGPUShaderModule _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/SurfacesManager.cpp:
--------------------------------------------------------------------------------
1 | #include "SurfacesManager.h"
2 |
3 | namespace wgpu {
4 |
5 | SurfacesManager *SurfacesManager::_instance = new SurfacesManager;
6 |
7 | void SurfacesManager::set(std::string &uuid, std::shared_ptr surface) {
8 | std::lock_guard lock(_mutex);
9 | _surfaces.insert_or_assign(uuid, surface);
10 | }
11 |
12 | void SurfacesManager::remove(std::string &uuid) {
13 | std::lock_guard lock(_mutex);
14 | _surfaces.erase(uuid);
15 | }
16 |
17 | std::weak_ptr SurfacesManager::get(std::string &uuid) {
18 | std::lock_guard lock(_mutex);
19 | std::weak_ptr result;
20 | auto it = _surfaces.find(uuid);
21 | if (it != _surfaces.end()) {
22 | return it->second;
23 | }
24 | return result;
25 | }
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/SurfacesManager.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "Surface.h"
9 |
10 | namespace wgpu {
11 |
12 | class SurfacesManager {
13 | public:
14 | static inline SurfacesManager *getInstance() { return _instance; }
15 | void set(std::string &uuid, std::shared_ptr surface);
16 | void remove(std::string &uuid);
17 | std::weak_ptr get(std::string &uuid);
18 |
19 | private:
20 | static SurfacesManager *_instance;
21 | std::unordered_map> _surfaces;
22 | std::mutex _mutex;
23 | };
24 |
25 | } // namespace wgpu
26 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/TextureHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class TextureHostObject : public HostObject {
13 | public:
14 | explicit TextureHostObject(WGPUTexture value, std::shared_ptr context, std::string label,
15 | bool isSurfaceTexture)
16 | : _value(value), _context(context), _label(label), _isSurfaceTexture(isSurfaceTexture) {}
17 | ~TextureHostObject() { release(); }
18 | std::vector getPropertyNames(Runtime &runtime) override;
19 | Value get(Runtime &runtime, const PropNameID &name) override;
20 | void release() {
21 | if (_value != nullptr && !_isSurfaceTexture) {
22 | wgpuTextureRelease(_value);
23 | _value = nullptr;
24 | }
25 | }
26 | inline WGPUTexture getValue() { return _value; }
27 |
28 | private:
29 | WGPUTexture _value;
30 | std::shared_ptr _context;
31 | std::string _label;
32 | bool _isSurfaceTexture;
33 | };
34 |
35 | } // namespace wgpu
36 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/TextureViewHostObject.cpp:
--------------------------------------------------------------------------------
1 | #include "TextureViewHostObject.h"
2 |
3 | #include "Mixins.h"
4 | #include "WGPUContext.h"
5 | #include "WGPUJsiUtils.h"
6 |
7 | using namespace facebook::jsi;
8 | using namespace wgpu;
9 |
10 | Value TextureViewHostObject::get(Runtime &runtime, const PropNameID &propName) {
11 | auto name = propName.utf8(runtime);
12 |
13 | WGPU_LOG_GET_PROP;
14 |
15 | WGPU_GET_LABEL()
16 |
17 | WGPU_GET_BRAND(GPUTextureView)
18 |
19 | WGPU_LOG_UNIMPLEMENTED_GET_PROP;
20 |
21 | return Value::undefined();
22 | }
23 |
24 | std::vector TextureViewHostObject::getPropertyNames(Runtime &runtime) {
25 | return PropNameID::names(runtime, "label", "__brand");
26 | }
27 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/TextureViewHostObject.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "WGPUContext.h"
6 | #include "webgpu.h"
7 |
8 | using namespace facebook::jsi;
9 |
10 | namespace wgpu {
11 |
12 | class TextureViewHostObject : public HostObject {
13 | public:
14 | explicit TextureViewHostObject(WGPUTextureView value, std::shared_ptr context, std::string label)
15 | : _value(value), _context(context), _label(label) {}
16 | ~TextureViewHostObject() { wgpuTextureViewRelease(_value); }
17 | std::vector getPropertyNames(Runtime &runtime) override;
18 | Value get(Runtime &runtime, const PropNameID &name) override;
19 | inline WGPUTextureView getValue() { return _value; }
20 |
21 | private:
22 | WGPUTextureView _value;
23 | std::shared_ptr _context;
24 | std::string _label;
25 | };
26 |
27 | } // namespace wgpu
28 |
--------------------------------------------------------------------------------
/packages/react-native-webgpu/cxx/Thread.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | namespace facebook::react {
7 | class CallInvoker;
8 | }
9 |
10 | namespace wgpu {
11 |
12 | class Thread {
13 | public:
14 | explicit Thread(std::shared_ptr invoker) : _invoker(invoker) {}
15 | void run(std::function