Skip to content

Commit 872e722

Browse files
committed
*-mainloop: add dummy render to unblock input
Newer versions of Android will stop delivering input to applications that don't appear to be responsive because they aren't rendering anything. This updates na-mainloop and agdk-mainloop so that they at least do a NOOP post of an untouched framebuffer each frame, so that they continue to be delivered touch input.
1 parent 41e72ca commit 872e722

File tree

2 files changed

+46
-8
lines changed

2 files changed

+46
-8
lines changed

agdk-mainloop/src/lib.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn android_main(app: AndroidApp) {
77

88
let mut quit = false;
99
let mut redraw_pending = true;
10-
let mut render_state: Option<()> = Default::default();
10+
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
1111

1212
while !quit {
1313
app.poll_events(
@@ -37,11 +37,11 @@ fn android_main(app: AndroidApp) {
3737
}
3838
}
3939
MainEvent::InitWindow { .. } => {
40-
render_state = Some(());
40+
native_window = app.native_window();
4141
redraw_pending = true;
4242
}
4343
MainEvent::TerminateWindow { .. } => {
44-
render_state = None;
44+
native_window = None;
4545
}
4646
MainEvent::WindowResized { .. } => {
4747
redraw_pending = true;
@@ -65,7 +65,7 @@ fn android_main(app: AndroidApp) {
6565
}
6666

6767
if redraw_pending {
68-
if let Some(_rs) = render_state {
68+
if let Some(native_window) = &native_window {
6969
redraw_pending = false;
7070

7171
// Handle input
@@ -75,9 +75,28 @@ fn android_main(app: AndroidApp) {
7575
});
7676

7777
info!("Render...");
78+
dummy_render(native_window);
7879
}
7980
}
8081
},
8182
);
8283
}
8384
}
85+
86+
/// Post a NOP frame to the window
87+
///
88+
/// Since this is a bare minimum test app we don't depend
89+
/// on any GPU graphics APIs but we do need to at least
90+
/// convince Android that we're drawing something and are
91+
/// responsive, otherwise it will stop delivering input
92+
/// events to us.
93+
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
94+
unsafe {
95+
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
96+
let mut rect: ndk_sys::ARect = std::mem::zeroed();
97+
ndk_sys::ANativeWindow_lock(native_window.ptr().as_ptr() as _, &mut buf as _, &mut rect as _);
98+
// Note: we don't try and touch the buffer since that
99+
// also requires us to handle various buffer formats
100+
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
101+
}
102+
}

na-mainloop/src/lib.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn android_main(app: AndroidApp) {
77

88
let mut quit = false;
99
let mut redraw_pending = true;
10-
let mut render_state: Option<()> = Default::default();
10+
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
1111

1212
while !quit {
1313
app.poll_events(
@@ -37,11 +37,11 @@ fn android_main(app: AndroidApp) {
3737
}
3838
}
3939
MainEvent::InitWindow { .. } => {
40-
render_state = Some(());
40+
native_window = app.native_window();
4141
redraw_pending = true;
4242
}
4343
MainEvent::TerminateWindow { .. } => {
44-
render_state = None;
44+
native_window = None;
4545
}
4646
MainEvent::WindowResized { .. } => {
4747
redraw_pending = true;
@@ -65,7 +65,7 @@ fn android_main(app: AndroidApp) {
6565
}
6666

6767
if redraw_pending {
68-
if let Some(_rs) = render_state {
68+
if let Some(native_window) = &native_window {
6969
redraw_pending = false;
7070

7171
// Handle input
@@ -75,9 +75,28 @@ fn android_main(app: AndroidApp) {
7575
});
7676

7777
info!("Render...");
78+
dummy_render(native_window);
7879
}
7980
}
8081
},
8182
);
8283
}
8384
}
85+
86+
/// Post a NOP frame to the window
87+
///
88+
/// Since this is a bare minimum test app we don't depend
89+
/// on any GPU graphics APIs but we do need to at least
90+
/// convince Android that we're drawing something and are
91+
/// responsive, otherwise it will stop delivering input
92+
/// events to us.
93+
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
94+
unsafe {
95+
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
96+
let mut rect: ndk_sys::ARect = std::mem::zeroed();
97+
ndk_sys::ANativeWindow_lock(native_window.ptr().as_ptr() as _, &mut buf as _, &mut rect as _);
98+
// Note: we don't try and touch the buffer since that
99+
// also requires us to handle various buffer formats
100+
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
101+
}
102+
}

0 commit comments

Comments
 (0)