@@ -17,11 +17,16 @@ use crate::{BufferInterface, Pixel, Rect, SoftBufferError, SurfaceInterface};
1717/// The handle to a window for software buffering.
1818#[ derive( Debug ) ]
1919pub struct AndroidImpl < D , W > {
20+ // Must be first in the struct to guarantee being dropped and unlocked before the `NativeWindow` reference
21+ in_progress_buffer : Option < NativeWindowBufferLockGuard < ' static > > ,
2022 native_window : NativeWindow ,
2123 window : W ,
2224 _display : PhantomData < D > ,
2325}
2426
27+ // TODO: Move to NativeWindowBufferLockGuard?
28+ unsafe impl < D , W > Send for AndroidImpl < D , W > { }
29+
2530impl < D : HasDisplayHandle , W : HasWindowHandle > SurfaceInterface < D , W > for AndroidImpl < D , W > {
2631 type Context = D ;
2732 type Buffer < ' surface >
@@ -41,6 +46,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Android
4146 let native_window = unsafe { NativeWindow :: clone_from_ptr ( a. a_native_window . cast ( ) ) } ;
4247
4348 Ok ( Self {
49+ in_progress_buffer : None ,
4450 native_window,
4551 _display : PhantomData ,
4652 window,
@@ -77,6 +83,12 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Android
7783 }
7884
7985 fn buffer_mut ( & mut self ) -> Result < BufferImpl < ' _ > , SoftBufferError > {
86+ if self . in_progress_buffer . is_some ( ) {
87+ return Ok ( BufferImpl {
88+ native_window_buffer : & mut self . in_progress_buffer ,
89+ } ) ;
90+ }
91+
8092 let native_window_buffer = self . native_window . lock ( None ) . map_err ( |err| {
8193 SoftBufferError :: PlatformError (
8294 Some ( "Failed to lock ANativeWindow" . to_owned ( ) ) ,
@@ -99,8 +111,15 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Android
99111 ) ) ;
100112 }
101113
114+ // SAFETY: We guarantee that the guard isn't actually held longer than this owned handle of
115+ // the `NativeWindow` (which is trivially clonable), by means of having BufferImpl take a
116+ // mutable borrow on AndroidImpl which owns the NativeWindow and LockGuard.
117+ let native_window_buffer: NativeWindowBufferLockGuard < ' static > =
118+ unsafe { std:: mem:: transmute ( native_window_buffer) } ;
119+ self . in_progress_buffer = Some ( native_window_buffer) ;
120+
102121 Ok ( BufferImpl {
103- native_window_buffer,
122+ native_window_buffer : & mut self . in_progress_buffer ,
104123 } )
105124 }
106125
@@ -112,28 +131,29 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Android
112131
113132#[ derive( Debug ) ]
114133pub struct BufferImpl < ' surface > {
115- native_window_buffer : NativeWindowBufferLockGuard < ' surface > ,
134+ // This Option will always be Some until present_with_damage() is called
135+ native_window_buffer : & ' surface mut Option < NativeWindowBufferLockGuard < ' static > > ,
116136}
117137
118138// TODO: Move to NativeWindowBufferLockGuard?
119139unsafe impl Send for BufferImpl < ' _ > { }
120140
121141impl BufferInterface for BufferImpl < ' _ > {
122142 fn byte_stride ( & self ) -> NonZeroU32 {
123- NonZeroU32 :: new ( self . native_window_buffer . stride ( ) as u32 * 4 ) . unwrap ( )
143+ NonZeroU32 :: new ( self . native_window_buffer . as_ref ( ) . unwrap ( ) . stride ( ) as u32 * 4 ) . unwrap ( )
124144 }
125145
126146 fn width ( & self ) -> NonZeroU32 {
127- NonZeroU32 :: new ( self . native_window_buffer . width ( ) as u32 ) . unwrap ( )
147+ NonZeroU32 :: new ( self . native_window_buffer . as_ref ( ) . unwrap ( ) . width ( ) as u32 ) . unwrap ( )
128148 }
129149
130150 fn height ( & self ) -> NonZeroU32 {
131- NonZeroU32 :: new ( self . native_window_buffer . height ( ) as u32 ) . unwrap ( )
151+ NonZeroU32 :: new ( self . native_window_buffer . as_ref ( ) . unwrap ( ) . height ( ) as u32 ) . unwrap ( )
132152 }
133153
134154 #[ inline]
135155 fn pixels_mut ( & mut self ) -> & mut [ Pixel ] {
136- let native_buffer = self . native_window_buffer . bytes ( ) . unwrap ( ) ;
156+ let native_buffer = self . native_window_buffer . as_mut ( ) . unwrap ( ) . bytes ( ) . unwrap ( ) ;
137157 // assert_eq!(
138158 // native_buffer.len(),
139159 // self.native_window_buffer.stride() * self.native_window_buffer.height()
@@ -168,6 +188,7 @@ impl BufferInterface for BufferImpl<'_> {
168188
169189 // The surface will be presented when it is unlocked, which happens when the owned guard
170190 // is dropped.
191+ self . native_window_buffer . take ( ) ;
171192
172193 Ok ( ( ) )
173194 }
0 commit comments