Skip to content

Commit efe7f94

Browse files
committed
No longer obtain multiple read locks on Android NativeWindow
1 parent cbeddb0 commit efe7f94

File tree

1 file changed

+36
-11
lines changed
  • src/platform_impl/android

1 file changed

+36
-11
lines changed

src/platform_impl/android/mod.rs

+36-11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use ndk::{
1313
native_window::NativeWindow,
1414
};
1515
use ndk_glue::{Event, Rect};
16+
use raw_window_handle::RawWindowHandle;
1617
use std::{
1718
collections::VecDeque,
1819
sync::{Arc, Mutex, RwLock, RwLockReadGuard},
@@ -72,6 +73,7 @@ impl<T: 'static> EventLoop<T> {
7273
Self {
7374
window_target: event_loop::EventLoopWindowTarget {
7475
p: EventLoopWindowTarget {
76+
raw_window_handle: Default::default(),
7577
_marker: std::marker::PhantomData,
7678
},
7779
_marker: std::marker::PhantomData,
@@ -117,6 +119,9 @@ impl<T: 'static> EventLoop<T> {
117119
let native_window_lock = ndk_glue::native_window();
118120
// The window could have gone away before we got the message
119121
if native_window_lock.is_some() {
122+
self.window_target
123+
.p
124+
.update_native_window(native_window_lock.as_ref());
120125
self.native_window_lock = Some(native_window_lock);
121126
call_event_handler!(
122127
event_handler,
@@ -140,6 +145,7 @@ impl<T: 'static> EventLoop<T> {
140145
event::Event::Suspended
141146
);
142147
}
148+
self.window_target.p.update_native_window(None);
143149
}
144150
Event::Pause => self.running = false,
145151
Event::Resume => self.running = true,
@@ -418,10 +424,25 @@ impl<T> Clone for EventLoopProxy<T> {
418424
}
419425

420426
pub struct EventLoopWindowTarget<T: 'static> {
427+
raw_window_handle: Arc<Mutex<Option<RawWindowHandle>>>,
421428
_marker: std::marker::PhantomData<T>,
422429
}
423430

424431
impl<T: 'static> EventLoopWindowTarget<T> {
432+
fn update_native_window(&self, native_window: Option<&NativeWindow>) {
433+
match native_window {
434+
Some(native_window) => {
435+
let mut handle = raw_window_handle::android::AndroidHandle::empty();
436+
handle.a_native_window =
437+
unsafe { native_window.ptr().as_mut() as *mut _ as *mut _ };
438+
*self.raw_window_handle.lock().unwrap() = Some(RawWindowHandle::Android(handle));
439+
}
440+
None => {
441+
*self.raw_window_handle.lock().unwrap() = None;
442+
}
443+
}
444+
}
445+
425446
pub fn primary_monitor(&self) -> Option<monitor::MonitorHandle> {
426447
Some(monitor::MonitorHandle {
427448
inner: MonitorHandle,
@@ -456,16 +477,20 @@ impl DeviceId {
456477
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
457478
pub struct PlatformSpecificWindowBuilderAttributes;
458479

459-
pub struct Window;
480+
pub struct Window {
481+
raw_window_handle: Arc<Mutex<Option<RawWindowHandle>>>,
482+
}
460483

461484
impl Window {
462485
pub fn new<T: 'static>(
463-
_el: &EventLoopWindowTarget<T>,
486+
el: &EventLoopWindowTarget<T>,
464487
_window_attrs: window::WindowAttributes,
465488
_: PlatformSpecificWindowBuilderAttributes,
466489
) -> Result<Self, error::OsError> {
467490
// FIXME this ignores requested window attributes
468-
Ok(Self)
491+
Ok(Self {
492+
raw_window_handle: Arc::clone(&el.raw_window_handle),
493+
})
469494
}
470495

471496
pub fn id(&self) -> WindowId {
@@ -581,14 +606,14 @@ impl Window {
581606
}
582607

583608
pub fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
584-
let a_native_window = if let Some(native_window) = ndk_glue::native_window().as_ref() {
585-
unsafe { native_window.ptr().as_mut() as *mut _ as *mut _ }
586-
} else {
587-
panic!("Cannot get the native window, it's null and will always be null before Event::Resumed and after Event::Suspended. Make sure you only call this function between those events.");
588-
};
589-
let mut handle = raw_window_handle::android::AndroidHandle::empty();
590-
handle.a_native_window = a_native_window;
591-
raw_window_handle::RawWindowHandle::Android(handle)
609+
self.raw_window_handle
610+
.lock()
611+
.unwrap()
612+
.as_ref()
613+
.expect(
614+
"The window can be obtained only between `Event::Resumed` and `Event::Suspended`!",
615+
)
616+
.clone()
592617
}
593618

594619
pub fn config(&self) -> Configuration {

0 commit comments

Comments
 (0)