Skip to content

Commit

Permalink
Return SyncFence'd HardwareBuffer to Java
Browse files Browse the repository at this point in the history
  • Loading branch information
MarijnS95 committed Oct 25, 2023
1 parent 6eae641 commit 56f7986
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 3 deletions.
4 changes: 2 additions & 2 deletions android_native_surface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ android_logger = "0.13"
glutin = { version = "0.31", default-features = false, features = ["egl"] }
jni = "0.21"
log = "0.4"
ndk = { version = "0.8", default-features = false, features = ["api-level-28", "rwh_05"] }
ndk = { version = "0.8", default-features = false, features = ["api-level-28", "media", "sync", "rwh_05"] }
raw-window-handle = "0.5"
rustix = { version = "0.38", default-features = false, features = ["std", "pipe", "stdio"] }
rustix = { version = "0.38", default-features = false, features = ["std", "event", "pipe", "stdio"] }

[build-dependencies]
gl_generator = "0.14"
64 changes: 63 additions & 1 deletion android_native_surface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::{
fs::File,
io::{self, BufRead, BufReader},
os::fd::{AsFd, FromRawFd, RawFd},
thread,
time::Instant,
};

use glutin::{
Expand All @@ -13,8 +15,15 @@ use jni::{
JNIEnv,
};
use log::{debug, info, LevelFilter};
use ndk::{native_window::NativeWindow, surface_texture::SurfaceTexture};
use ndk::{
hardware_buffer::HardwareBufferUsage,
media::image_reader::{ImageFormat, ImageReader},
native_window::NativeWindow,
surface_texture::SurfaceTexture,
sync::SyncFileInfo,
};
use raw_window_handle::{AndroidDisplayHandle, HasRawWindowHandle, RawDisplayHandle};
use rustix::event::{PollFd, PollFlags};

mod support;

Expand Down Expand Up @@ -148,3 +157,56 @@ pub extern "system" fn Java_rust_androidnativesurface_MainActivity_00024Companio

render_to_native_window(window)
}

#[no_mangle]
pub extern "system" fn Java_rust_androidnativesurface_MainActivity_00024Companion_renderHardwareBuffer(
mut env: JNIEnv,
_class: JClass,
) {
debug!("SurfaceControl hack");

let cls = env
.find_class("rust/androidnativesurface/RenderedHardwareBuffer")
.unwrap();
dbg!(cls);
let image_reader = ImageReader::new(100, 100, ImageFormat::RGBA_8888, 10).expect("ImageReader");
let window = image_reader.window().expect("NativeWindow");
dbg!(&image_reader, &window);

debug!(
"Acquire before {:?}",
image_reader.acquire_latest_image_async()
);

render_to_native_window(window);

let (image, fd) = image_reader.acquire_latest_image_async().unwrap();
dbg!(&image, &fd);

if let Some(fd) = &fd {
let sync_file_info = SyncFileInfo::new(fd.as_fd()).expect("SyncFileInfo");
dbg!(&sync_file_info);
}

let hwbuf = image.hardware_buffer().unwrap();
dbg!(&hwbuf);
dbg!(hwbuf.describe());

if let Some(fd) = &fd {
let x = Instant::now();
let mut pfd = PollFd::new(fd, PollFlags::all());
rustix::event::poll(std::slice::from_mut(&mut pfd), -1).unwrap();
debug!("Polling on fd took {:.3?}: {pfd:?}", x.elapsed());
}
let x = Instant::now();
// let map = hwbuf.lock(HardwareBufferUsage::CPU_READ_OFTEN, None, None);
let map = hwbuf.lock(HardwareBufferUsage::CPU_READ_OFTEN, fd, None);
debug!("Locking with fd took {:.3?}", x.elapsed());
debug!("map {:?}", map);
debug!("unlock async {:?}", hwbuf.unlock_async());

// let obj = env.alloc_object(cls).unwrap();
// dbg!(obj);
// env.new_object(cls, ctor_sig, ctor_args)
// hwbuf.to_jni(env)
}
32 changes: 32 additions & 0 deletions app/src/main/java/rust/androidnativesurface/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@ package rust.androidnativesurface

import android.app.Activity
import android.graphics.SurfaceTexture
import android.hardware.HardwareBuffer
import android.hardware.SyncFence
import android.os.Bundle
import android.os.ParcelFileDescriptor
import android.view.Surface
import android.view.SurfaceControl
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.TextureView
import java.io.FileDescriptor

data class RenderedHardwareBuffer(
val hardware_buffer: HardwareBuffer,
val fd: Int
)


class MainActivity : Activity() {
companion object {
Expand All @@ -18,6 +29,8 @@ class MainActivity : Activity() {
private external fun init()
external fun renderToSurface(surface: Surface)
external fun renderToSurfaceTexture(surfaceTexture: SurfaceTexture)

external fun renderHardwareBuffer() // : RenderedHardwareBuffer
}

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -26,9 +39,28 @@ class MainActivity : Activity() {

val surfaceView: SurfaceView = findViewById(R.id.surface_view)
println("SurfaceView: ${surfaceView.holder.surface}")


renderHardwareBuffer()
//
// val hwbuf = renderHardwareBuffer()
// println("Have HardwareBuffer ${hwbuf.hardware_buffer}, wait for fd ${hwbuf.fd}")
// val t = SurfaceControl.Transaction()
//
// // TODO: This is @hide :(
// val f = SyncFence.create(ParcelFileDescriptor.adoptFd(hwbuf.fd))
// println("Fence $f")
// t.setBuffer(
// surfaceView.surfaceControl,
// hwbuf.hardware_buffer,
// f
// )
return

surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
println("SurfaceView created: ${holder.surface}")
// holder.surface.attachAndQueueBufferWithColorSpace()
renderToSurface(holder.surface)
}

Expand Down

0 comments on commit 56f7986

Please sign in to comment.