From 66e3ed7a6435914a88dc651cdacc7ed09e12adf0 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 23 Apr 2022 00:39:50 +0000 Subject: [PATCH 01/35] adds surface_texture support --- ndk/src/lib.rs | 2 +- ndk/src/surface_texture.rs | 72 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 ndk/src/surface_texture.rs diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index 79fb23e0..ef6561ea 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -23,7 +23,7 @@ pub mod input_queue; pub mod looper; pub mod native_activity; pub mod native_window; - +pub mod surface_texture; pub mod aaudio; pub mod hardware_buffer; pub mod media; diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs new file mode 100644 index 00000000..9466e346 --- /dev/null +++ b/ndk/src/surface_texture.rs @@ -0,0 +1,72 @@ +//! Bindings for [`ffi::ASurfaceTexture`] +use crate::native_window::NativeWindow; +use jni_sys::jobject; +use jni_sys::JNIEnv; +use std::ptr::NonNull; + +#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct SurfaceTexture { + ptr: NonNull, +} + +unsafe impl Send for SurfaceTexture {} +unsafe impl Sync for SurfaceTexture {} + +impl Drop for SurfaceTexture { + fn drop(&mut self) { + unsafe { ffi::ASurfaceTexture_release(self.ptr.as_ptr()) } + } +} + +impl SurfaceTexture { + /// Assumes ownership of `ptr` + /// + /// # Safety + /// `ptr` must be a valid pointer to an Android [`ffi::ASurfaceTexture`]. + pub unsafe fn from_ptr(ptr: NonNull) -> Self { + Self { ptr } + } + + pub fn ptr(&self) -> NonNull { + self.ptr + } + + pub fn acquire_native_window(&mut self) -> Option { + let native_window = unsafe { ffi::ASurfaceTexture_acquireANativeWindow(self.ptr.as_ptr()) }; + let n = NonNull::new(native_window)?; + Some(unsafe { NativeWindow::from_ptr(n) }) + } + + pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), i32> { + let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; + if r == 0 { + Ok(()) + } else { + Err(r) + } + } + + pub fn detach_from_gl_context(&self) -> Result<(), i32> { + let r = unsafe { ffi::ASurfaceTexture_detachFromGLContext(self.ptr.as_ptr()) }; + if r == 0 { + Ok(()) + } else { + Err(r) + } + } + + pub fn get_transform_matrix(&self, matrix: &mut [f32; 16]) { + unsafe { ffi::ASurfaceTexture_getTransformMatrix(self.ptr.as_ptr(), matrix.as_mut_ptr()) }; + } + + pub fn get_timestamp(&self) -> i64 { + unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } + } + + pub fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { + let a_surface_texture_ptr = + unsafe { ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture) }; + let s = NonNull::new(a_surface_texture_ptr)?; + Some(unsafe { SurfaceTexture::from_ptr(s) }) + } +} From d39cb7e38389b67a4ba7e217445885c8ba86ceed Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 23 Apr 2022 00:45:04 +0000 Subject: [PATCH 02/35] changes --- ndk/src/lib.rs | 6 +++--- ndk/src/surface_texture.rs | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index ef6561ea..a727bb6c 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -15,16 +15,16 @@ )] #![warn(missing_debug_implementations, trivial_casts)] +pub mod aaudio; pub mod asset; pub mod bitmap; pub mod configuration; pub mod event; +pub mod hardware_buffer; pub mod input_queue; pub mod looper; +pub mod media; pub mod native_activity; pub mod native_window; pub mod surface_texture; -pub mod aaudio; -pub mod hardware_buffer; -pub mod media; pub mod trace; diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 9466e346..7352bbae 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -55,11 +55,13 @@ impl SurfaceTexture { } } - pub fn get_transform_matrix(&self, matrix: &mut [f32; 16]) { - unsafe { ffi::ASurfaceTexture_getTransformMatrix(self.ptr.as_ptr(), matrix.as_mut_ptr()) }; + pub fn get_transform_matrix(&self) -> [f32; 16] { + let mut r = [0f32; 16]; + unsafe { ffi::ASurfaceTexture_getTransformMatrix(self.ptr.as_ptr(), r.as_mut_ptr()) }; + r } - pub fn get_timestamp(&self) -> i64 { + pub fn timestamp(&self) -> i64 { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } From 1c6a64793c3a8bb2dda6721a861beb13bf92e2ea Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 23 Apr 2022 00:47:38 +0000 Subject: [PATCH 03/35] update_tex_image --- ndk/src/surface_texture.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 7352bbae..fd6e921c 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -65,6 +65,15 @@ impl SurfaceTexture { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } + pub fn update_tex_image(&self) -> Result<(), i32> { + let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; + if r == 0 { + Ok(()) + } else { + Err(r) + } + } + pub fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { let a_surface_texture_ptr = unsafe { ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture) }; From 49a6b2750daae92532f9efcc733ccbb059ccb090 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 23 Apr 2022 00:59:04 +0000 Subject: [PATCH 04/35] clippy --- ndk/src/surface_texture.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index fd6e921c..bfe91486 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -74,10 +74,9 @@ impl SurfaceTexture { } } - pub fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { - let a_surface_texture_ptr = - unsafe { ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture) }; + pub unsafe fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { + let a_surface_texture_ptr = ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture); let s = NonNull::new(a_surface_texture_ptr)?; - Some(unsafe { SurfaceTexture::from_ptr(s) }) + Some(SurfaceTexture::from_ptr(s)) } } From 83878d3b6fd7c8762eec2c805f013378ffb9492c Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 23 Apr 2022 01:03:49 +0000 Subject: [PATCH 05/35] clippy fixed --- ndk/src/surface_texture.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index bfe91486..3ab95640 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -74,6 +74,10 @@ impl SurfaceTexture { } } + /// # Safety + /// + /// This function should be called by a healthy JVM pointer and with a non null surface texture, + /// which must be kept alive on the java/kotlin side. pub unsafe fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { let a_surface_texture_ptr = ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture); let s = NonNull::new(a_surface_texture_ptr)?; From 0431a32618b6aff1c3e5e3410efd61b64e5d3d9b Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 23 Apr 2022 01:15:48 +0000 Subject: [PATCH 06/35] no sync --- ndk/src/surface_texture.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 3ab95640..485766c5 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -10,7 +10,6 @@ pub struct SurfaceTexture { } unsafe impl Send for SurfaceTexture {} -unsafe impl Sync for SurfaceTexture {} impl Drop for SurfaceTexture { fn drop(&mut self) { From cef7247e9fb55036f0cbdee69db90abb6a3bf956 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 18 May 2022 19:58:15 -0300 Subject: [PATCH 07/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 485766c5..d2b5e26e 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -75,8 +75,8 @@ impl SurfaceTexture { /// # Safety /// - /// This function should be called by a healthy JVM pointer and with a non null surface texture, - /// which must be kept alive on the java/kotlin side. + /// This function should be called with a healthy JVM pointer and with a non-null surface texture, + /// which must be kept alive on the Java/Kotlin side. pub unsafe fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { let a_surface_texture_ptr = ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture); let s = NonNull::new(a_surface_texture_ptr)?; From 84a4a833017037d866da0665637f9b64abda5238 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 18 May 2022 23:07:19 +0000 Subject: [PATCH 08/35] fix media --- ndk/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index ecf67dc8..9956ed87 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -29,5 +29,4 @@ pub mod native_window; pub mod surface_texture; pub mod audio; pub mod hardware_buffer; -pub mod media; pub mod trace; From ff2d807758e42e2fbcd429bf05a4be8fb75c2945 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 18 May 2022 23:11:27 +0000 Subject: [PATCH 09/35] posix --- ndk/src/surface_texture.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index d2b5e26e..610e3a15 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -11,6 +11,8 @@ pub struct SurfaceTexture { unsafe impl Send for SurfaceTexture {} +struct PosixError(pub i32); + impl Drop for SurfaceTexture { fn drop(&mut self) { unsafe { ffi::ASurfaceTexture_release(self.ptr.as_ptr()) } @@ -36,12 +38,12 @@ impl SurfaceTexture { Some(unsafe { NativeWindow::from_ptr(n) }) } - pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), i32> { + pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; if r == 0 { Ok(()) } else { - Err(r) + Err(PosixError(r)) } } From 0f7f56ab79311bedcdf388774134fe34a711c4ba Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 18 May 2022 23:15:31 +0000 Subject: [PATCH 10/35] fixes --- ndk/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index 9956ed87..a5d00a02 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -15,12 +15,10 @@ )] #![warn(missing_debug_implementations, trivial_casts)] -pub mod aaudio; pub mod asset; pub mod bitmap; pub mod configuration; pub mod event; -pub mod hardware_buffer; pub mod input_queue; pub mod looper; pub mod media; From 57d61ae94cb616b15ee151ba0396980dc50b6f89 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 18 May 2022 23:18:29 +0000 Subject: [PATCH 11/35] pub --- ndk/src/surface_texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 610e3a15..4f0f5055 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -11,7 +11,7 @@ pub struct SurfaceTexture { unsafe impl Send for SurfaceTexture {} -struct PosixError(pub i32); +pub struct PosixError(pub i32); impl Drop for SurfaceTexture { fn drop(&mut self) { From 830b68227521c26aa135047e3cf1e991acf3c480 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 18 May 2022 23:22:31 +0000 Subject: [PATCH 12/35] debug --- ndk/src/surface_texture.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 4f0f5055..79b9fe15 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -11,6 +11,7 @@ pub struct SurfaceTexture { unsafe impl Send for SurfaceTexture {} +#[derive(Debug)] pub struct PosixError(pub i32); impl Drop for SurfaceTexture { From 82a76268de76fa77410ff3b8432cce3c1368f295 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sun, 22 May 2022 02:02:55 +0000 Subject: [PATCH 13/35] surface texture enhancements --- ndk/src/surface_texture.rs | 46 +++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 79b9fe15..5e2e43c4 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -3,6 +3,7 @@ use crate::native_window::NativeWindow; use jni_sys::jobject; use jni_sys::JNIEnv; use std::ptr::NonNull; +use thiserror::Error; #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct SurfaceTexture { @@ -11,9 +12,15 @@ pub struct SurfaceTexture { unsafe impl Send for SurfaceTexture {} -#[derive(Debug)] +#[derive(Debug, Error)] pub struct PosixError(pub i32); +impl std::fmt::Display for PosixError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Posix Error: {}", self.0) + } +} + impl Drop for SurfaceTexture { fn drop(&mut self) { unsafe { ffi::ASurfaceTexture_release(self.ptr.as_ptr()) } @@ -29,16 +36,31 @@ impl SurfaceTexture { Self { ptr } } + /// # Safety + /// + /// This function should be called with a healthy JVM pointer and with a non-null surface texture, + /// which must be kept alive on the Java/Kotlin side. + pub unsafe fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { + let a_surface_texture_ptr = ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture); + let s = NonNull::new(a_surface_texture_ptr)?; + Some(SurfaceTexture::from_ptr(s)) + } + + /// Returns native internal pointer pub fn ptr(&self) -> NonNull { self.ptr } + /// Returns a reference to an ANativeWindow (i.e. the Producer) + /// for this SurfaceTexture. This is equivalent to Java's: + /// Surface sur = new Surface(surfaceTexture); pub fn acquire_native_window(&mut self) -> Option { let native_window = unsafe { ffi::ASurfaceTexture_acquireANativeWindow(self.ptr.as_ptr()) }; let n = NonNull::new(native_window)?; Some(unsafe { NativeWindow::from_ptr(n) }) } + /// Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; if r == 0 { @@ -48,41 +70,35 @@ impl SurfaceTexture { } } - pub fn detach_from_gl_context(&self) -> Result<(), i32> { + /// Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object. + pub fn detach_from_gl_context(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_detachFromGLContext(self.ptr.as_ptr()) }; if r == 0 { Ok(()) } else { - Err(r) + Err(PosixError(r)) } } + /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to updateTexImage. pub fn get_transform_matrix(&self) -> [f32; 16] { let mut r = [0f32; 16]; unsafe { ffi::ASurfaceTexture_getTransformMatrix(self.ptr.as_ptr(), r.as_mut_ptr()) }; r } + /// Retrieve the timestamp associated with the texture image set by the most recent call to updateTexImage. pub fn timestamp(&self) -> i64 { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } - pub fn update_tex_image(&self) -> Result<(), i32> { + /// Update the texture image to the most recent frame from the image stream. + pub fn update_tex_image(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; if r == 0 { Ok(()) } else { - Err(r) + Err(PosixError(r)) } } - - /// # Safety - /// - /// This function should be called with a healthy JVM pointer and with a non-null surface texture, - /// which must be kept alive on the Java/Kotlin side. - pub unsafe fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { - let a_surface_texture_ptr = ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture); - let s = NonNull::new(a_surface_texture_ptr)?; - Some(SurfaceTexture::from_ptr(s)) - } } From cce23e766d60da4755b3b6986329809fcea5743d Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sun, 22 May 2022 02:03:30 +0000 Subject: [PATCH 14/35] merge import --- ndk/src/surface_texture.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 5e2e43c4..02323052 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,7 +1,6 @@ //! Bindings for [`ffi::ASurfaceTexture`] use crate::native_window::NativeWindow; -use jni_sys::jobject; -use jni_sys::JNIEnv; +use jni_sys::{jobject, JNIEnv}; use std::ptr::NonNull; use thiserror::Error; From 8c12f722f163b46e6b22e42a6e14b197f12c6798 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sun, 22 May 2022 02:08:08 +0000 Subject: [PATCH 15/35] fmt --- ndk/src/lib.rs | 4 ++-- ndk/src/surface_texture.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index a5d00a02..026a7f81 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -16,15 +16,15 @@ #![warn(missing_debug_implementations, trivial_casts)] pub mod asset; +pub mod audio; pub mod bitmap; pub mod configuration; pub mod event; +pub mod hardware_buffer; pub mod input_queue; pub mod looper; pub mod media; pub mod native_activity; pub mod native_window; pub mod surface_texture; -pub mod audio; -pub mod hardware_buffer; pub mod trace; diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 02323052..a55908d5 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -86,12 +86,12 @@ impl SurfaceTexture { r } - /// Retrieve the timestamp associated with the texture image set by the most recent call to updateTexImage. + /// Retrieve the timestamp associated with the texture image set by the most recent call to updateTexImage. pub fn timestamp(&self) -> i64 { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } - /// Update the texture image to the most recent frame from the image stream. + /// Update the texture image to the most recent frame from the image stream. pub fn update_tex_image(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; if r == 0 { From 438c8fddde9f19d790730c5bae48190c5ded7b5d Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sun, 22 May 2022 02:16:28 +0000 Subject: [PATCH 16/35] api guards --- ndk/src/surface_texture.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index a55908d5..31abeaa0 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -35,6 +35,7 @@ impl SurfaceTexture { Self { ptr } } + #[cfg(feature = "api-level-28")] /// # Safety /// /// This function should be called with a healthy JVM pointer and with a non-null surface texture, @@ -50,6 +51,7 @@ impl SurfaceTexture { self.ptr } + #[cfg(feature = "api-level-28")] /// Returns a reference to an ANativeWindow (i.e. the Producer) /// for this SurfaceTexture. This is equivalent to Java's: /// Surface sur = new Surface(surfaceTexture); @@ -59,6 +61,7 @@ impl SurfaceTexture { Some(unsafe { NativeWindow::from_ptr(n) }) } + #[cfg(feature = "api-level-28")] /// Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; @@ -69,6 +72,7 @@ impl SurfaceTexture { } } + #[cfg(feature = "api-level-28")] /// Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object. pub fn detach_from_gl_context(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_detachFromGLContext(self.ptr.as_ptr()) }; @@ -79,6 +83,7 @@ impl SurfaceTexture { } } + #[cfg(feature = "api-level-28")] /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to updateTexImage. pub fn get_transform_matrix(&self) -> [f32; 16] { let mut r = [0f32; 16]; @@ -86,11 +91,13 @@ impl SurfaceTexture { r } + #[cfg(feature = "api-level-28")] /// Retrieve the timestamp associated with the texture image set by the most recent call to updateTexImage. pub fn timestamp(&self) -> i64 { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } + #[cfg(feature = "api-level-28")] /// Update the texture image to the most recent frame from the image stream. pub fn update_tex_image(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; From 05ebfd034e563bc493ee518fa71d5f9fd0519906 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sun, 22 May 2022 02:27:26 +0000 Subject: [PATCH 17/35] unused import fix --- ndk/src/surface_texture.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 31abeaa0..ca0c71f1 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,5 +1,7 @@ //! Bindings for [`ffi::ASurfaceTexture`] +#[cfg(feature = "api-level-28")] use crate::native_window::NativeWindow; +#[cfg(feature = "api-level-28")] use jni_sys::{jobject, JNIEnv}; use std::ptr::NonNull; use thiserror::Error; From 32151c2c41756a90b1d6745cb988b1d30950dc6f Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 25 May 2022 17:41:52 -0300 Subject: [PATCH 18/35] texture --- ndk/src/lib.rs | 1 + ndk/src/surface_texture.rs | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index 026a7f81..2bd1ac8f 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -26,5 +26,6 @@ pub mod looper; pub mod media; pub mod native_activity; pub mod native_window; +#[cfg(feature = "api-level-28")] pub mod surface_texture; pub mod trace; diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index ca0c71f1..a55908d5 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,7 +1,5 @@ //! Bindings for [`ffi::ASurfaceTexture`] -#[cfg(feature = "api-level-28")] use crate::native_window::NativeWindow; -#[cfg(feature = "api-level-28")] use jni_sys::{jobject, JNIEnv}; use std::ptr::NonNull; use thiserror::Error; @@ -37,7 +35,6 @@ impl SurfaceTexture { Self { ptr } } - #[cfg(feature = "api-level-28")] /// # Safety /// /// This function should be called with a healthy JVM pointer and with a non-null surface texture, @@ -53,7 +50,6 @@ impl SurfaceTexture { self.ptr } - #[cfg(feature = "api-level-28")] /// Returns a reference to an ANativeWindow (i.e. the Producer) /// for this SurfaceTexture. This is equivalent to Java's: /// Surface sur = new Surface(surfaceTexture); @@ -63,7 +59,6 @@ impl SurfaceTexture { Some(unsafe { NativeWindow::from_ptr(n) }) } - #[cfg(feature = "api-level-28")] /// Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; @@ -74,7 +69,6 @@ impl SurfaceTexture { } } - #[cfg(feature = "api-level-28")] /// Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object. pub fn detach_from_gl_context(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_detachFromGLContext(self.ptr.as_ptr()) }; @@ -85,7 +79,6 @@ impl SurfaceTexture { } } - #[cfg(feature = "api-level-28")] /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to updateTexImage. pub fn get_transform_matrix(&self) -> [f32; 16] { let mut r = [0f32; 16]; @@ -93,13 +86,11 @@ impl SurfaceTexture { r } - #[cfg(feature = "api-level-28")] /// Retrieve the timestamp associated with the texture image set by the most recent call to updateTexImage. pub fn timestamp(&self) -> i64 { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } - #[cfg(feature = "api-level-28")] /// Update the texture image to the most recent frame from the image stream. pub fn update_tex_image(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; From cb36cbe63575c074fb951702a2690c18563da7bf Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Wed, 25 May 2022 17:48:22 -0300 Subject: [PATCH 19/35] fix --- ndk/src/lib.rs | 1 - ndk/src/surface_texture.rs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index 2bd1ac8f..026a7f81 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -26,6 +26,5 @@ pub mod looper; pub mod media; pub mod native_activity; pub mod native_window; -#[cfg(feature = "api-level-28")] pub mod surface_texture; pub mod trace; diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index a55908d5..7381d3ea 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "api-level-28")] //! Bindings for [`ffi::ASurfaceTexture`] use crate::native_window::NativeWindow; use jni_sys::{jobject, JNIEnv}; From 1e6fd421e93549edff4b43f5602a7c9930eeef1e Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 21:40:53 -0300 Subject: [PATCH 20/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 7381d3ea..603d5052 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -51,9 +51,12 @@ impl SurfaceTexture { self.ptr } - /// Returns a reference to an ANativeWindow (i.e. the Producer) - /// for this SurfaceTexture. This is equivalent to Java's: + /// Returns a reference to a [`NativeWindow`] (i.e. the Producer) for this [`SurfaceTexture`]. + /// + /// This is equivalent to Java's: + /// ```java /// Surface sur = new Surface(surfaceTexture); + /// ``` pub fn acquire_native_window(&mut self) -> Option { let native_window = unsafe { ffi::ASurfaceTexture_acquireANativeWindow(self.ptr.as_ptr()) }; let n = NonNull::new(native_window)?; From 8bd28a6b3c5dd887c8dc567115862258444c40ad Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 21:41:03 -0300 Subject: [PATCH 21/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 603d5052..f007db36 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -73,7 +73,7 @@ impl SurfaceTexture { } } - /// Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object. + /// Detach the [`SurfaceTexture`] from the OpenGL ES context that owns the OpenGL ES texture object. pub fn detach_from_gl_context(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_detachFromGLContext(self.ptr.as_ptr()) }; if r == 0 { From 8beef629966aadeaa805aaedd4c1aa6685ea348f Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 21:41:10 -0300 Subject: [PATCH 22/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index f007db36..5e1aa8d1 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -90,7 +90,7 @@ impl SurfaceTexture { r } - /// Retrieve the timestamp associated with the texture image set by the most recent call to updateTexImage. + /// Retrieve the timestamp associated with the texture image set by the most recent call to [`update_tex_image()`][Self::update_tex_image()]. pub fn timestamp(&self) -> i64 { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } From 02d816553cef4e8807b46e4b55555fedfbbaa01e Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 21:41:41 -0300 Subject: [PATCH 23/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 5e1aa8d1..dff8ec85 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -83,7 +83,7 @@ impl SurfaceTexture { } } - /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to updateTexImage. + /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to [`update_tex_image()`][Self::update_tex_image()]. pub fn get_transform_matrix(&self) -> [f32; 16] { let mut r = [0f32; 16]; unsafe { ffi::ASurfaceTexture_getTransformMatrix(self.ptr.as_ptr(), r.as_mut_ptr()) }; From 29443246e09b484358a8e91391d97aebdef1d12d Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 21:41:52 -0300 Subject: [PATCH 24/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index dff8ec85..de3e5a94 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -63,7 +63,7 @@ impl SurfaceTexture { Some(unsafe { NativeWindow::from_ptr(n) }) } - /// Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. + /// Attach the [`SurfaceTexture`] to the OpenGL ES context that is current on the calling thread. pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; if r == 0 { From 421ac3f663d9fdc6b678d8b1594ce233a86efa04 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 21:42:12 -0300 Subject: [PATCH 25/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index de3e5a94..f879f938 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -46,7 +46,7 @@ impl SurfaceTexture { Some(SurfaceTexture::from_ptr(s)) } - /// Returns native internal pointer + /// Returns a pointer to the native [`ASurfaceTexture`](ffi::ASurfaceTexture). pub fn ptr(&self) -> NonNull { self.ptr } From 4742ff5d574a6d6b48f86ecde6b184dabc803c77 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 21:50:31 -0300 Subject: [PATCH 26/35] mods --- ndk/src/surface_texture.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index f879f938..c7a463b1 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -84,7 +84,7 @@ impl SurfaceTexture { } /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to [`update_tex_image()`][Self::update_tex_image()]. - pub fn get_transform_matrix(&self) -> [f32; 16] { + pub fn transform_matrix(&self) -> [f32; 16] { let mut r = [0f32; 16]; unsafe { ffi::ASurfaceTexture_getTransformMatrix(self.ptr.as_ptr(), r.as_mut_ptr()) }; r From 39a5a59b85a517eeadf7af9395783ca14656b239 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Thu, 26 May 2022 22:01:08 -0300 Subject: [PATCH 27/35] adds --- ndk/src/lib.rs | 1 + ndk/src/posix.rs | 10 ++++++++++ ndk/src/surface_texture.rs | 11 +---------- 3 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 ndk/src/posix.rs diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index 026a7f81..a3994374 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -28,3 +28,4 @@ pub mod native_activity; pub mod native_window; pub mod surface_texture; pub mod trace; +pub mod posix; \ No newline at end of file diff --git a/ndk/src/posix.rs b/ndk/src/posix.rs new file mode 100644 index 00000000..60c7d4b6 --- /dev/null +++ b/ndk/src/posix.rs @@ -0,0 +1,10 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub struct PosixError(pub i32); + +impl std::fmt::Display for PosixError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Posix Error: {}", self.0) + } +} \ No newline at end of file diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index c7a463b1..f56ea96c 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -3,7 +3,7 @@ use crate::native_window::NativeWindow; use jni_sys::{jobject, JNIEnv}; use std::ptr::NonNull; -use thiserror::Error; +use super::posix::PosixError; #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct SurfaceTexture { @@ -12,15 +12,6 @@ pub struct SurfaceTexture { unsafe impl Send for SurfaceTexture {} -#[derive(Debug, Error)] -pub struct PosixError(pub i32); - -impl std::fmt::Display for PosixError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "Posix Error: {}", self.0) - } -} - impl Drop for SurfaceTexture { fn drop(&mut self) { unsafe { ffi::ASurfaceTexture_release(self.ptr.as_ptr()) } From 52e21411d8b987d1941ea32209ee5fe8dc7af076 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 28 May 2022 04:02:10 -0300 Subject: [PATCH 28/35] format --- ndk/src/lib.rs | 2 +- ndk/src/posix.rs | 2 +- ndk/src/surface_texture.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index a3994374..6fadec8c 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -26,6 +26,6 @@ pub mod looper; pub mod media; pub mod native_activity; pub mod native_window; +pub mod posix; pub mod surface_texture; pub mod trace; -pub mod posix; \ No newline at end of file diff --git a/ndk/src/posix.rs b/ndk/src/posix.rs index 60c7d4b6..c0f81817 100644 --- a/ndk/src/posix.rs +++ b/ndk/src/posix.rs @@ -7,4 +7,4 @@ impl std::fmt::Display for PosixError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "Posix Error: {}", self.0) } -} \ No newline at end of file +} diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index f56ea96c..9e82644b 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,9 +1,9 @@ #![cfg(feature = "api-level-28")] //! Bindings for [`ffi::ASurfaceTexture`] +use super::posix::PosixError; use crate::native_window::NativeWindow; use jni_sys::{jobject, JNIEnv}; use std::ptr::NonNull; -use super::posix::PosixError; #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct SurfaceTexture { From cac2eadfd81366f116883727ccd673c9b3e687fc Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Sat, 28 May 2022 10:30:06 +0200 Subject: [PATCH 29/35] Apply suggestions from code review --- ndk/src/surface_texture.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 9e82644b..55a2436f 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,5 +1,6 @@ -#![cfg(feature = "api-level-28")] //! Bindings for [`ffi::ASurfaceTexture`] +#![cfg(feature = "api-level-28")] + use super::posix::PosixError; use crate::native_window::NativeWindow; use jni_sys::{jobject, JNIEnv}; From 88ba5e0cc363342e726aefae5ff1e8e627adc97c Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 28 May 2022 15:57:54 -0300 Subject: [PATCH 30/35] Update ndk/src/surface_texture.rs Co-authored-by: Marijn Suijten --- ndk/src/surface_texture.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 55a2436f..62a66f9e 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -88,6 +88,8 @@ impl SurfaceTexture { } /// Update the texture image to the most recent frame from the image stream. + /// + /// This may only be called while the OpenGL ES context that owns the texture is current on the calling thread. It will implicitly bind its texture to the `GL_TEXTURE_EXTERNAL_OES` texture target. pub fn update_tex_image(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; if r == 0 { From ec5700f58384080dcb9ee6c14f68980c7e7ad229 Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 28 May 2022 16:05:49 -0300 Subject: [PATCH 31/35] better docs --- ndk/src/surface_texture.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 62a66f9e..dffb94dc 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -32,6 +32,11 @@ impl SurfaceTexture { /// /// This function should be called with a healthy JVM pointer and with a non-null surface texture, /// which must be kept alive on the Java/Kotlin side. + /// Get a reference to the native ASurfaceTexture from the corresponding java object. + // + /// The caller must keep a reference to the Java `SurfaceTexture` during the lifetime of the returned [`SurfaceTexture`]. + /// Failing to do so could result in the [`SurfaceTexture`] to stop functioning properly once the Java object gets finalized. + /// However, this will not result in program termination. pub unsafe fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { let a_surface_texture_ptr = ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture); let s = NonNull::new(a_surface_texture_ptr)?; @@ -56,6 +61,11 @@ impl SurfaceTexture { } /// Attach the [`SurfaceTexture`] to the OpenGL ES context that is current on the calling thread. + /// A new OpenGL ES texture object is created and populated with the SurfaceTexture image frame + /// that was current at the time of the last call to ASurfaceTexture_detachFromGLContext. + /// This new texture is bound to the [`GL_TEXTURE_EXTERNAL_OES`] texture target. + /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES contexts. + /// Note, however, that the image contents are only accessible from one OpenGL ES context at a time. pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; if r == 0 { @@ -66,6 +76,12 @@ impl SurfaceTexture { } /// Detach the [`SurfaceTexture`] from the OpenGL ES context that owns the OpenGL ES texture object. + /// This call must be made with the OpenGL ES context current on the calling thread. The OpenGL + /// ES texture object will be deleted as a result of this call. After calling this method all + /// calls to [`update_tex_image()`][Self::update_tex_image()] will fail until a successful call to + /// [`attach_gl_context()`][Self::attach_gl_context()] is made. + /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES contexts. + /// Note, however, that the image contents are only accessible from one OpenGL ES context at a time. pub fn detach_from_gl_context(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_detachFromGLContext(self.ptr.as_ptr()) }; if r == 0 { @@ -82,14 +98,23 @@ impl SurfaceTexture { r } - /// Retrieve the timestamp associated with the texture image set by the most recent call to [`update_tex_image()`][Self::update_tex_image()]. + /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to updateTexImage. + /// This transform matrix maps 2D homogeneous texture coordinates of the form (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture coordinate + /// that should be used to sample that location from the texture. Sampling the texture outside of the range of this transform is undefined. + /// The matrix is stored in column-major order so that it may be passed directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv functions. + /// This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp should be unaffected by time-of-day adjustments, and for + /// a camera should be strictly monotonic but for a MediaPlayer may be reset when the position is set. The specific meaning and zero point of the timestamp depends + /// on the source providing images to the SurfaceTexture. Unless otherwise specified by the image source, timestamps cannot generally be compared across SurfaceTexture + /// instances, or across multiple program invocations. It is mostly useful for determining time offsets between subsequent frames + /// For EGL/Vulkan producers, this timestamp is the desired present time set with the EGL_ANDROID_presentation_time or VK_GOOGLE_display_timing extensions pub fn timestamp(&self) -> i64 { unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } } /// Update the texture image to the most recent frame from the image stream. - /// - /// This may only be called while the OpenGL ES context that owns the texture is current on the calling thread. It will implicitly bind its texture to the `GL_TEXTURE_EXTERNAL_OES` texture target. + /// This may only be called while the OpenGL ES context that owns the texture is + /// current on the calling thread. It will implicitly bind its texture to the + /// `GL_TEXTURE_EXTERNAL_OES` texture target. pub fn update_tex_image(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; if r == 0 { From 4dd07624a1c658373b7ea7b1b9a46ae72a9f79ff Mon Sep 17 00:00:00 2001 From: Lattice 0 Date: Sat, 28 May 2022 16:22:21 -0300 Subject: [PATCH 32/35] docs --- ndk/src/surface_texture.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index dffb94dc..51c0df41 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -63,7 +63,7 @@ impl SurfaceTexture { /// Attach the [`SurfaceTexture`] to the OpenGL ES context that is current on the calling thread. /// A new OpenGL ES texture object is created and populated with the SurfaceTexture image frame /// that was current at the time of the last call to ASurfaceTexture_detachFromGLContext. - /// This new texture is bound to the [`GL_TEXTURE_EXTERNAL_OES`] texture target. + /// This new texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target. /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES contexts. /// Note, however, that the image contents are only accessible from one OpenGL ES context at a time. pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { @@ -79,7 +79,7 @@ impl SurfaceTexture { /// This call must be made with the OpenGL ES context current on the calling thread. The OpenGL /// ES texture object will be deleted as a result of this call. After calling this method all /// calls to [`update_tex_image()`][Self::update_tex_image()] will fail until a successful call to - /// [`attach_gl_context()`][Self::attach_gl_context()] is made. + /// [`attach_to_gl_context()`][Self::attach_to_gl_context()] is made. /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES contexts. /// Note, however, that the image contents are only accessible from one OpenGL ES context at a time. pub fn detach_from_gl_context(&self) -> Result<(), PosixError> { From d8d2bce01699e3a044c743551de608bd20f6fe68 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 9 Jun 2022 00:13:49 +0200 Subject: [PATCH 33/35] Doc cleanup --- ndk/src/surface_texture.rs | 112 +++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 35 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 51c0df41..649e80de 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,11 +1,15 @@ //! Bindings for [`ffi::ASurfaceTexture`] +//! +//! See for an architectural overview of +//! [`SurfaceTexture`] internals. #![cfg(feature = "api-level-28")] use super::posix::PosixError; use crate::native_window::NativeWindow; use jni_sys::{jobject, JNIEnv}; -use std::ptr::NonNull; +use std::{convert::TryInto, ptr::NonNull, time::Duration}; +/// #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct SurfaceTexture { ptr: NonNull, @@ -28,22 +32,26 @@ impl SurfaceTexture { Self { ptr } } + /// Get a reference to the native [`SurfaceTexture`] from the corresponding java object. + /// /// # Safety /// - /// This function should be called with a healthy JVM pointer and with a non-null surface texture, - /// which must be kept alive on the Java/Kotlin side. - /// Get a reference to the native ASurfaceTexture from the corresponding java object. - // - /// The caller must keep a reference to the Java `SurfaceTexture` during the lifetime of the returned [`SurfaceTexture`]. - /// Failing to do so could result in the [`SurfaceTexture`] to stop functioning properly once the Java object gets finalized. + /// This function should be called with a healthy JVM pointer and with a non-null + /// [`android.graphics.SurfaceTexture`], which must be kept alive on the Java/Kotlin side. + /// + /// The caller must keep a reference to the Java [`android.graphics.SurfaceTexture`] during the + /// lifetime of the returned [`SurfaceTexture`]. Failing to do so could result in the + /// [`SurfaceTexture`] to stop functioning properly once the Java object gets finalized. /// However, this will not result in program termination. + /// + /// [`android.graphics.SurfaceTexture`]: https://developer.android.com/reference/android/graphics/SurfaceTexture pub unsafe fn from_surface_texture(env: *mut JNIEnv, surface_texture: jobject) -> Option { let a_surface_texture_ptr = ffi::ASurfaceTexture_fromSurfaceTexture(env, surface_texture); let s = NonNull::new(a_surface_texture_ptr)?; Some(SurfaceTexture::from_ptr(s)) } - /// Returns a pointer to the native [`ASurfaceTexture`](ffi::ASurfaceTexture). + /// Returns a pointer to the native [`ffi::ASurfaceTexture`]. pub fn ptr(&self) -> NonNull { self.ptr } @@ -54,18 +62,23 @@ impl SurfaceTexture { /// ```java /// Surface sur = new Surface(surfaceTexture); /// ``` - pub fn acquire_native_window(&mut self) -> Option { + pub fn acquire_native_window(&self) -> Option { let native_window = unsafe { ffi::ASurfaceTexture_acquireANativeWindow(self.ptr.as_ptr()) }; let n = NonNull::new(native_window)?; Some(unsafe { NativeWindow::from_ptr(n) }) } - /// Attach the [`SurfaceTexture`] to the OpenGL ES context that is current on the calling thread. - /// A new OpenGL ES texture object is created and populated with the SurfaceTexture image frame - /// that was current at the time of the last call to ASurfaceTexture_detachFromGLContext. - /// This new texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target. - /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES contexts. - /// Note, however, that the image contents are only accessible from one OpenGL ES context at a time. + /// Attach the [`SurfaceTexture`] to the OpenGL ES context that is current on the calling + /// thread. + /// + /// A new OpenGL ES texture object is created and populated with the [`SurfaceTexture`] image + /// frame that was current at the time of the last call to + /// [`detach_from_gl_context()`][Self::detach_from_gl_context()]. This new texture is bound to + /// the `GL_TEXTURE_EXTERNAL_OES` texture target. + /// + /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES + /// contexts. Note, however, that the image contents are only accessible from one OpenGL ES + /// context at a time. pub fn attach_to_gl_context(&self, tex_name: u32) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_attachToGLContext(self.ptr.as_ptr(), tex_name) }; if r == 0 { @@ -75,13 +88,17 @@ impl SurfaceTexture { } } - /// Detach the [`SurfaceTexture`] from the OpenGL ES context that owns the OpenGL ES texture object. + /// Detach the [`SurfaceTexture`] from the OpenGL ES context that owns the OpenGL ES texture + /// object. + /// /// This call must be made with the OpenGL ES context current on the calling thread. The OpenGL /// ES texture object will be deleted as a result of this call. After calling this method all - /// calls to [`update_tex_image()`][Self::update_tex_image()] will fail until a successful call to - /// [`attach_to_gl_context()`][Self::attach_to_gl_context()] is made. - /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES contexts. - /// Note, however, that the image contents are only accessible from one OpenGL ES context at a time. + /// calls to [`update_tex_image()`][Self::update_tex_image()] will fail until a successful call + /// to [`attach_to_gl_context()`][Self::attach_to_gl_context()] is made. + /// + /// This can be used to access the [`SurfaceTexture`] image contents from multiple OpenGL ES + /// contexts. Note, however, that the image contents are only accessible from one OpenGL ES + /// context at a time. pub fn detach_from_gl_context(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_detachFromGLContext(self.ptr.as_ptr()) }; if r == 0 { @@ -91,30 +108,55 @@ impl SurfaceTexture { } } - /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to [`update_tex_image()`][Self::update_tex_image()]. + /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set + /// by the most recent call to [`update_tex_image()`][Self::update_tex_image()]. + /// + /// This transform matrix maps 2D homogeneous texture coordinates of the form `(s, t, 0, 1)` + /// with `s` and `t` in the inclusive range `[0, 1]` to the texture coordinate that should be + /// used to sample that location from the texture. Sampling the texture outside of the range of + /// this transform is undefined. + /// + /// The matrix is stored in column-major order so that it may be passed directly to OpenGL ES + /// via the [`glLoadMatrixf()`] or [`glUniformMatrix4fv()`] functions. + /// + /// [`glLoadMatrixf()`]: https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glLoadMatrix.xml + /// [`gluniformmatrix4fv()`]: https://www.khronos.org/registry/OpenGL-Refpages/es3.1/html/glUniform.xhtml pub fn transform_matrix(&self) -> [f32; 16] { let mut r = [0f32; 16]; unsafe { ffi::ASurfaceTexture_getTransformMatrix(self.ptr.as_ptr(), r.as_mut_ptr()) }; r } - /// Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by the most recent call to updateTexImage. - /// This transform matrix maps 2D homogeneous texture coordinates of the form (s, t, 0, 1) with s and t in the inclusive range [0, 1] to the texture coordinate - /// that should be used to sample that location from the texture. Sampling the texture outside of the range of this transform is undefined. - /// The matrix is stored in column-major order so that it may be passed directly to OpenGL ES via the glLoadMatrixf or glUniformMatrix4fv functions. - /// This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp should be unaffected by time-of-day adjustments, and for - /// a camera should be strictly monotonic but for a MediaPlayer may be reset when the position is set. The specific meaning and zero point of the timestamp depends - /// on the source providing images to the SurfaceTexture. Unless otherwise specified by the image source, timestamps cannot generally be compared across SurfaceTexture - /// instances, or across multiple program invocations. It is mostly useful for determining time offsets between subsequent frames - /// For EGL/Vulkan producers, this timestamp is the desired present time set with the EGL_ANDROID_presentation_time or VK_GOOGLE_display_timing extensions - pub fn timestamp(&self) -> i64 { - unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } + /// Retrieve the timestamp associated with the texture image set by the most recent call to + /// [`update_tex_image()`][Self::update_tex_image()]. + /// + /// This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp + /// should be unaffected by time-of-day adjustments, and for a camera should be strictly + /// monotonic but for a [`MediaPlayer`] may be reset when the position is set. The specific + /// meaning and zero point of the timestamp depends on the source providing images to the + /// [`SurfaceTexture`]. Unless otherwise specified by the image source, timestamps cannot + /// generally be compared across [`SurfaceTexture`] instances, or across multiple program + /// invocations. It is mostly useful for determining time offsets between subsequent frames. + /// + /// For EGL/Vulkan producers, this timestamp is the desired present time set with the + /// `EGL_ANDROID_presentation_time` or `VK_GOOGLE_display_timing` extensions. + /// + /// [`MediaPlayer`]: https://developer.android.com/reference/android/media/MediaPlayer + /// [`EGL_ANDROID_presentation_time`]: https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_presentation_time.txt + /// [`VK_GOOGLE_display_timing`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html + pub fn timestamp(&self) -> Duration { + Duration::from_nanos( + unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) } + .try_into() + .unwrap(), + ) } /// Update the texture image to the most recent frame from the image stream. - /// This may only be called while the OpenGL ES context that owns the texture is - /// current on the calling thread. It will implicitly bind its texture to the - /// `GL_TEXTURE_EXTERNAL_OES` texture target. + /// + /// This may only be called while the OpenGL ES context that owns the texture is current on the + /// calling thread. It will implicitly bind its texture to the `GL_TEXTURE_EXTERNAL_OES` + /// texture target. pub fn update_tex_image(&self) -> Result<(), PosixError> { let r = unsafe { ffi::ASurfaceTexture_updateTexImage(self.ptr.as_ptr()) }; if r == 0 { From fc0c399114f4649b09f659cbc4beb7c8a6cb4a47 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 9 Jun 2022 01:01:24 +0200 Subject: [PATCH 34/35] Add changelog entry --- ndk/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ndk/CHANGELOG.md b/ndk/CHANGELOG.md index 4bb4d463..5f4e9693 100644 --- a/ndk/CHANGELOG.md +++ b/ndk/CHANGELOG.md @@ -11,6 +11,7 @@ - native_window: Add `format()` getter and `set_buffers_geometry()` setter. (#276) - native_activity: Add `set_window_format()` setter. (#277) - native_activity: Add `set_window_flags()` to change window behavior. (#278) +- Add `SurfaceTexture` bindings. (#267) # 0.6.0 (2022-01-05) From 4908cacd62fcef1d6803065d2723ac15c7f620f7 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 9 Jun 2022 11:53:24 +0200 Subject: [PATCH 35/35] More doc links --- ndk/src/surface_texture.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ndk/src/surface_texture.rs b/ndk/src/surface_texture.rs index 649e80de..2d79bd77 100644 --- a/ndk/src/surface_texture.rs +++ b/ndk/src/surface_texture.rs @@ -1,7 +1,9 @@ -//! Bindings for [`ffi::ASurfaceTexture`] +//! Bindings for [`ASurfaceTexture`] //! //! See for an architectural overview of //! [`SurfaceTexture`] internals. +//! +//! [`ASurfaceTexture`]: https://developer.android.com/ndk/reference/group/surface-texture #![cfg(feature = "api-level-28")] use super::posix::PosixError; @@ -9,7 +11,9 @@ use crate::native_window::NativeWindow; use jni_sys::{jobject, JNIEnv}; use std::{convert::TryInto, ptr::NonNull, time::Duration}; -/// +/// An opaque type to manage [`android.graphics.SurfaceTexture`] from native code +/// +/// [`android.graphics.SurfaceTexture`]: https://developer.android.com/reference/android/graphics/SurfaceTexture #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct SurfaceTexture { ptr: NonNull, @@ -32,7 +36,7 @@ impl SurfaceTexture { Self { ptr } } - /// Get a reference to the native [`SurfaceTexture`] from the corresponding java object. + /// Get a reference to the native [`SurfaceTexture`] from the corresponding Java object. /// /// # Safety /// @@ -139,7 +143,7 @@ impl SurfaceTexture { /// invocations. It is mostly useful for determining time offsets between subsequent frames. /// /// For EGL/Vulkan producers, this timestamp is the desired present time set with the - /// `EGL_ANDROID_presentation_time` or `VK_GOOGLE_display_timing` extensions. + /// [`EGL_ANDROID_presentation_time`] or [`VK_GOOGLE_display_timing`] extensions. /// /// [`MediaPlayer`]: https://developer.android.com/reference/android/media/MediaPlayer /// [`EGL_ANDROID_presentation_time`]: https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_presentation_time.txt