Skip to content

Commit d50efc1

Browse files
committed
Use new NativeWindow::lock() API in dummy_render()
1 parent 32e3ddf commit d50efc1

File tree

4 files changed

+132
-56
lines changed

4 files changed

+132
-56
lines changed

agdk-cpal/src/lib.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
33
use std::sync::OnceLock;
44

5-
use android_activity::{AndroidApp, InputStatus, MainEvent, PollEvent};
5+
use android_activity::{
6+
ndk::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
7+
AndroidApp, InputStatus, MainEvent, PollEvent,
8+
};
69
use cpal::{
710
traits::{DeviceTrait, HostTrait, StreamTrait},
811
FromSample, Sample, SizedSample,
@@ -74,7 +77,7 @@ fn android_main(app: AndroidApp) {
7477

7578
let mut quit = false;
7679
let mut redraw_pending = true;
77-
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
80+
let mut native_window = None;
7881

7982
let host = cpal::default_host();
8083

@@ -139,6 +142,16 @@ fn android_main(app: AndroidApp) {
139142
}
140143
MainEvent::InitWindow { .. } => {
141144
native_window = app.native_window();
145+
if let Some(nw) = &native_window {
146+
// Set the backing buffer to a known format (without changing
147+
// the size) so that we can safely draw to it in dummy_render().
148+
nw.set_buffers_geometry(
149+
0,
150+
0,
151+
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
152+
)
153+
.unwrap()
154+
}
142155
redraw_pending = true;
143156
}
144157
MainEvent::TerminateWindow { .. } => {
@@ -192,17 +205,24 @@ fn android_main(app: AndroidApp) {
192205
/// convince Android that we're drawing something and are
193206
/// responsive, otherwise it will stop delivering input
194207
/// events to us.
195-
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 _);
208+
fn dummy_render(native_window: &NativeWindow) {
209+
let mut lock = native_window.lock(None).unwrap();
210+
let (w, h) = (lock.width(), lock.height());
211+
212+
assert_eq!(
213+
lock.format(),
214+
HardwareBufferFormat::R8G8B8A8_UNORM,
215+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
216+
);
217+
218+
for (y, line) in lock.lines().unwrap().enumerate() {
219+
let r = y * 255 / h;
220+
for (x, pixels) in line.chunks_mut(4).enumerate() {
221+
let g = x * 255 / w;
222+
pixels[0].write(r as u8);
223+
pixels[1].write(g as u8);
224+
pixels[2].write(0);
225+
pixels[3].write(255);
226+
}
207227
}
208228
}

agdk-mainloop/src/lib.rs

Lines changed: 32 additions & 14 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::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
6+
AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
67
};
78
use jni::{
89
objects::{JObject, JString},
@@ -140,7 +141,7 @@ fn android_main(app: AndroidApp) {
140141

141142
let mut quit = false;
142143
let mut redraw_pending = true;
143-
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
144+
let mut native_window = None;
144145

145146
let mut combining_accent = None;
146147

@@ -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,17 +412,24 @@ fn character_map_and_combine_key(
401412
/// convince Android that we're drawing something and are
402413
/// responsive, otherwise it will stop delivering input
403414
/// events to us.
404-
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+
fn dummy_render(native_window: &NativeWindow) {
416+
let mut lock = native_window.lock(None).unwrap();
417+
let (w, h) = (lock.width(), lock.height());
418+
419+
assert_eq!(
420+
lock.format(),
421+
HardwareBufferFormat::R8G8B8A8_UNORM,
422+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
423+
);
424+
425+
for (y, line) in lock.lines().unwrap().enumerate() {
426+
let r = y * 255 / h;
427+
for (x, pixels) in line.chunks_mut(4).enumerate() {
428+
let g = x * 255 / w;
429+
pixels[0].write(r as u8);
430+
pixels[1].write(g as u8);
431+
pixels[2].write(0);
432+
pixels[3].write(255);
433+
}
416434
}
417435
}

na-mainloop/src/lib.rs

Lines changed: 32 additions & 14 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::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
6+
AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
67
};
78
use jni::{
89
objects::{JObject, JString},
@@ -140,7 +141,7 @@ fn android_main(app: AndroidApp) {
140141

141142
let mut quit = false;
142143
let mut redraw_pending = true;
143-
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
144+
let mut native_window = None;
144145

145146
let mut combining_accent = None;
146147

@@ -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,17 +412,24 @@ fn character_map_and_combine_key(
401412
/// convince Android that we're drawing something and are
402413
/// responsive, otherwise it will stop delivering input
403414
/// events to us.
404-
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+
fn dummy_render(native_window: &NativeWindow) {
416+
let mut lock = native_window.lock(None).unwrap();
417+
let (w, h) = (lock.width(), lock.height());
418+
419+
assert_eq!(
420+
lock.format(),
421+
HardwareBufferFormat::R8G8B8A8_UNORM,
422+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
423+
);
424+
425+
for (y, line) in lock.lines().unwrap().enumerate() {
426+
let r = y * 255 / h;
427+
for (x, pixels) in line.chunks_mut(4).enumerate() {
428+
let g = x * 255 / w;
429+
pixels[0].write(r as u8);
430+
pixels[1].write(g as u8);
431+
pixels[2].write(0);
432+
pixels[3].write(255);
433+
}
416434
}
417435
}

na-subclass-jni/src/lib.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use android_activity::{AndroidApp, InputStatus, MainEvent, PollEvent};
1+
use android_activity::{
2+
ndk::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
3+
AndroidApp, InputStatus, MainEvent, PollEvent,
4+
};
25
use log::info;
36

47
#[unsafe(no_mangle)]
@@ -9,7 +12,7 @@ fn android_main(app: AndroidApp) {
912

1013
let mut quit = false;
1114
let mut redraw_pending = true;
12-
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
15+
let mut native_window = None;
1316

1417
while !quit {
1518
app.poll_events(
@@ -40,6 +43,16 @@ fn android_main(app: AndroidApp) {
4043
}
4144
MainEvent::InitWindow { .. } => {
4245
native_window = app.native_window();
46+
if let Some(nw) = &native_window {
47+
// Set the backing buffer to a known format (without changing
48+
// the size) so that we can safely draw to it in dummy_render().
49+
nw.set_buffers_geometry(
50+
0,
51+
0,
52+
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
53+
)
54+
.unwrap()
55+
}
4356
redraw_pending = true;
4457
}
4558
MainEvent::TerminateWindow { .. } => {
@@ -100,18 +113,25 @@ fn android_main(app: AndroidApp) {
100113
/// convince Android that we're drawing something and are
101114
/// responsive, otherwise it will stop delivering input
102115
/// events to us.
103-
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 _);
116+
fn dummy_render(native_window: &NativeWindow) {
117+
let mut lock = native_window.lock(None).unwrap();
118+
let (w, h) = (lock.width(), lock.height());
119+
120+
assert_eq!(
121+
lock.format(),
122+
HardwareBufferFormat::R8G8B8A8_UNORM,
123+
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
124+
);
125+
126+
for (y, line) in lock.lines().unwrap().enumerate() {
127+
let r = y * 255 / h;
128+
for (x, pixels) in line.chunks_mut(4).enumerate() {
129+
let g = x * 255 / w;
130+
pixels[0].write(r as u8);
131+
pixels[1].write(g as u8);
132+
pixels[2].write(0);
133+
pixels[3].write(255);
134+
}
115135
}
116136
}
117137

0 commit comments

Comments
 (0)