Skip to content

Commit 655a0ab

Browse files
committed
Use new NativeWindow::lock() API in dummy_render()
1 parent 7b42ef8 commit 655a0ab

File tree

4 files changed

+120
-49
lines changed

4 files changed

+120
-49
lines changed

agdk-cpal/src/lib.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
///! Based on https://github.com/RustAudio/cpal/blob/master/examples/android.rs
2-
use android_activity::{AndroidApp, InputStatus, MainEvent, PollEvent};
32
use std::sync::OnceLock;
4-
use tracing::{error, info};
53

4+
use android_activity::{ndk, AndroidApp, InputStatus, MainEvent, PollEvent};
65
use cpal::{
76
traits::{DeviceTrait, HostTrait, StreamTrait},
87
SizedSample,
98
};
109
use cpal::{FromSample, Sample};
10+
use ndk::hardware_buffer_format::HardwareBufferFormat;
11+
use tracing::{error, info};
1112

1213
fn write_data<T>(output: &mut [T], channels: usize, next_sample: &mut dyn FnMut() -> f32)
1314
where
@@ -139,6 +140,16 @@ fn android_main(app: AndroidApp) {
139140
}
140141
MainEvent::InitWindow { .. } => {
141142
native_window = app.native_window();
143+
if let Some(nw) = &native_window {
144+
// Set the backing buffer to a known format (without changing
145+
// the size) so that we can safely draw to it in dummy_render().
146+
nw.set_buffers_geometry(
147+
0,
148+
0,
149+
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
150+
)
151+
.unwrap()
152+
}
142153
redraw_pending = true;
143154
}
144155
MainEvent::TerminateWindow { .. } => {
@@ -193,16 +204,23 @@ fn android_main(app: AndroidApp) {
193204
/// responsive, otherwise it will stop delivering input
194205
/// events to us.
195206
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
196-
unsafe {
197-
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
198-
let mut rect: ndk_sys::ARect = std::mem::zeroed();
199-
ndk_sys::ANativeWindow_lock(
200-
native_window.ptr().as_ptr() as _,
201-
&mut buf as _,
202-
&mut rect as _,
203-
);
204-
// Note: we don't try and touch the buffer since that
205-
// also requires us to handle various buffer formats
206-
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
207+
let mut lock = native_window.lock(None).unwrap();
208+
let (w, h) = (lock.width(), lock.height());
209+
210+
assert_eq!(
211+
lock.format(),
212+
HardwareBufferFormat::R8G8B8A8_UNORM,
213+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
214+
);
215+
216+
for (y, line) in lock.lines().unwrap().enumerate() {
217+
let r = y * 255 / h;
218+
for (x, pixels) in line.chunks_mut(4).enumerate() {
219+
let g = x * 255 / w;
220+
pixels[0].write(r as u8);
221+
pixels[1].write(g as u8);
222+
pixels[2].write(0);
223+
pixels[3].write(255);
224+
}
207225
}
208226
}

agdk-mainloop/src/lib.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ 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, AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
66
};
77
use jni::{
88
objects::{JObject, JString},
99
refs::Global,
1010
vm::JavaVM,
1111
};
12+
use ndk::hardware_buffer_format::HardwareBufferFormat;
1213
use tracing::{error, info};
1314

1415
jni::bind_java_type! { Context => "android.content.Context" }
@@ -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);
431+
pixels[3].write(255);
432+
}
415433
}
416434
}

na-mainloop/src/lib.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
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, AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
76
};
87
use jni::{
98
objects::{JObject, JString},
109
refs::Global,
1110
vm::JavaVM,
1211
};
12+
use ndk::hardware_buffer_format::HardwareBufferFormat;
1313
use tracing::{error, info};
1414

1515
jni::bind_java_type! { Context => "android.content.Context" }
@@ -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);
431+
pixels[3].write(255);
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);
131+
pixels[3].write(255);
132+
}
115133
}
116134
}
117135

0 commit comments

Comments
 (0)