Skip to content

Commit

Permalink
feat: android builds working fine again
Browse files Browse the repository at this point in the history
  • Loading branch information
ElhamAryanpur committed Mar 30, 2024
1 parent c4f1918 commit d3af15a
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 47 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "blue_engine"
version = "0.5.8"
version = "0.5.9"
authors = ["Elham Aryanpur <elhamaryanpur5@gmail.com>"]
edition = "2021"
description = "General-Purpose, Easy-to-use, Fast, and Portable graphics engine"
Expand All @@ -17,6 +17,8 @@ name = "blue_engine"
default = ["debug"]
debug = ["dep:env_logger"]
android = ["dep:log", "dep:android_logger"]
android_native_activity = ["winit/android-native-activity"]
android_game_activity = ["winit/android-game-activity"]

[dependencies]
image = { version = "0.24" }
Expand Down
14 changes: 10 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# fork of Dockerfile at https://github.com/not-fl3/cargo-quad-apk
# fork of Dockerfile at https://github.com/not-fl3/cargo-quad-apk, testing for aarch64-linux-android

FROM archlinux

RUN pacman -Syu --noconfirm
RUN pacman -S --noconfirm gcc
RUN pacman -S --noconfirm jdk8-openjdk unzip wget cmake rustup openssl pkgconf
RUN pacman -S --noconfirm jdk17-openjdk unzip wget cmake rustup openssl pkgconf gradle kotlin clang llvm lld gcc

# github override HOME, so here we are
ENV RUSTUP_HOME=/usr/local/rustup \
Expand Down Expand Up @@ -54,4 +53,11 @@ RUN cargo install --git https://github.com/tauri-apps/cargo-mobile2
# Add build-tools to PATH, for apksigner
ENV PATH="/opt/android-sdk-linux/build-tools/31.0.0/:${PATH}"

WORKDIR /root/src
WORKDIR /root/src

# need to somehow agree to android licenses maybe below
# RUN yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses
#
# Then run
# RUN cargo mobile init
# RUN cargo mobile android apk build aarch64
1 change: 0 additions & 1 deletion src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ pub struct Renderer {
/// A [`wgpu::Surface`] represents a platform-specific surface (e.g. a window) onto which rendered images may be presented.
pub surface: Option<wgpu::Surface<'static>>,
/// Context for all of the gpu objects
#[cfg(feature = "android")]
pub instance: wgpu::Instance,
/// Handle to a physical graphics and/or compute device.
#[allow(unused)]
Expand Down
53 changes: 27 additions & 26 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,24 @@ impl Renderer {
backends: settings.backends,
..Default::default()
});
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
let surface = Some(unsafe {
instance.create_surface_unsafe(wgpu::SurfaceTargetUnsafe::from_window(&window)?)?
});
#[cfg(feature = "android")]
#[cfg(target_os = "android")]
let surface = None;

let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: settings.power_preference,
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
compatible_surface: Some(&surface.as_ref().unwrap()),
#[cfg(feature = "android")]
#[cfg(target_os = "android")]
compatible_surface: surface,
force_fallback_adapter: false,
})
.await
.unwrap();
.expect("Failed to find an appropriate adapter");

let (device, queue) = adapter
.request_device(
Expand All @@ -59,34 +59,34 @@ impl Renderer {
None, // Trace path
)
.await
.unwrap();
.expect("Failed to create device");

#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
let tex_format = surface.as_ref().unwrap().get_capabilities(&adapter).formats[0];

#[cfg(feature = "android")]
#[cfg(target_os = "android")]
let tex_format = wgpu::TextureFormat::Rgba8UnormSrgb;

let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: tex_format, //wgpu::TextureFormat::Bgra8UnormSrgb,
#[cfg(feature = "android")]
#[cfg(target_os = "android")]
width: 1080,
#[cfg(not(feature = "android"))]
width: size.width,
#[cfg(feature = "android")]
#[cfg(target_os = "android")]
height: 2300,
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
height: size.height,
#[cfg(feature = "android")]
#[cfg(target_os = "android")]
present_mode: wgpu::PresentMode::Mailbox,
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
present_mode: settings.present_mode,
alpha_mode: settings.alpha_mode,
view_formats: vec![tex_format],
desired_maximum_frame_latency: settings.desired_maximum_frame_latency,
};
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
surface.as_ref().unwrap().configure(&device, &config);

