@@ -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,19 @@ 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 cloneable), by means of having BufferImpl take a
116+ // mutable borrow on AndroidImpl which owns the NativeWindow and LockGuard.
117+ let native_window_buffer = unsafe {
118+ std:: mem:: transmute :: <
119+ NativeWindowBufferLockGuard < ' _ > ,
120+ NativeWindowBufferLockGuard < ' static > ,
121+ > ( native_window_buffer)
122+ } ;
123+ self . in_progress_buffer = Some ( native_window_buffer) ;
124+
102125 Ok ( BufferImpl {
103- native_window_buffer,
126+ native_window_buffer : & mut self . in_progress_buffer ,
104127 } )
105128 }
106129
@@ -112,28 +135,29 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for Android
112135
113136#[ derive( Debug ) ]
114137pub struct BufferImpl < ' surface > {
115- native_window_buffer : NativeWindowBufferLockGuard < ' surface > ,
138+ // This Option will always be Some until present_with_damage() is called
139+ native_window_buffer : & ' surface mut Option < NativeWindowBufferLockGuard < ' static > > ,
116140}
117141
118142// TODO: Move to NativeWindowBufferLockGuard?
119143unsafe impl Send for BufferImpl < ' _ > { }
120144
121145impl BufferInterface for BufferImpl < ' _ > {
122146 fn byte_stride ( & self ) -> NonZeroU32 {
123- NonZeroU32 :: new ( self . native_window_buffer . stride ( ) as u32 * 4 ) . unwrap ( )
147+ NonZeroU32 :: new ( self . native_window_buffer . as_ref ( ) . unwrap ( ) . stride ( ) as u32 * 4 ) . unwrap ( )
124148 }
125149
126150 fn width ( & self ) -> NonZeroU32 {
127- NonZeroU32 :: new ( self . native_window_buffer . width ( ) as u32 ) . unwrap ( )
151+ NonZeroU32 :: new ( self . native_window_buffer . as_ref ( ) . unwrap ( ) . width ( ) as u32 ) . unwrap ( )
128152 }
129153
130154 fn height ( & self ) -> NonZeroU32 {
131- NonZeroU32 :: new ( self . native_window_buffer . height ( ) as u32 ) . unwrap ( )
155+ NonZeroU32 :: new ( self . native_window_buffer . as_ref ( ) . unwrap ( ) . height ( ) as u32 ) . unwrap ( )
132156 }
133157
134158 #[ inline]
135159 fn pixels_mut ( & mut self ) -> & mut [ Pixel ] {
136- let native_buffer = self . native_window_buffer . bytes ( ) . unwrap ( ) ;
160+ let native_buffer = self . native_window_buffer . as_mut ( ) . unwrap ( ) . bytes ( ) . unwrap ( ) ;
137161 // assert_eq!(
138162 // native_buffer.len(),
139163 // self.native_window_buffer.stride() * self.native_window_buffer.height()
@@ -168,6 +192,7 @@ impl BufferInterface for BufferImpl<'_> {
168192
169193 // The surface will be presented when it is unlocked, which happens when the owned guard
170194 // is dropped.
195+ self . native_window_buffer . take ( ) ;
171196
172197 Ok ( ( ) )
173198 }
0 commit comments