Skip to content

Commit c726c77

Browse files
MarijnS95rib
authored andcommitted
Use new NativeWindow::lock() API in dummy_render()
1 parent 7b42ef8 commit c726c77

File tree

3 files changed

+89
-36
lines changed

3 files changed

+89
-36
lines changed

agdk-mainloop/src/lib.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use std::sync::OnceLock;
22

33
use android_activity::{
44
input::{InputEvent, KeyAction, KeyEvent, KeyMapChar, MotionAction},
5-
ndk, ndk_sys, AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
5+
ndk::{self, hardware_buffer_format::HardwareBufferFormat},
6+
AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
67
};
78
use jni::{
89
objects::{JObject, JString},
@@ -176,6 +177,16 @@ fn android_main(app: AndroidApp) {
176177
}
177178
MainEvent::InitWindow { .. } => {
178179
native_window = app.native_window();
180+
if let Some(nw) = &native_window {
181+
// Set the backing buffer to a known format (without changing
182+
// the size) so that we can safely draw to it in dummy_render().
183+
nw.set_buffers_geometry(
184+
0,
185+
0,
186+
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
187+
)
188+
.unwrap()
189+
}
179190
redraw_pending = true;
180191
}
181192
MainEvent::TerminateWindow { .. } => {
@@ -401,16 +412,23 @@ fn character_map_and_combine_key(
401412
/// responsive, otherwise it will stop delivering input
402413
/// events to us.
403414
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
404-
unsafe {
405-
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
406-
let mut rect: ndk_sys::ARect = std::mem::zeroed();
407-
ndk_sys::ANativeWindow_lock(
408-
native_window.ptr().as_ptr() as _,
409-
&mut buf as _,
410-
&mut rect as _,
411-
);
412-
// Note: we don't try and touch the buffer since that
413-
// also requires us to handle various buffer formats
414-
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
415+
let mut lock = native_window.lock(None).unwrap();
416+
let (w, h) = (lock.width(), lock.height());
417+
418+
assert_eq!(
419+
lock.format(),
420+
HardwareBufferFormat::R8G8B8A8_UNORM,
421+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
422+
);
423+
424+
for (y, line) in lock.lines().unwrap().enumerate() {
425+
let r = y * 255 / h;
426+
for (x, pixels) in line.chunks_mut(4).enumerate() {
427+
let g = x * 255 / w;
428+
pixels[0].write(r as u8);
429+
pixels[1].write(g as u8);
430+
pixels[2].write(0 as u8);
431+
pixels[3].write(255 as u8);
432+
}
415433
}
416434
}

na-mainloop/src/lib.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use std::sync::OnceLock;
22

33
use android_activity::{
4-
AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
54
input::{InputEvent, KeyAction, KeyEvent, KeyMapChar, MotionAction},
6-
ndk, ndk_sys,
5+
ndk::{self, hardware_buffer_format::HardwareBufferFormat},
6+
AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
77
};
88
use jni::{
99
objects::{JObject, JString},
@@ -177,6 +177,16 @@ fn android_main(app: AndroidApp) {
177177
}
178178
MainEvent::InitWindow { .. } => {
179179
native_window = app.native_window();
180+
if let Some(nw) = &native_window {
181+
// Set the backing buffer to a known format (without changing
182+
// the size) so that we can safely draw to it in dummy_render().
183+
nw.set_buffers_geometry(
184+
0,
185+
0,
186+
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
187+
)
188+
.unwrap()
189+
}
180190
redraw_pending = true;
181191
}
182192
MainEvent::TerminateWindow { .. } => {
@@ -402,16 +412,23 @@ fn character_map_and_combine_key(
402412
/// responsive, otherwise it will stop delivering input
403413
/// events to us.
404414
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
405-
unsafe {
406-
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
407-
let mut rect: ndk_sys::ARect = std::mem::zeroed();
408-
ndk_sys::ANativeWindow_lock(
409-
native_window.ptr().as_ptr() as _,
410-
&mut buf as _,
411-
&mut rect as _,
412-
);
413-
// Note: we don't try and touch the buffer since that
414-
// also requires us to handle various buffer formats
415-
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
415+
let mut lock = native_window.lock(None).unwrap();
416+
let (w, h) = (lock.width(), lock.height());
417+
418+
assert_eq!(
419+
lock.format(),
420+
HardwareBufferFormat::R8G8B8A8_UNORM,
421+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
422+
);
423+
424+
for (y, line) in lock.lines().unwrap().enumerate() {
425+
let r = y * 255 / h;
426+
for (x, pixels) in line.chunks_mut(4).enumerate() {
427+
let g = x * 255 / w;
428+
pixels[0].write(r as u8);
429+
pixels[1].write(g as u8);
430+
pixels[2].write(0 as u8);
431+
pixels[3].write(255 as u8);
432+
}
416433
}
417434
}

na-subclass-jni/src/lib.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use android_activity::{AndroidApp, InputStatus, MainEvent, PollEvent};
22
use log::info;
3+
use ndk::hardware_buffer_format::HardwareBufferFormat;
34

45
#[unsafe(no_mangle)]
56
fn android_main(app: AndroidApp) {
@@ -40,6 +41,16 @@ fn android_main(app: AndroidApp) {
4041
}
4142
MainEvent::InitWindow { .. } => {
4243
native_window = app.native_window();
44+
if let Some(nw) = &native_window {
45+
// Set the backing buffer to a known format (without changing
46+
// the size) so that we can safely draw to it in dummy_render().
47+
nw.set_buffers_geometry(
48+
0,
49+
0,
50+
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
51+
)
52+
.unwrap()
53+
}
4354
redraw_pending = true;
4455
}
4556
MainEvent::TerminateWindow { .. } => {
@@ -101,17 +112,24 @@ fn android_main(app: AndroidApp) {
101112
/// responsive, otherwise it will stop delivering input
102113
/// events to us.
103114
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
104-
unsafe {
105-
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
106-
let mut rect: ndk_sys::ARect = std::mem::zeroed();
107-
ndk_sys::ANativeWindow_lock(
108-
native_window.ptr().as_ptr() as _,
109-
&mut buf as _,
110-
&mut rect as _,
111-
);
112-
// Note: we don't try and touch the buffer since that
113-
// also requires us to handle various buffer formats
114-
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
115+
let mut lock = native_window.lock(None).unwrap();
116+
let (w, h) = (lock.width(), lock.height());
117+
118+
assert_eq!(
119+
lock.format(),
120+
HardwareBufferFormat::R8G8B8A8_UNORM,
121+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
122+
);
123+
124+
for (y, line) in lock.lines().unwrap().enumerate() {
125+
let r = y * 255 / h;
126+
for (x, pixels) in line.chunks_mut(4).enumerate() {
127+
let g = x * 255 / w;
128+
pixels[0].write(r as u8);
129+
pixels[1].write(g as u8);
130+
pixels[2].write(0 as u8);
131+
pixels[3].write(255 as u8);
132+
}
115133
}
116134
}
117135

0 commit comments

Comments
 (0)