Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Replace VSync with PresentMode #3812

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions crates/bevy_render/src/view/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
use bevy_utils::{tracing::debug, HashMap, HashSet};
use bevy_window::{RawWindowHandleWrapper, WindowId, Windows};
use bevy_window::{PresentMode, RawWindowHandleWrapper, WindowId, Windows};
use std::ops::{Deref, DerefMut};
use wgpu::TextureFormat;

Expand Down Expand Up @@ -43,7 +43,7 @@ pub struct ExtractedWindow {
pub handle: RawWindowHandleWrapper,
pub physical_width: u32,
pub physical_height: u32,
pub vsync: bool,
pub present_mode: PresentMode,
pub swap_chain_texture: Option<TextureView>,
pub size_changed: bool,
}
Expand Down Expand Up @@ -83,7 +83,7 @@ fn extract_windows(mut render_world: ResMut<RenderWorld>, windows: Res<Windows>)
handle: window.raw_window_handle(),
physical_width: new_width,
physical_height: new_height,
vsync: window.vsync(),
present_mode: window.present_mode(),
swap_chain_texture: None,
size_changed: false,
});
Expand Down Expand Up @@ -138,10 +138,10 @@ pub fn prepare_windows(
width: window.physical_width,
height: window.physical_height,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
present_mode: if window.vsync {
wgpu::PresentMode::Fifo
} else {
wgpu::PresentMode::Immediate
present_mode: match window.present_mode {
PresentMode::Fifo => wgpu::PresentMode::Fifo,
PresentMode::Mailbox => wgpu::PresentMode::Mailbox,
PresentMode::Immediate => wgpu::PresentMode::Immediate,
},
};

Expand Down
59 changes: 48 additions & 11 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ use raw_window_handle::RawWindowHandle;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct WindowId(Uuid);

/// Presentation mode for a window.
///
/// The presentation mode specifies when a frame is presented to the window. The `Fifo`
/// option corresponds to a traditional `VSync`, where the framerate is capped by the
/// display refresh rate. Both `Immediate` and `Mailbox` are low-latency and are not
/// capped by the refresh rate, but may not be available on all platforms. Tearing
/// may be observed with `Immediate` mode, but will not be observed with `Mailbox` or
/// `Fifo`.
///
/// `Immediate` or `Mailbox` will gracefully fallback to `Fifo` when unavailable.
///
/// The presentation mode may be declared in the [`WindowDescriptor`](WindowDescriptor::present_mode)
/// or updated on a [`Window`](Window::set_present_mode).
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[doc(alias = "vsync")]
pub enum PresentMode {
aloucks marked this conversation as resolved.
Show resolved Hide resolved
/// The presentation engine does **not** wait for a vertical blanking period and
/// the request is presented immediately. This is a low-latency presentation mode,
/// but visible tearing may be observed. Will fallback to `Fifo` if unavailable on the
/// selected platform and backend. Not optimal for mobile.
Immediate = 0,
aloucks marked this conversation as resolved.
Show resolved Hide resolved
/// The presentation engine waits for the next vertical blanking period to update
/// the current image, but frames may be submitted without delay. This is a low-latency
/// presentation mode and visible tearing will **not** be observed. Will fallback to `Fifo`
/// if unavailable on the selected platform and backend. Not optimal for mobile.
Mailbox = 1,
/// The presentation engine waits for the next vertical blanking period to update
/// the current image. The framerate will be capped at the display refresh rate,
/// corresponding to the `VSync`. Tearing cannot be observed. Optimal for mobile.
Fifo = 2, // NOTE: The explicit ordinal values mirror wgpu and the vulkan spec.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put this comment on the enum itself instead of on this one variant within the enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it here so that it's in close proximity to the values. The concern was that someone might remove them erroneously, and having the comment right next to the value makes it rather impossible to miss.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont have a strong opinion here :)

}

impl WindowId {
pub fn new() -> Self {
WindowId(Uuid::new_v4())
Expand Down Expand Up @@ -121,7 +154,7 @@ pub struct Window {
scale_factor_override: Option<f64>,
backend_scale_factor: f64,
title: String,
vsync: bool,
present_mode: PresentMode,
resizable: bool,
decorations: bool,
cursor_icon: CursorIcon,
Expand Down Expand Up @@ -152,8 +185,8 @@ pub enum WindowCommand {
logical_resolution: (f32, f32),
scale_factor: f64,
},
SetVsync {
vsync: bool,
SetPresentMode {
present_mode: PresentMode,
},
SetResizable {
resizable: bool,
Expand Down Expand Up @@ -222,7 +255,7 @@ impl Window {
scale_factor_override: window_descriptor.scale_factor_override,
backend_scale_factor: scale_factor,
title: window_descriptor.title.clone(),
vsync: window_descriptor.vsync,
present_mode: window_descriptor.present_mode,
resizable: window_descriptor.resizable,
decorations: window_descriptor.decorations,
cursor_visible: window_descriptor.cursor_visible,
Expand Down Expand Up @@ -425,14 +458,17 @@ impl Window {
}

#[inline]
pub fn vsync(&self) -> bool {
self.vsync
#[doc(alias = "vsync")]
pub fn present_mode(&self) -> PresentMode {
self.present_mode
}

#[inline]
pub fn set_vsync(&mut self, vsync: bool) {
self.vsync = vsync;
self.command_queue.push(WindowCommand::SetVsync { vsync });
#[doc(alias = "set_vsync")]
pub fn set_present_mode(&mut self, present_mode: PresentMode) {
self.present_mode = present_mode;
self.command_queue
.push(WindowCommand::SetPresentMode { present_mode });
}

#[inline]
Expand Down Expand Up @@ -557,7 +593,8 @@ pub struct WindowDescriptor {
pub resize_constraints: WindowResizeConstraints,
pub scale_factor_override: Option<f64>,
pub title: String,
pub vsync: bool,
#[doc(alias = "vsync")]
pub present_mode: PresentMode,
pub resizable: bool,
pub decorations: bool,
pub cursor_visible: bool,
Expand All @@ -584,7 +621,7 @@ impl Default for WindowDescriptor {
position: None,
resize_constraints: WindowResizeConstraints::default(),
scale_factor_override: None,
vsync: true,
present_mode: PresentMode::Fifo,
resizable: true,
decorations: true,
cursor_locked: false,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fn change_window(world: &mut World) {
.to_physical::<f64>(scale_factor),
);
}
bevy_window::WindowCommand::SetVsync { .. } => (),
bevy_window::WindowCommand::SetPresentMode { .. } => (),
bevy_window::WindowCommand::SetResizable { resizable } => {
let window = winit_windows.get_window(id).unwrap();
window.set_resizable(resizable);
Expand Down
1 change: 0 additions & 1 deletion examples/ios/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use bevy::{input::touch::TouchPhase, prelude::*, window::WindowMode};
fn main() {
App::new()
.insert_resource(WindowDescriptor {
vsync: true,
resizable: false,
mode: WindowMode::BorderlessFullscreen,
..Default::default()
Expand Down
3 changes: 2 additions & 1 deletion examples/tools/bevymark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bevy::{
core::FixedTimestep,
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
prelude::*,
window::PresentMode,
};
use rand::random;

Expand All @@ -28,7 +29,7 @@ fn main() {
title: "BevyMark".to_string(),
width: 800.,
height: 600.,
vsync: false,
present_mode: PresentMode::Mailbox,
resizable: true,
..Default::default()
})
Expand Down
3 changes: 2 additions & 1 deletion examples/ui/text_debug.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use bevy::{
diagnostic::{Diagnostics, FrameTimeDiagnosticsPlugin},
prelude::*,
window::PresentMode,
};

/// This example is for debugging text layout
fn main() {
App::new()
.insert_resource(WindowDescriptor {
vsync: false,
present_mode: PresentMode::Immediate,
..Default::default()
})
.add_plugins(DefaultPlugins)
Expand Down
4 changes: 2 additions & 2 deletions examples/window/multiple_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bevy::{
renderer::RenderContext,
RenderApp, RenderStage,
},
window::{CreateWindow, WindowId},
window::{CreateWindow, PresentMode, WindowId},
};

/// This example creates a second window and draws a mesh from two different cameras, one in each window
Expand Down Expand Up @@ -57,7 +57,7 @@ fn create_new_window(
descriptor: WindowDescriptor {
width: 800.,
height: 600.,
vsync: false,
present_mode: PresentMode::Immediate,
title: "Second window".to_string(),
..Default::default()
},
Expand Down
4 changes: 2 additions & 2 deletions examples/window/window_settings.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::prelude::*;
use bevy::{prelude::*, window::PresentMode};

/// This example illustrates how to customize the default window settings
fn main() {
Expand All @@ -7,7 +7,7 @@ fn main() {
title: "I am a window!".to_string(),
width: 500.,
height: 300.,
vsync: true,
present_mode: PresentMode::Fifo,
..Default::default()
})
.add_plugins(DefaultPlugins)
Expand Down