Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/docs/content/docs/getting-started/canvas.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ context.present(); // React Native only

`present()` is a React Native only method (it is not part of the Web WebGPU spec). It runs **synchronously** on the calling thread, so the frame is presented from whichever thread did the rendering. This works the same on every runtime: the main JS runtime, the UI thread, and dedicated worklet runtimes. Always call it after `submit()`, never before.

Your loop sets the frame rate.
A loop on the Reanimated UI runtime or on a worklet runtime (see [Worklets](/docs/integrations/worklets)) runs at the display's rate, 120 Hz on a ProMotion iPhone or iPad, while React Native's `requestAnimationFrame` on the JS thread runs at 60 Hz on iOS.
An app created from an Expo or React Native template before React Native 0.82 may still carry iOS's 60 Hz cap for iPhone: [Reanimated's performance guide](https://docs.swmansion.com/react-native-reanimated/docs/guides/performance/#-enable-120-fps) covers the `Info.plist` opt-in.

## Pixel density

Just like on the Web, a canvas has two independent sizes:
Expand Down
1 change: 1 addition & 0 deletions apps/docs/content/docs/integrations/worklets.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description: Run WebGPU rendering off the JS thread on worklet runtimes.

By default, WebGPU rendering runs on the JavaScript thread alongside React.
Using [React Native Worklets](https://github.com/margelo/react-native-worklets), you can run WebGPU rendering on the UI thread or on a dedicated worklet runtime.
A worklet loop also runs at the display's rate, 120 Hz on a ProMotion iPhone or iPad, where the JS thread's `requestAnimationFrame` is capped at 60 Hz (see [Frame presentations](/docs/getting-started/canvas#frame-presentations)).
There is even an experimental [Bundle Mode](https://docs.swmansion.com/react-native-worklets/docs/bundleMode/) that lets you run complex Three.js scenes on a dedicated thread.
You can see an example of Bundle Mode working with Three.js [here](https://github.com/software-mansion-labs/Bundle-Mode-showcase-app).

Expand Down
16 changes: 15 additions & 1 deletion apps/example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,24 @@ require "#{ws_dir}/node_modules/react-native-test-app/test_app.rb"

workspace 'Example.xcworkspace'

# react-native-test-app generates the app's Info.plist from its own template
# and takes no extra keys from app.json. Without this one iOS caps every
# display link at 60 Hz on iPhone, so a ProMotion iPhone would never show a
# canvas above 60 fps (see the docs, "Frame presentations").
opt_in_promotion = ->(_installer) do
plist_path = File.expand_path('../node_modules/.generated/ios/Info.plist', __dir__)
return unless File.exist?(plist_path)

info = Xcodeproj::Plist.read_from_path(plist_path)
info['CADisableMinimumFrameDurationOnPhone'] = true
Xcodeproj::Plist.write_to_path(info, plist_path)
end

options = {
:hermes_enabled => true,
:fabric_enabled => true,
:new_arch_enabled => true
:new_arch_enabled => true,
:post_install => opt_in_promotion
}

use_test_app! options
Loading