mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 14:20:04 -04:00
Address review comments
This commit is contained in:
2
.github/workflows/rust.yml
vendored
2
.github/workflows/rust.yml
vendored
@@ -94,7 +94,7 @@ jobs:
|
|||||||
- name: wasm-bindgen
|
- name: wasm-bindgen
|
||||||
uses: jetli/wasm-bindgen-action@v0.1.0
|
uses: jetli/wasm-bindgen-action@v0.1.0
|
||||||
with:
|
with:
|
||||||
version: "0.2.114" # Keep wasm-bindgen version in sync in: setup_web.sh, Cargo.toml, Cargo.lock, rust.yml
|
version: "0.2.108" # Keep wasm-bindgen version in sync in: setup_web.sh, Cargo.toml, Cargo.lock, rust.yml
|
||||||
|
|
||||||
- run: ./scripts/wasm_bindgen_check.sh --skip-setup
|
- run: ./scripts/wasm_bindgen_check.sh --skip-setup
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ type-map = "0.5.1"
|
|||||||
unicode_names2 = { version = "2.0.0", default-features = false }
|
unicode_names2 = { version = "2.0.0", default-features = false }
|
||||||
unicode-segmentation = "1.12.0"
|
unicode-segmentation = "1.12.0"
|
||||||
vello_cpu = { version = "0.0.6", default-features = false, features = ["std", "u8_pipeline", "f32_pipeline"] }
|
vello_cpu = { version = "0.0.6", default-features = false, features = ["std", "u8_pipeline", "f32_pipeline"] }
|
||||||
wasm-bindgen = "0.2.114" # Keep wasm-bindgen version in sync in: setup_web.sh, Cargo.toml, Cargo.lock, rust.yml
|
wasm-bindgen = "0.2.108" # Keep wasm-bindgen version in sync in: setup_web.sh, Cargo.toml, Cargo.lock, rust.yml
|
||||||
wasm-bindgen-futures = "0.4.0"
|
wasm-bindgen-futures = "0.4.0"
|
||||||
wayland-cursor = { version = "0.31.11", default-features = false }
|
wayland-cursor = { version = "0.31.11", default-features = false }
|
||||||
web-sys = "0.3.77"
|
web-sys = "0.3.77"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use egui::{Event, UserData, ViewportId};
|
use egui::{Event, UserData, ViewportId};
|
||||||
use egui_wgpu::{
|
use egui_wgpu::{
|
||||||
RenderState, SurfaceErrorAction, SurfaceStatus,
|
RenderState, SurfaceErrorAction,
|
||||||
capture::{CaptureReceiver, CaptureSender, CaptureState, capture_channel},
|
capture::{CaptureReceiver, CaptureSender, CaptureState, capture_channel},
|
||||||
};
|
};
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
@@ -15,7 +15,7 @@ pub(crate) struct WebPainterWgpu {
|
|||||||
surface: wgpu::Surface<'static>,
|
surface: wgpu::Surface<'static>,
|
||||||
surface_configuration: wgpu::SurfaceConfiguration,
|
surface_configuration: wgpu::SurfaceConfiguration,
|
||||||
render_state: Option<RenderState>,
|
render_state: Option<RenderState>,
|
||||||
on_surface_error: Arc<dyn Fn(SurfaceStatus) -> SurfaceErrorAction>,
|
on_surface_status: Arc<dyn Fn(&wgpu::CurrentSurfaceTexture) -> SurfaceErrorAction>,
|
||||||
depth_stencil_format: Option<wgpu::TextureFormat>,
|
depth_stencil_format: Option<wgpu::TextureFormat>,
|
||||||
depth_texture_view: Option<wgpu::TextureView>,
|
depth_texture_view: Option<wgpu::TextureView>,
|
||||||
screen_capture_state: Option<CaptureState>,
|
screen_capture_state: Option<CaptureState>,
|
||||||
@@ -105,7 +105,7 @@ impl WebPainterWgpu {
|
|||||||
surface_configuration,
|
surface_configuration,
|
||||||
depth_stencil_format,
|
depth_stencil_format,
|
||||||
depth_texture_view: None,
|
depth_texture_view: None,
|
||||||
on_surface_error: Arc::clone(&options.wgpu_options.on_surface_error) as _,
|
on_surface_status: Arc::clone(&options.wgpu_options.on_surface_status) as _,
|
||||||
screen_capture_state: None,
|
screen_capture_state: None,
|
||||||
capture_tx,
|
capture_tx,
|
||||||
capture_rx,
|
capture_rx,
|
||||||
@@ -196,50 +196,14 @@ impl WebPainter for WebPainterWgpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let output_frame = match self.surface.get_current_texture() {
|
let output_frame = match self.surface.get_current_texture() {
|
||||||
wgpu::CurrentSurfaceTexture::Success(frame)
|
wgpu::CurrentSurfaceTexture::Success(frame) => frame,
|
||||||
| wgpu::CurrentSurfaceTexture::Suboptimal(frame) => frame,
|
wgpu::CurrentSurfaceTexture::Suboptimal(frame) => {
|
||||||
wgpu::CurrentSurfaceTexture::Timeout => {
|
self.surface
|
||||||
match (*self.on_surface_error)(SurfaceStatus::Timeout) {
|
.configure(&render_state.device, &self.surface_configuration);
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
frame
|
||||||
self.surface
|
|
||||||
.configure(&render_state.device, &self.surface_configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
wgpu::CurrentSurfaceTexture::Outdated => {
|
ref other => {
|
||||||
match (*self.on_surface_error)(SurfaceStatus::Outdated) {
|
match (*self.on_surface_status)(other) {
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
|
||||||
self.surface
|
|
||||||
.configure(&render_state.device, &self.surface_configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
wgpu::CurrentSurfaceTexture::Lost => {
|
|
||||||
match (*self.on_surface_error)(SurfaceStatus::Lost) {
|
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
|
||||||
self.surface
|
|
||||||
.configure(&render_state.device, &self.surface_configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
wgpu::CurrentSurfaceTexture::Occluded => {
|
|
||||||
match (*self.on_surface_error)(SurfaceStatus::Occluded) {
|
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
|
||||||
self.surface
|
|
||||||
.configure(&render_state.device, &self.surface_configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
wgpu::CurrentSurfaceTexture::Validation => {
|
|
||||||
match (*self.on_surface_error)(SurfaceStatus::Validation) {
|
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
SurfaceErrorAction::RecreateSurface => {
|
||||||
self.surface
|
self.surface
|
||||||
.configure(&render_state.device, &self.surface_configuration);
|
.configure(&render_state.device, &self.surface_configuration);
|
||||||
|
|||||||
@@ -276,58 +276,7 @@ fn describe_adapters(adapters: &[wgpu::Adapter]) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes a surface error when acquiring a texture for rendering.
|
/// Specifies which action should be taken as consequence of a surface error.
|
||||||
///
|
|
||||||
/// These correspond to the error variants of [`wgpu::CurrentSurfaceTexture`] — everything
|
|
||||||
/// except `Success` and `Suboptimal`, which contain usable frames. This enum is passed to the
|
|
||||||
/// [`WgpuConfiguration::on_surface_error`] callback so you can decide how to respond.
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub enum SurfaceStatus {
|
|
||||||
/// Timed out waiting for the next frame.
|
|
||||||
///
|
|
||||||
/// This is usually transient. Skip the current frame and try again next frame.
|
|
||||||
Timeout,
|
|
||||||
|
|
||||||
/// The surface configuration no longer matches the underlying display surface.
|
|
||||||
///
|
|
||||||
/// The surface should be reconfigured (egui will do this automatically if you return
|
|
||||||
/// [`SurfaceErrorAction::RecreateSurface`]). This commonly happens after a window resize
|
|
||||||
/// or display settings change.
|
|
||||||
Outdated,
|
|
||||||
|
|
||||||
/// The surface has been lost and must be recreated from scratch.
|
|
||||||
///
|
|
||||||
/// This is more severe than [`Self::Outdated`] — the entire surface is invalid. Return
|
|
||||||
/// [`SurfaceErrorAction::RecreateSurface`] to recover.
|
|
||||||
Lost,
|
|
||||||
|
|
||||||
/// The window is not visible (e.g. minimized or fully behind another window).
|
|
||||||
///
|
|
||||||
/// Skip the current frame. There is nothing to render to.
|
|
||||||
Occluded,
|
|
||||||
|
|
||||||
/// A GPU validation error occurred.
|
|
||||||
///
|
|
||||||
/// This should not be reachable under normal circumstances, unless
|
|
||||||
/// you wrap the [`winit::Painter::paint_and_update_textures`] in a wgpu
|
|
||||||
/// error scope, and there is a validation error in the
|
|
||||||
/// [`wgpu::Surface::get_current_texture`] call.
|
|
||||||
Validation,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for SurfaceStatus {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Timeout => write!(f, "Surface timed out"),
|
|
||||||
Self::Outdated => write!(f, "Surface outdated"),
|
|
||||||
Self::Lost => write!(f, "Surface lost"),
|
|
||||||
Self::Occluded => write!(f, "Surface occluded"),
|
|
||||||
Self::Validation => write!(f, "Surface validation error"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Specifies which action should be taken as consequence of a [`SurfaceStatus`]
|
|
||||||
pub enum SurfaceErrorAction {
|
pub enum SurfaceErrorAction {
|
||||||
/// Do nothing and skip the current frame.
|
/// Do nothing and skip the current frame.
|
||||||
SkipFrame,
|
SkipFrame,
|
||||||
@@ -354,8 +303,13 @@ pub struct WgpuConfiguration {
|
|||||||
/// How to create the wgpu adapter & device
|
/// How to create the wgpu adapter & device
|
||||||
pub wgpu_setup: WgpuSetup,
|
pub wgpu_setup: WgpuSetup,
|
||||||
|
|
||||||
/// Callback for surface errors.
|
/// Callback for surface status changes.
|
||||||
pub on_surface_error: Arc<dyn Fn(SurfaceStatus) -> SurfaceErrorAction + Send + Sync>,
|
///
|
||||||
|
/// Called with the [`wgpu::CurrentSurfaceTexture`] result whenever acquiring a frame
|
||||||
|
/// does not return [`wgpu::CurrentSurfaceTexture::Success`]. For
|
||||||
|
/// [`wgpu::CurrentSurfaceTexture::Suboptimal`], egui automatically reconfigures the
|
||||||
|
/// surface and uses the frame — the callback is not invoked in that case.
|
||||||
|
pub on_surface_status: Arc<dyn Fn(&wgpu::CurrentSurfaceTexture) -> SurfaceErrorAction + Send + Sync>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -370,7 +324,7 @@ impl std::fmt::Debug for WgpuConfiguration {
|
|||||||
present_mode,
|
present_mode,
|
||||||
desired_maximum_frame_latency,
|
desired_maximum_frame_latency,
|
||||||
wgpu_setup,
|
wgpu_setup,
|
||||||
on_surface_error: _,
|
on_surface_status: _,
|
||||||
} = self;
|
} = self;
|
||||||
f.debug_struct("WgpuConfiguration")
|
f.debug_struct("WgpuConfiguration")
|
||||||
.field("present_mode", &present_mode)
|
.field("present_mode", &present_mode)
|
||||||
@@ -391,13 +345,13 @@ impl Default for WgpuConfiguration {
|
|||||||
// No display handle available at this point — callers should replace this with
|
// No display handle available at this point — callers should replace this with
|
||||||
// `WgpuSetup::from_display_handle(...)` before creating the instance if one is available.
|
// `WgpuSetup::from_display_handle(...)` before creating the instance if one is available.
|
||||||
wgpu_setup: WgpuSetup::without_display_handle(),
|
wgpu_setup: WgpuSetup::without_display_handle(),
|
||||||
on_surface_error: Arc::new(|err| {
|
on_surface_status: Arc::new(|status| {
|
||||||
if err == SurfaceStatus::Outdated {
|
if matches!(status, wgpu::CurrentSurfaceTexture::Outdated) {
|
||||||
// This error occurs when the app is minimized on Windows.
|
// This error occurs when the app is minimized on Windows.
|
||||||
// Silently return here to prevent spamming the console with:
|
// Silently return here to prevent spamming the console with:
|
||||||
// "The underlying surface has changed, and therefore the swap chain must be updated"
|
// "The underlying surface has changed, and therefore the swap chain must be updated"
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Dropped frame with error: {err}");
|
log::warn!("Dropped frame with error: {status:?}");
|
||||||
}
|
}
|
||||||
SurfaceErrorAction::SkipFrame
|
SurfaceErrorAction::SkipFrame
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -132,16 +132,13 @@ impl WgpuSetup {
|
|||||||
|
|
||||||
log::debug!("Creating wgpu instance with backends {backends:?}");
|
log::debug!("Creating wgpu instance with backends {backends:?}");
|
||||||
let desc = &create_new.instance_descriptor;
|
let desc = &create_new.instance_descriptor;
|
||||||
let mut descriptor = wgpu::InstanceDescriptor {
|
let descriptor = wgpu::InstanceDescriptor {
|
||||||
backends: desc.backends,
|
backends: desc.backends,
|
||||||
flags: desc.flags,
|
flags: desc.flags,
|
||||||
backend_options: desc.backend_options.clone(),
|
backend_options: desc.backend_options.clone(),
|
||||||
memory_budget_thresholds: desc.memory_budget_thresholds,
|
memory_budget_thresholds: desc.memory_budget_thresholds,
|
||||||
display: None,
|
display: create_new.display_handle.as_ref().map(|handle| handle.clone_for_wgpu()),
|
||||||
};
|
};
|
||||||
if let Some(handle) = &create_new.display_handle {
|
|
||||||
descriptor.display = Some(handle.clone_for_wgpu());
|
|
||||||
}
|
|
||||||
wgpu::util::new_instance_with_webgpu_detection(descriptor).await
|
wgpu::util::new_instance_with_webgpu_detection(descriptor).await
|
||||||
}
|
}
|
||||||
Self::Existing(existing) => existing.instance.clone(),
|
Self::Existing(existing) => existing.instance.clone(),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#![expect(clippy::unwrap_used)] // TODO(emilk): avoid unwraps
|
#![expect(clippy::unwrap_used)] // TODO(emilk): avoid unwraps
|
||||||
#![expect(unsafe_code)]
|
#![expect(unsafe_code)]
|
||||||
|
|
||||||
use crate::{RenderState, SurfaceErrorAction, SurfaceStatus, WgpuConfiguration, renderer};
|
use crate::{RenderState, SurfaceErrorAction, WgpuConfiguration, renderer};
|
||||||
use crate::{
|
use crate::{
|
||||||
RendererOptions,
|
RendererOptions,
|
||||||
capture::{CaptureReceiver, CaptureSender, CaptureState, capture_channel},
|
capture::{CaptureReceiver, CaptureSender, CaptureState, capture_channel},
|
||||||
@@ -501,46 +501,13 @@ impl Painter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let output_frame = match output_frame {
|
let output_frame = match output_frame {
|
||||||
wgpu::CurrentSurfaceTexture::Success(frame)
|
wgpu::CurrentSurfaceTexture::Success(frame) => frame,
|
||||||
| wgpu::CurrentSurfaceTexture::Suboptimal(frame) => frame,
|
wgpu::CurrentSurfaceTexture::Suboptimal(frame) => {
|
||||||
wgpu::CurrentSurfaceTexture::Timeout => {
|
Self::configure_surface(surface_state, render_state, &self.configuration);
|
||||||
match (*self.configuration.on_surface_error)(SurfaceStatus::Timeout) {
|
frame
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
|
||||||
Self::configure_surface(surface_state, render_state, &self.configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return vsync_sec;
|
|
||||||
}
|
}
|
||||||
wgpu::CurrentSurfaceTexture::Outdated => {
|
ref other => {
|
||||||
match (*self.configuration.on_surface_error)(SurfaceStatus::Outdated) {
|
match (*self.configuration.on_surface_status)(other) {
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
|
||||||
Self::configure_surface(surface_state, render_state, &self.configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return vsync_sec;
|
|
||||||
}
|
|
||||||
wgpu::CurrentSurfaceTexture::Lost => {
|
|
||||||
match (*self.configuration.on_surface_error)(SurfaceStatus::Lost) {
|
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
|
||||||
Self::configure_surface(surface_state, render_state, &self.configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return vsync_sec;
|
|
||||||
}
|
|
||||||
wgpu::CurrentSurfaceTexture::Occluded => {
|
|
||||||
match (*self.configuration.on_surface_error)(SurfaceStatus::Occluded) {
|
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
|
||||||
Self::configure_surface(surface_state, render_state, &self.configuration);
|
|
||||||
}
|
|
||||||
SurfaceErrorAction::SkipFrame => {}
|
|
||||||
}
|
|
||||||
return vsync_sec;
|
|
||||||
}
|
|
||||||
wgpu::CurrentSurfaceTexture::Validation => {
|
|
||||||
match (*self.configuration.on_surface_error)(SurfaceStatus::Validation) {
|
|
||||||
SurfaceErrorAction::RecreateSurface => {
|
SurfaceErrorAction::RecreateSurface => {
|
||||||
Self::configure_surface(surface_state, render_state, &self.configuration);
|
Self::configure_surface(surface_state, render_state, &self.configuration);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ rustup target add wasm32-unknown-unknown
|
|||||||
|
|
||||||
# For generating JS bindings:
|
# For generating JS bindings:
|
||||||
# Keep wasm-bindgen version in sync in: setup_web.sh, Cargo.toml, Cargo.lock, rust.yml
|
# Keep wasm-bindgen version in sync in: setup_web.sh, Cargo.toml, Cargo.lock, rust.yml
|
||||||
if ! cargo install --list | grep -q 'wasm-bindgen-cli v0.2.114'; then
|
if ! cargo install --list | grep -q 'wasm-bindgen-cli v0.2.108'; then
|
||||||
cargo install --force --quiet wasm-bindgen-cli --version 0.2.114
|
cargo install --force --quiet wasm-bindgen-cli --version 0.2.108
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user