Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions agdk-cpal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

use std::sync::OnceLock;

use android_activity::{AndroidApp, InputStatus, MainEvent, PollEvent};
use android_activity::{
ndk::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
AndroidApp, InputStatus, MainEvent, PollEvent,
};
use cpal::{
traits::{DeviceTrait, HostTrait, StreamTrait},
FromSample, Sample, SizedSample,
Expand Down Expand Up @@ -74,7 +77,7 @@ fn android_main(app: AndroidApp) {

let mut quit = false;
let mut redraw_pending = true;
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
let mut native_window = None;

let host = cpal::default_host();

Expand Down Expand Up @@ -139,6 +142,16 @@ fn android_main(app: AndroidApp) {
}
MainEvent::InitWindow { .. } => {
native_window = app.native_window();
if let Some(nw) = &native_window {
// Set the backing buffer to a known format (without changing
// the size) so that we can safely draw to it in dummy_render().
nw.set_buffers_geometry(
0,
0,
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
)
.unwrap()
}
redraw_pending = true;
}
MainEvent::TerminateWindow { .. } => {
Expand Down Expand Up @@ -192,17 +205,24 @@ fn android_main(app: AndroidApp) {
/// convince Android that we're drawing something and are
/// responsive, otherwise it will stop delivering input
/// events to us.
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
unsafe {
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
let mut rect: ndk_sys::ARect = std::mem::zeroed();
ndk_sys::ANativeWindow_lock(
native_window.ptr().as_ptr() as _,
&mut buf as _,
&mut rect as _,
);
// Note: we don't try and touch the buffer since that
// also requires us to handle various buffer formats
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
fn dummy_render(native_window: &NativeWindow) {
let mut lock = native_window.lock(None).unwrap();
let (w, h) = (lock.width(), lock.height());

assert_eq!(
lock.format(),
HardwareBufferFormat::R8G8B8A8_UNORM,
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
);

for (y, line) in lock.lines().unwrap().enumerate() {
let r = y * 255 / h;
for (x, pixels) in line.chunks_mut(4).enumerate() {
let g = x * 255 / w;
pixels[0].write(r as u8);
pixels[1].write(g as u8);
pixels[2].write(0);
pixels[3].write(255);
}
}
}
46 changes: 32 additions & 14 deletions agdk-mainloop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::sync::OnceLock;

use android_activity::{
input::{InputEvent, KeyAction, KeyEvent, KeyMapChar, MotionAction},
ndk, ndk_sys, AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
ndk::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
};
use jni::{
objects::{JObject, JString},
Expand Down Expand Up @@ -140,7 +141,7 @@ fn android_main(app: AndroidApp) {

let mut quit = false;
let mut redraw_pending = true;
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
let mut native_window = None;

let mut combining_accent = None;

Expand Down Expand Up @@ -176,6 +177,16 @@ fn android_main(app: AndroidApp) {
}
MainEvent::InitWindow { .. } => {
native_window = app.native_window();
if let Some(nw) = &native_window {
// Set the backing buffer to a known format (without changing
// the size) so that we can safely draw to it in dummy_render().
nw.set_buffers_geometry(
0,
0,
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
)
.unwrap()
}
redraw_pending = true;
}
MainEvent::TerminateWindow { .. } => {
Expand Down Expand Up @@ -401,17 +412,24 @@ fn character_map_and_combine_key(
/// convince Android that we're drawing something and are
/// responsive, otherwise it will stop delivering input
/// events to us.
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
unsafe {
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
let mut rect: ndk_sys::ARect = std::mem::zeroed();
ndk_sys::ANativeWindow_lock(
native_window.ptr().as_ptr() as _,
&mut buf as _,
&mut rect as _,
);
// Note: we don't try and touch the buffer since that
// also requires us to handle various buffer formats
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
fn dummy_render(native_window: &NativeWindow) {
let mut lock = native_window.lock(None).unwrap();
let (w, h) = (lock.width(), lock.height());

assert_eq!(
lock.format(),
HardwareBufferFormat::R8G8B8A8_UNORM,
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
);

for (y, line) in lock.lines().unwrap().enumerate() {
let r = y * 255 / h;
for (x, pixels) in line.chunks_mut(4).enumerate() {
let g = x * 255 / w;
pixels[0].write(r as u8);
pixels[1].write(g as u8);
pixels[2].write(0);
pixels[3].write(255);
}
}
}
46 changes: 32 additions & 14 deletions na-mainloop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::sync::OnceLock;

use android_activity::{
input::{InputEvent, KeyAction, KeyEvent, KeyMapChar, MotionAction},
ndk, ndk_sys, AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
ndk::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
AndroidApp, InputStatus, MainEvent, OnCreateState, PollEvent,
};
use jni::{
objects::{JObject, JString},
Expand Down Expand Up @@ -140,7 +141,7 @@ fn android_main(app: AndroidApp) {

let mut quit = false;
let mut redraw_pending = true;
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
let mut native_window = None;

let mut combining_accent = None;

Expand Down Expand Up @@ -176,6 +177,16 @@ fn android_main(app: AndroidApp) {
}
MainEvent::InitWindow { .. } => {
native_window = app.native_window();
if let Some(nw) = &native_window {
// Set the backing buffer to a known format (without changing
// the size) so that we can safely draw to it in dummy_render().
nw.set_buffers_geometry(
0,
0,
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
)
.unwrap()
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be good to have a comment explaining what this is for.

This is intended to be a bare-bones example of how to use android-activity so it's quite likely someone looking at this isn't going to be familiar with what set_buffers_geometry does (and the name from the NDK isn't very self documenting when we're using it to set the format and not the 'geometry' as such).

Maybe we can just note that, since this example is going to clear the window from the CPU then we want to ensure the buffer is in a known format that we will be able to write to from dummy_render()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, still a draft as I wanted to share progress and show what's possible with the new bindings.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I'd be happy to have a convenient way to at least show something other than a black screen, but without needing to pull in a full-blown graphics API.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool cool, this already shows a gradient instead of a black screen, as a sign of life.

We can probably drop the draft status now, IIRC this is mostly ready.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah don't mind if it's taken out of draft and will just want to wait until it doesn't depend on [patches] before landing.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, expect that to take ±1month though. That should be enough time to see if there are any issues with this patch though, pretty helpful to test compatibility with the ecosystem meanwhile.

redraw_pending = true;
}
MainEvent::TerminateWindow { .. } => {
Expand Down Expand Up @@ -401,17 +412,24 @@ fn character_map_and_combine_key(
/// convince Android that we're drawing something and are
/// responsive, otherwise it will stop delivering input
/// events to us.
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
unsafe {
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
let mut rect: ndk_sys::ARect = std::mem::zeroed();
ndk_sys::ANativeWindow_lock(
native_window.ptr().as_ptr() as _,
&mut buf as _,
&mut rect as _,
);
// Note: we don't try and touch the buffer since that
// also requires us to handle various buffer formats
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
fn dummy_render(native_window: &NativeWindow) {
let mut lock = native_window.lock(None).unwrap();
let (w, h) = (lock.width(), lock.height());

assert_eq!(
lock.format(),
HardwareBufferFormat::R8G8B8A8_UNORM,
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
);

for (y, line) in lock.lines().unwrap().enumerate() {
let r = y * 255 / h;
for (x, pixels) in line.chunks_mut(4).enumerate() {
let g = x * 255 / w;
pixels[0].write(r as u8);
pixels[1].write(g as u8);
pixels[2].write(0);
pixels[3].write(255);
}
}
}
48 changes: 34 additions & 14 deletions na-subclass-jni/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use android_activity::{AndroidApp, InputStatus, MainEvent, PollEvent};
use android_activity::{
ndk::{hardware_buffer_format::HardwareBufferFormat, native_window::NativeWindow},
AndroidApp, InputStatus, MainEvent, PollEvent,
};
use log::info;

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

let mut quit = false;
let mut redraw_pending = true;
let mut native_window: Option<ndk::native_window::NativeWindow> = None;
let mut native_window = None;

while !quit {
app.poll_events(
Expand Down Expand Up @@ -40,6 +43,16 @@ fn android_main(app: AndroidApp) {
}
MainEvent::InitWindow { .. } => {
native_window = app.native_window();
if let Some(nw) = &native_window {
// Set the backing buffer to a known format (without changing
// the size) so that we can safely draw to it in dummy_render().
nw.set_buffers_geometry(
0,
0,
Some(HardwareBufferFormat::R8G8B8A8_UNORM),
)
.unwrap()
}
redraw_pending = true;
}
MainEvent::TerminateWindow { .. } => {
Expand Down Expand Up @@ -100,18 +113,25 @@ fn android_main(app: AndroidApp) {
/// convince Android that we're drawing something and are
/// responsive, otherwise it will stop delivering input
/// events to us.
fn dummy_render(native_window: &ndk::native_window::NativeWindow) {
unsafe {
let mut buf: ndk_sys::ANativeWindow_Buffer = std::mem::zeroed();
let mut rect: ndk_sys::ARect = std::mem::zeroed();
ndk_sys::ANativeWindow_lock(
native_window.ptr().as_ptr() as _,
&mut buf as _,
&mut rect as _,
);
// Note: we don't try and touch the buffer since that
// also requires us to handle various buffer formats
ndk_sys::ANativeWindow_unlockAndPost(native_window.ptr().as_ptr() as _);
fn dummy_render(native_window: &NativeWindow) {
let mut lock = native_window.lock(None).unwrap();
let (w, h) = (lock.width(), lock.height());

assert_eq!(
lock.format(),
HardwareBufferFormat::R8G8B8A8_UNORM,
"Expected the buffer format to be R8G8B8A8_UNORM since we set that in `InitWindow` handling"
);

for (y, line) in lock.lines().unwrap().enumerate() {
let r = y * 255 / h;
for (x, pixels) in line.chunks_mut(4).enumerate() {
let g = x * 255 / w;
pixels[0].write(r as u8);
pixels[1].write(g as u8);
pixels[2].write(0);
pixels[3].write(255);
}
}
}

Expand Down
Loading