let texture_bind_group_layout =
Expand Down Expand Up @@ -131,12 +131,11 @@ impl Renderer {
let depth_buffer = Renderer::build_depth_buffer("Depth Buffer", &device, &config);

let mut renderer = Self {
#[cfg(feature = "android")]
instance,
adapter,
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
surface,
#[cfg(feature = "android")]
#[cfg(target_os = "android")]
surface: None,
device,
queue,
Expand Down Expand Up @@ -191,15 +190,17 @@ impl Renderer {
self.size = new_size;
self.config.width = new_size.width;
self.config.height = new_size.height;
#[cfg(not(feature = "android"))]
self.surface
.as_ref()
.unwrap()
.configure(&self.device, &self.config);
#[cfg(not(feature = "android"))]
{
self.depth_buffer =
Self::build_depth_buffer("Depth Buffer", &self.device, &self.config);
#[cfg(not(target_os = "android"))]
if self.surface.is_some() {
self.surface
.as_ref()
.expect("Couldn't get the surface for resizing")
.configure(&self.device, &self.config);

{
self.depth_buffer =
Self::build_depth_buffer("Depth Buffer", &self.device, &self.config);
}
}
}
}
Expand Down
78 changes: 63 additions & 15 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,55 @@ use winit::{
impl Engine {
/// Creates a new window in current thread using default settings.
pub fn new() -> color_eyre::Result<Self> {
Self::new_inner(WindowDescriptor::default())
Self::new_inner(
WindowDescriptor::default(),
#[cfg(target_os = "android")]
None,
)
}

/// Creates a new window in current thread using provided settings.
pub fn new_config(settings: WindowDescriptor) -> color_eyre::Result<Self> {
Self::new_inner(settings)
Self::new_inner(
settings,
#[cfg(target_os = "android")]
None,
)
}

/// Creates a new window for android
#[cfg(target_os = "android")]
pub fn new_android(
settings: WindowDescriptor,
app: winit::platform::android::activity::AndroidApp,
) -> color_eyre::Result<Self> {
Self::new_inner(settings, Some(app))
}

/// Creates a new window in current thread.
#[allow(unreachable_code)]
pub(crate) fn new_inner(settings: WindowDescriptor) -> color_eyre::Result<Self> {
pub(crate) fn new_inner(
settings: WindowDescriptor,
#[cfg(target_os = "android")] android_app: Option<
winit::platform::android::activity::AndroidApp,
>,
) -> color_eyre::Result<Self> {
#[cfg(feature = "debug")]
env_logger::init();
// Dimensions of the window, as width and height
// and then are set as a logical size that the window can accept
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
let dimension = winit::dpi::PhysicalSize {
width: settings.width, // Which sets the width of the window
height: settings.height, // And sets the height of the window
};

// Here the size is finally made according to the dimensions we set earlier
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
let size = winit::dpi::Size::Physical(dimension);

// And we will create a new window and set all the options we stored
#[cfg(not(feature = "android"))]
#[cfg(not(target_os = "android"))]
let new_window = WindowBuilder::new()
.with_inner_size(size) // sets the width and height of window
.with_title(String::from(settings.title)) // sets title of the window
Expand All @@ -54,14 +76,43 @@ impl Engine {
// will create the main event loop of the window.
// and will contain all the callbacks and button press
// also will allow graphics API
#[cfg(target_os = "android")]
let event_loop = if android_app.is_some() {
use winit::platform::android::EventLoopBuilderExtAndroid;

android_logger::init_once(
android_logger::Config::default()
.with_max_level(log::LevelFilter::Trace) // Default comes from `log::max_level`, i.e. Off
.with_filter(
android_logger::FilterBuilder::new()
.filter_level(log::LevelFilter::Debug)
.filter_module("android_activity", log::LevelFilter::Trace)
.filter_module("winit", log::LevelFilter::Trace)
.build(),
),
);

winit::event_loop::EventLoopBuilder::new()
.with_android_app(if android_app.is_some() {
android_app.unwrap()
} else {
panic!("No android app")
})
.build()?
} else {
EventLoop::new()?
};

#[cfg(not(target_os = "android"))]
let event_loop = EventLoop::new()?;

event_loop.set_control_flow(settings.control_flow);

// bind the loop to window
#[cfg(not(feature = "android"))]
let window = new_window.build(&event_loop)?;
#[cfg(feature = "android")]
let window = Window::new(&event_loop).unwrap();
let window = Window::new(&event_loop)?;

// The renderer init on current window
let mut renderer = futures::executor::block_on(Renderer::new(&window, settings))?;
Expand Down Expand Up @@ -137,6 +188,7 @@ impl Engine {
window_target.exit();
std::process::exit(0);
}

WindowEvent::Resized(size) => {
renderer.resize(*size);
camera
Expand All @@ -146,12 +198,14 @@ impl Engine {
.update_view_projection(&mut renderer)
.expect("Couldn't set the resize to camera in renderer");
}

WindowEvent::RedrawRequested => {
let pre_render = renderer
.pre_render(&objects, window.inner_size(), &camera)
.expect("Couldn't get pre render data");
if pre_render.is_some() {
let (mut encoder, view, frame) = pre_render.unwrap();
let (mut encoder, view, frame) =
pre_render.expect("Couldn't get pre render data");

update_function(
&mut renderer,
Expand Down Expand Up @@ -202,7 +256,6 @@ impl Engine {
_ => {}
},

#[cfg(feature = "android")]
Event::Resumed => {
let surface = unsafe {
renderer
Expand All @@ -222,17 +275,12 @@ impl Engine {
);
renderer.surface = Some(surface);
}
#[cfg(feature = "android")]

Event::Suspended => {
renderer.surface = None;
}

Event::DeviceEvent { event, .. } => _device_event = event,

Event::NewEvents(_new_events) => {
// updates the data on what events happened before the frame start
}

_ => (),
}
})?;
Expand Down

0 comments on commit d3af15a

Please sign in to comment.