Repository navigation
fix(🤖): find Skia's Dawn instance in librnskia.so on Android - #582
Conversation
System.loadLibrary loads librnskia.so with RTLD_LOCAL, so dlsym(RTLD_DEFAULT, "rnskia_getWGPUInstance") never finds it and react-native-webgpu creates its own instance. Look the getter up in librnskia.so with RTLD_NOLOAD when the global lookup fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Confirming this on a device. I hit the same bug and patched it the same way, |
|
this is correct, wouldn't be cleaner for this to be in WebGPUModule.java,? |
|
Note Written by Claude Opus 5.5 on behalf of Enzo (@enzomanuelmangano). Thanks a lot, and thanks @camchis for confirming on a Seeker! Good question. I tested it on a Redmi Note 8 Pro (release build,
So Java is a great place for the loading order you mentioned, and it would make this deterministic, but it can't replace the lookup: If you'd like, I'm happy to add the |
Note
Written by Claude Opus 5.5 on behalf of Enzo (@enzomanuelmangano).
Fixes #581.
Problem
On Android,
importDevice(Skia.getNativeDevice())returns a device whose async work never settles (mapAsyncstays pending).createInstance()looks Skia's getter up withdlsym(RTLD_DEFAULT, "rnskia_getWGPUInstance").System.loadLibraryloadslibrnskia.sowithRTLD_LOCAL, so the global lookup does not see it, even thoughlibrnskia.soexports the symbol. react-native-webgpu then creates its own instance and never pumps Skia's device.Fix
On Android, when the global lookup fails,
createInstance()asks for the handle oflibrnskia.sowithdlopen("librnskia.so", RTLD_NOW | RTLD_NOLOAD)and looks the getter up on that handle.RTLD_NOLOADreturns the library only if it is already loaded. This never loads Skia into an app that does not use it, and it adds no build-time dependency.dlclosereleases the reference thatdlopentook. The library stays loaded, becauseSystem.loadLibraryholds it, so the function pointer stays valid..sofiles are in the app's class loader namespace, so the lookup by soname resolves.The ordering requirement does not change: as with the existing
dlsym, Skia must be loaded before the firstGPUobject is created.Alternative considered:
dl_iterate_phdrover all loaded objects. It finds the library without knowing its name, but it is more code and walks every loaded library to find one known soname.Test plan
Reproduction app: https://github.com/enzomanuelmangano/repro-lab, demo
webgpu-skia-shared-instance. Itsfix/webgpu-skia-shared-instance-androidbranch applies this change to 0.17.0 (diff). Android API 36 emulator (arm64), release build,react-native-skia3.7.2.mapAsyncon Skia's imported deviceVideo, Redmi Note 8 Pro, release build (left: 0.17.0, stays at "Running…"; right: with the fix, settles in 16 ms): https://github.com/enzomanuelmangano/repro-lab/blob/main/media/webgpu-skia-shared-instance-android.mp4
Not run: the repository's E2E suite (
yarn test) and the example app. The change only adds a fallback when the existing lookup returnsnullptr.