mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
Merge pull request #82 from linebender/android2
Add example Android apk
This commit is contained in:
commit
f6c2558743
62
Cargo.lock
generated
62
Cargo.lock
generated
|
@ -610,7 +610,19 @@ checksum = "5eb167c1febed0a496639034d0c76b3b74263636045db5489eee52143c246e73"
|
|||
dependencies = [
|
||||
"jni-sys",
|
||||
"ndk-sys",
|
||||
"num_enum",
|
||||
"num_enum 0.4.3",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab"
|
||||
dependencies = [
|
||||
"jni-sys",
|
||||
"ndk-sys",
|
||||
"num_enum 0.5.1",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -623,7 +635,21 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"ndk",
|
||||
"ndk 0.2.1",
|
||||
"ndk-macro",
|
||||
"ndk-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk-glue"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"ndk 0.3.0",
|
||||
"ndk-macro",
|
||||
"ndk-sys",
|
||||
]
|
||||
|
@ -687,7 +713,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"num_enum_derive",
|
||||
"num_enum_derive 0.4.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"num_enum_derive 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -702,6 +738,18 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
|
@ -773,11 +821,15 @@ name = "piet-gpu"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"ndk 0.3.0",
|
||||
"ndk-glue 0.3.0",
|
||||
"ndk-sys",
|
||||
"piet",
|
||||
"piet-gpu-hal",
|
||||
"piet-gpu-types",
|
||||
"png",
|
||||
"rand",
|
||||
"raw-window-handle",
|
||||
"roxmltree",
|
||||
"winit",
|
||||
]
|
||||
|
@ -1298,8 +1350,8 @@ dependencies = [
|
|||
"log",
|
||||
"mio",
|
||||
"mio-extras",
|
||||
"ndk",
|
||||
"ndk-glue",
|
||||
"ndk 0.2.1",
|
||||
"ndk-glue 0.2.1",
|
||||
"ndk-sys",
|
||||
"objc",
|
||||
"parking_lot",
|
||||
|
|
|
@ -14,6 +14,11 @@ path = "bin/cli.rs"
|
|||
name = "winit"
|
||||
path = "bin/winit.rs"
|
||||
|
||||
[[example]]
|
||||
name = "android"
|
||||
path = "bin/android.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies.piet-gpu-hal]
|
||||
path = "../piet-gpu-hal"
|
||||
|
||||
|
@ -27,3 +32,9 @@ rand = "0.7.3"
|
|||
roxmltree = "0.13"
|
||||
winit = "0.23"
|
||||
clap = "2.33"
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
ndk = "0.3"
|
||||
ndk-sys = "0.2.0"
|
||||
ndk-glue = "0.3"
|
||||
raw-window-handle = "0.3"
|
||||
|
|
176
piet-gpu/bin/android.rs
Normal file
176
piet-gpu/bin/android.rs
Normal file
|
@ -0,0 +1,176 @@
|
|||
//! Android example
|
||||
//!
|
||||
//! Run using `cargo apk run --example android`
|
||||
//!
|
||||
//! Requires the [cargo-apk] tool.
|
||||
//! [cargo-apk]: https://crates.io/crates/cargo-apk
|
||||
|
||||
use raw_window_handle::android::AndroidHandle;
|
||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||
|
||||
use ndk::native_window::NativeWindow;
|
||||
use ndk_glue::Event;
|
||||
|
||||
use piet_gpu_hal::hub;
|
||||
use piet_gpu_hal::vulkan::{QueryPool, VkInstance, VkSurface, VkSwapchain};
|
||||
use piet_gpu_hal::{CmdBuf, Error, ImageLayout};
|
||||
|
||||
use piet_gpu::{render_scene, PietGpuRenderContext, Renderer};
|
||||
|
||||
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
|
||||
fn main() {
|
||||
my_main().unwrap();
|
||||
}
|
||||
|
||||
struct MyHandle {
|
||||
handle: AndroidHandle,
|
||||
}
|
||||
|
||||
// State required to render and present the contents
|
||||
struct GfxState {
|
||||
session: hub::Session,
|
||||
renderer: Renderer,
|
||||
swapchain: VkSwapchain,
|
||||
current_frame: usize,
|
||||
last_frame_idx: usize,
|
||||
submitted: Option<hub::SubmittedCmdBuf>,
|
||||
query_pools: Vec<QueryPool>,
|
||||
present_semaphores: Vec<hub::Semaphore>,
|
||||
}
|
||||
|
||||
const WIDTH: usize = 1080;
|
||||
const HEIGHT: usize = 2280;
|
||||
const NUM_FRAMES: usize = 2;
|
||||
|
||||
fn my_main() -> Result<(), Error> {
|
||||
let mut gfx_state = None;
|
||||
loop {
|
||||
for event in ndk_glue::poll_events() {
|
||||
println!("got event {:?}", event);
|
||||
match event {
|
||||
Event::WindowCreated => {
|
||||
let window = ndk_glue::native_window();
|
||||
if let Some(window) = &*window {
|
||||
let handle = get_handle(window);
|
||||
let (instance, surface) = VkInstance::new(Some(&handle))?;
|
||||
gfx_state = Some(GfxState::new(&instance, surface.as_ref())?);
|
||||
} else {
|
||||
println!("native window is sadly none");
|
||||
}
|
||||
}
|
||||
Event::WindowRedrawNeeded => {
|
||||
if let Some(gfx_state) = gfx_state.as_mut() {
|
||||
for _ in 0..10 {
|
||||
gfx_state.redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_handle(window: &NativeWindow) -> MyHandle {
|
||||
println!(
|
||||
"window = {:?}, {}x{}",
|
||||
window.ptr(),
|
||||
window.width(),
|
||||
window.height()
|
||||
);
|
||||
let mut handle = AndroidHandle::empty();
|
||||
handle.a_native_window = window.ptr().as_ptr() as *mut std::ffi::c_void;
|
||||
MyHandle { handle }
|
||||
}
|
||||
|
||||
unsafe impl HasRawWindowHandle for MyHandle {
|
||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||
RawWindowHandle::Android(self.handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl GfxState {
|
||||
fn new(instance: &VkInstance, surface: Option<&VkSurface>) -> Result<GfxState, Error> {
|
||||
unsafe {
|
||||
let device = instance.device(surface)?;
|
||||
let mut swapchain =
|
||||
instance.swapchain(WIDTH / 2, HEIGHT / 2, &device, surface.unwrap())?;
|
||||
let session = hub::Session::new(device);
|
||||
let mut current_frame = 0;
|
||||
let present_semaphores = (0..NUM_FRAMES)
|
||||
.map(|_| session.create_semaphore())
|
||||
.collect::<Result<Vec<_>, Error>>()?;
|
||||
let query_pools = (0..NUM_FRAMES)
|
||||
.map(|_| session.create_query_pool(8))
|
||||
.collect::<Result<Vec<_>, Error>>()?;
|
||||
|
||||
let mut ctx = PietGpuRenderContext::new();
|
||||
render_scene(&mut ctx);
|
||||
let n_paths = ctx.path_count();
|
||||
let n_pathseg = ctx.pathseg_count();
|
||||
let n_trans = ctx.pathseg_count();
|
||||
let scene = ctx.get_scene_buf();
|
||||
|
||||
let renderer = Renderer::new(&session, scene, n_paths, n_pathseg, n_trans)?;
|
||||
|
||||
let submitted: Option<hub::SubmittedCmdBuf> = None;
|
||||
let current_frame = 0;
|
||||
let last_frame_idx = 0;
|
||||
Ok(GfxState {
|
||||
session,
|
||||
renderer,
|
||||
swapchain,
|
||||
current_frame,
|
||||
last_frame_idx,
|
||||
submitted,
|
||||
query_pools,
|
||||
present_semaphores,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn redraw(&mut self) {
|
||||
println!("redraw");
|
||||
unsafe {
|
||||
if let Some(submitted) = self.submitted.take() {
|
||||
submitted.wait().unwrap();
|
||||
|
||||
let ts = self
|
||||
.session
|
||||
.fetch_query_pool(&self.query_pools[self.last_frame_idx])
|
||||
.unwrap();
|
||||
println!("render time: {:?}", ts);
|
||||
}
|
||||
let frame_idx = self.current_frame % NUM_FRAMES;
|
||||
let (image_idx, acquisition_semaphore) = self.swapchain.next().unwrap();
|
||||
let swap_image = self.swapchain.image(image_idx);
|
||||
let query_pool = &self.query_pools[frame_idx];
|
||||
let mut cmd_buf = self.session.cmd_buf().unwrap();
|
||||
cmd_buf.begin();
|
||||
self.renderer.record(&mut cmd_buf, &query_pool);
|
||||
|
||||
// Image -> Swapchain
|
||||
cmd_buf.image_barrier(&swap_image, ImageLayout::Undefined, ImageLayout::BlitDst);
|
||||
cmd_buf.blit_image(self.renderer.image_dev.vk_image(), &swap_image);
|
||||
cmd_buf.image_barrier(&swap_image, ImageLayout::BlitDst, ImageLayout::Present);
|
||||
cmd_buf.finish();
|
||||
|
||||
self.submitted = Some(
|
||||
self.session
|
||||
.run_cmd_buf(
|
||||
cmd_buf,
|
||||
&[acquisition_semaphore],
|
||||
&[self.present_semaphores[frame_idx]],
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
self.last_frame_idx = frame_idx;
|
||||
|
||||
self.swapchain
|
||||
.present(image_idx, &[self.present_semaphores[frame_idx]])
|
||||
.unwrap();
|
||||
|
||||
self.current_frame += 1;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue