Crash on startup due to lower powered gpu (MediaTek) on android phones and buggy Vulkan drivers
# Notedeck crashes on Android devices with PowerVR GPUs
## Problem
Notedeck immediately crashes on launch on low-end Android devices with PowerVR GPUs (e.g., TCL 30 Z with MediaTek MT6761 / PowerVR Rogue GE8300).
**Device:** TCL 30 Z (T602DL), Android 12, MediaTek Helio A22 (MT6761), PowerVR Rogue GE8300 GPU
## Root Causes
There are two independent issues preventing the app from running:
### 1. Vulkan driver crash (SIGSEGV in QueueSubmit)
The app defaults to the Vulkan backend. On the PowerVR GE8300, the Vulkan driver (`vulkan.mt6761.so`) crashes with a **null pointer dereference** during `vkQueueSubmit`. The app successfully initializes, loads fonts, connects to relays, and renders its first frame — but the driver segfaults when submitting the render commands to the GPU.
F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
F DEBUG : Cause: null pointer dereference
F DEBUG : #00 pc 000000000006d1bc /vendor/lib64/hw/vulkan.mt6761.so
F DEBUG : #01 pc 000000000001c808 /system/lib64/libvulkan.so (vulkan::driver::QueueSubmit+64)
F DEBUG : #02 ... wgpu_hal..vulkan..Queue::submit
F DEBUG : #08 ... egui_wgpu::winit::Painter::paint_and_update_textures
This is a bug in the vendor's Vulkan driver — not fixable from the app side.
### 2. wgpu GL backend rejects EGL robust access (BadAttribute)
Switching to the GL backend (`Backends::GL`) fails because `wgpu-hal` unconditionally requests `EGL_CONTEXT_OPENGL_ROBUST_ACCESS` when creating the GLES context. The PowerVR driver advertises `EGL_EXT_create_context_robustness` support but **rejects the attribute** at context creation time, returning `BadAttribute`.
The relevant code in `wgpu-hal/src/gles/egl.rs`:
```rust
let needs_robustness = true; // hardcoded — no way to disable
// ...
if needs_robustness {
if version >= (1, 5) && !display_extensions.contains("EGL_ANGLE_") {
context_attributes.push(khronos_egl::CONTEXT_OPENGL_ROBUST_ACCESS); // PowerVR rejects this
```
This results in: Instance::new: failed to create Gl backend: "unable to create GLES 3.x context", source: Some(BadAttribute)
# Solution by Opus that works
## Three changes are required:
### Fix 1: Force GL backend on Android (android.rs)
```rust
options.wgpu_options.wgpu_setup =
eframe::egui_wgpu::WgpuSetup::CreateNew(eframe::egui_wgpu::WgpuSetupCreateNew {
instance_descriptor: eframe::wgpu::InstanceDescriptor {
backends: eframe::wgpu::Backends::GL,
..Default::default()
},
..Default::default()
});
```
### Fix 2: Patch wgpu-hal to skip robust access on Android (wgpu-hal/src/gles/egl.rs)
```diff
- let needs_robustness = true;
+ // Disable robust access on Android - some drivers (e.g. PowerVR GE8300)
+ // advertise EGL_EXT_create_context_robustness but reject the attribute
+ let needs_robustness = !cfg!(target_os = "android");
```
This requires a [patch.crates-io] entry for wgpu-hal in Cargo.toml, or ideally an upstream PR to wgpu.
### Fix 3: Make Vulkan optional in Android manifest (notedeck_chrome/Cargo.toml)
```diff
[[package.metadata.android.uses_feature]]
name = "android.hardware.vulkan.level"
- required = true
+ required = false
version = 1
```
# Result
With these changes, the app successfully runs using the OpenGL ES 3.2 backend:
Creating wgpu instance with backends Backends(GL)
Picked the only available wgpu adapter: backend: Gl, device_type: Other,
name: "PowerVR Rogue GE8300", driver_info: "OpenGL ES 3.2 build 1.15@6070602"
# Notes
The ideal long-term fix is to try Vulkan first, then fall back to GL if it fails. The current fix forces GL for all Android devices.
The wgpu-hal robustness issue should be reported upstream — needs_robustness being hardcoded to true is too aggressive for Android where driver support is inconsistent.
An alternative to patching wgpu-hal would be for wgpu to catch the BadAttribute error and retry context creation without robust access.
---
## Diff 1: `crates/notedeck_chrome/src/android.rs`
```diff
@@ -50,6 +50,17 @@
};
options.renderer = eframe::Renderer::Wgpu;
+
+ // Force GL backend on Android to avoid Vulkan driver crashes on
+ // low-end GPUs (e.g. PowerVR GE8300 null deref in QueueSubmit)
+ options.wgpu_options.wgpu_setup =
+ eframe::egui_wgpu::WgpuSetup::CreateNew(eframe::egui_wgpu::WgpuSetupCreateNew {
+ instance_descriptor: eframe::wgpu::InstanceDescriptor {
+ backends: eframe::wgpu::Backends::GL,
+ ..Default::default()
+ },
+ ..Default::default()
+ });
// Clone `app` to use it both in the closure and later in the function
```
## Diff 2: crates/notedeck_chrome/Cargo.toml
```diff
[[package.metadata.android.uses_feature]]
name = "android.hardware.vulkan.level"
-required = true
+required = false
version = 1
```
## Diff 3: Cargo.toml
```diff
[patch.crates-io]
+wgpu-hal = { path = "wgpu-hal-patched" }
egui = { git = "https://github.com/damus-io/egui", rev = "82f91cb..." }
```
## Diff 4: wgpu-hal-patched/src/gles/egl.rs (vendored copy of wgpu-hal 24.0.4)
```diff
- let needs_robustness = true;
+ // Disable robust access on Android - some drivers (e.g. PowerVR GE8300)
+ // advertise EGL_EXT_create_context_robustness but reject the attribute
+ let needs_robustness = !cfg!(target_os = "android");
```
3 条评论