Skip to content

Commit

Permalink
Add Window::on_present_notify to ack about drawing
Browse files Browse the repository at this point in the history
That's a way to communicate to winit that you'll present to the window.
While it's a no-op for now, it'll be used to throttle drawing.
  • Loading branch information
kchibisov committed Jun 23, 2023
1 parent 66ff52b commit 95ff88a
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre

# Unreleased

- Add `Window::pre_present_notify` to notify winit before presenting to the windowing system.
- On Android, changed default behavior of Android to ignore volume keys letting the operating system handle them.
- On Android, added `EventLoopBuilderExtAndroid::handle_volume_keys` to indicate that the application will handle the volume keys manually.
- **Breaking:** Rename `DeviceEventFilter` to `DeviceEvents` reversing the behavior of variants.
Expand Down
2 changes: 2 additions & 0 deletions examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ fn main() {
window.request_redraw();
}
Event::RedrawRequested(_) => {
// Notify the windowing system that we'll be presenting to the window.
window.pre_present_notify();
fill::fill_window(&window);
}
_ => (),
Expand Down
2 changes: 2 additions & 0 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,8 @@ impl Window {
self.redraw_requester.request_redraw()
}

pub fn pre_present_notify(&self) {}

pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
Err(error::NotSupportedError::new())
}
Expand Down
2 changes: 2 additions & 0 deletions src/platform_impl/ios/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ impl Inner {
}
}

pub fn pre_present_notify(&self) {}

pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
unsafe {
let safe_area = self.safe_area_screen_space();
Expand Down
12 changes: 6 additions & 6 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,19 +541,19 @@ impl Window {
}
}
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
match self {
#[cfg(x11_platform)]
Window::X(ref w) => w.request_user_attention(request_type),
#[cfg(wayland_platform)]
Window::Wayland(ref w) => w.request_user_attention(request_type),
}
x11_or_wayland!(match self; Window(w) => w.request_user_attention(request_type))
}

#[inline]
pub fn request_redraw(&self) {
x11_or_wayland!(match self; Window(w) => w.request_redraw())
}

#[inline]
pub fn pre_present_notify(&self) {
x11_or_wayland!(match self; Window(w) => w.pre_present_notify())
}

#[inline]
pub fn current_monitor(&self) -> Option<MonitorHandle> {
match self {
Expand Down
5 changes: 5 additions & 0 deletions src/platform_impl/linux/wayland/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ impl Window {
self.event_loop_awakener.ping();
}

#[inline]
pub fn pre_present_notify(&self) {
// TODO
}

#[inline]
pub fn outer_size(&self) -> PhysicalSize<u32> {
let window_state = self.window_state.lock().unwrap();
Expand Down
5 changes: 5 additions & 0 deletions src/platform_impl/linux/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,11 @@ impl UnownedWindow {
.unwrap();
}

#[inline]
pub fn pre_present_notify(&self) {
// TODO timer
}

#[inline]
pub fn raw_window_handle(&self) -> RawWindowHandle {
let mut window_handle = XlibWindowHandle::empty();
Expand Down
3 changes: 3 additions & 0 deletions src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,9 @@ impl WinitWindow {
AppState::queue_redraw(RootWindowId(self.id()));
}

#[inline]
pub fn pre_present_notify(&self) {}

pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
let frame_rect = self.frame();
let position = LogicalPosition::new(
Expand Down
3 changes: 3 additions & 0 deletions src/platform_impl/orbital/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ impl Window {
}
}

#[inline]
pub fn pre_present_notify(&self) {}

#[inline]
pub fn reset_dead_keys(&self) {
// TODO?
Expand Down
2 changes: 2 additions & 0 deletions src/platform_impl/web/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ impl Window {
.dispatch(|inner| (inner.register_redraw_request)());
}

pub fn pre_present_notify(&self) {}

pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
self.inner.queue(|inner| {
Ok(inner
Expand Down
3 changes: 3 additions & 0 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ impl Window {
}
}

#[inline]
pub fn pre_present_notify(&self) {}

#[inline]
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
util::WindowArea::Outer.get_rect(self.hwnd())
Expand Down
37 changes: 37 additions & 0 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,43 @@ impl Window {
self.window.request_redraw()
}

/// Notify the windowing system that you're before presenting to the window.
///
/// You should call this event after you've done drawing operations, but before you submit
/// the buffer to the display or commit your drawings. Doing so will help winit to properly
/// schedule and do assumptions about its internal state. For example, it could properly
/// throttle [`Event::RedrawRequested`].
///
/// ## Example
///
/// This example illustrates how it looks with OpenGL, but it applies to other graphics
/// APIs and software rendering.
///
/// ```no_run
/// # use winit::event_loop::EventLoop;
/// # use winit::window::Window;
/// # let mut event_loop = EventLoop::new();
/// # let window = Window::new(&event_loop).unwrap();
/// # fn swap_buffers() {}
/// // Do the actual drawing with OpenGL.
///
/// // Notify winit that we're about to submit buffer to the windowing system.
/// window.pre_present_notify();
///
/// // Sumbit buffer to the windowing system.
/// swap_buffers();
/// ```
///
/// ## Platform-specific
///
/// **Wayland:** - schedules a frame callback to throttle [`Event::RedrawRequested`].
///
/// [`Event::RedrawRequested`]: crate::event::Event::RedrawRequested
#[inline]
pub fn pre_present_notify(&self) {
self.window.pre_present_notify();
}

/// Reset the dead key state of the keyboard.
///
/// This is useful when a dead key is bound to trigger an action. Then
Expand Down

0 comments on commit 95ff88a

Please sign in to comment.