Merge pull request #2191 from ids1024/raw-window-handle-0.6
Update `wgpu` to `0.19`, `glyphon` to `0.5`, `softbuffer` to `0.4`, `window-clipboard` to `0.4`, and `raw-window-handle` to `0.6`
This commit is contained in:
commit
7ae7fcb898
20 changed files with 207 additions and 128 deletions
12
Cargo.toml
12
Cargo.toml
|
|
@ -126,7 +126,7 @@ bytemuck = { version = "1.0", features = ["derive"] }
|
|||
cosmic-text = "0.10"
|
||||
futures = "0.3"
|
||||
glam = "0.24"
|
||||
glyphon = "0.4"
|
||||
glyphon = "0.5"
|
||||
guillotiere = "0.6"
|
||||
half = "2.2"
|
||||
image = "0.24"
|
||||
|
|
@ -140,12 +140,12 @@ once_cell = "1.0"
|
|||
ouroboros = "0.17"
|
||||
palette = "0.7"
|
||||
qrcode = { version = "0.12", default-features = false }
|
||||
raw-window-handle = "0.5"
|
||||
raw-window-handle = "0.6"
|
||||
resvg = "0.36"
|
||||
rustc-hash = "1.0"
|
||||
smol = "1.0"
|
||||
smol_str = "0.2"
|
||||
softbuffer = "0.2"
|
||||
softbuffer = "0.4"
|
||||
syntect = "5.1"
|
||||
sysinfo = "0.28"
|
||||
thiserror = "1.0"
|
||||
|
|
@ -158,7 +158,7 @@ wasm-bindgen-futures = "0.4"
|
|||
wasm-timer = "0.2"
|
||||
web-sys = "0.3"
|
||||
web-time = "0.2"
|
||||
wgpu = "0.18"
|
||||
wgpu = "0.19"
|
||||
winapi = "0.3"
|
||||
window_clipboard = "0.3"
|
||||
winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5", features = ["rwh_05"] }
|
||||
window_clipboard = "0.4"
|
||||
winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5" }
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ palette.workspace = true
|
|||
palette.optional = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
# TODO: Use `workspace` dependency once `wgpu` upgrades `raw-window-handle`
|
||||
raw-window-handle = "0.6"
|
||||
raw-window-handle.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
approx = "0.5"
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ impl Pipeline {
|
|||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||
view_formats: &[],
|
||||
},
|
||||
wgpu::util::TextureDataOrder::LayerMajor,
|
||||
&normal_map_data,
|
||||
);
|
||||
|
||||
|
|
@ -122,6 +123,7 @@ impl Pipeline {
|
|||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||
view_formats: &[],
|
||||
},
|
||||
wgpu::util::TextureDataOrder::LayerMajor,
|
||||
&skybox_data,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ use winit::{
|
|||
keyboard::ModifiersState,
|
||||
};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen::JsCast;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
|
@ -59,6 +61,8 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let window = winit::window::Window::new(&event_loop)?;
|
||||
|
||||
let window = Arc::new(window);
|
||||
|
||||
let physical_size = window.inner_size();
|
||||
let mut viewport = Viewport::with_physical_size(
|
||||
Size::new(physical_size.width, physical_size.height),
|
||||
|
|
@ -81,7 +85,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
backends: backend,
|
||||
..Default::default()
|
||||
});
|
||||
let surface = unsafe { instance.create_surface(&window) }?;
|
||||
let surface = instance.create_surface(window.clone())?;
|
||||
|
||||
let (format, (device, queue)) =
|
||||
futures::futures::executor::block_on(async {
|
||||
|
|
@ -115,9 +119,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
features: adapter_features
|
||||
required_features: adapter_features
|
||||
& wgpu::Features::default(),
|
||||
limits: needed_limits,
|
||||
required_limits: needed_limits,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
|
@ -136,6 +140,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
present_mode: wgpu::PresentMode::AutoVsync,
|
||||
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
||||
view_formats: vec![],
|
||||
desired_maximum_frame_latency: 2,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -188,6 +193,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
present_mode: wgpu::PresentMode::AutoVsync,
|
||||
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
||||
view_formats: vec![],
|
||||
desired_maximum_frame_latency: 2,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
pub use futures;
|
||||
pub use iced_core as core;
|
||||
|
||||
mod maybe_send;
|
||||
mod maybe;
|
||||
mod runtime;
|
||||
|
||||
pub mod backend;
|
||||
|
|
@ -25,7 +25,7 @@ pub mod keyboard;
|
|||
pub mod subscription;
|
||||
|
||||
pub use executor::Executor;
|
||||
pub use maybe_send::MaybeSend;
|
||||
pub use maybe::{MaybeSend, MaybeSync};
|
||||
pub use platform::*;
|
||||
pub use runtime::Runtime;
|
||||
pub use subscription::Subscription;
|
||||
|
|
|
|||
35
futures/src/maybe.rs
Normal file
35
futures/src/maybe.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod platform {
|
||||
/// An extension trait that enforces `Send` only on native platforms.
|
||||
///
|
||||
/// Useful for writing cross-platform async code!
|
||||
pub trait MaybeSend: Send {}
|
||||
|
||||
impl<T> MaybeSend for T where T: Send {}
|
||||
|
||||
/// An extension trait that enforces `Sync` only on native platforms.
|
||||
///
|
||||
/// Useful for writing cross-platform async code!
|
||||
pub trait MaybeSync: Sync {}
|
||||
|
||||
impl<T> MaybeSync for T where T: Sync {}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod platform {
|
||||
/// An extension trait that enforces `Send` only on native platforms.
|
||||
///
|
||||
/// Useful for writing cross-platform async code!
|
||||
pub trait MaybeSend {}
|
||||
|
||||
impl<T> MaybeSend for T {}
|
||||
|
||||
/// An extension trait that enforces `Sync` only on native platforms.
|
||||
///
|
||||
/// Useful for writing cross-platform async code!
|
||||
pub trait MaybeSync {}
|
||||
|
||||
impl<T> MaybeSync for T {}
|
||||
}
|
||||
|
||||
pub use platform::{MaybeSend, MaybeSync};
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
mod platform {
|
||||
/// An extension trait that enforces `Send` only on native platforms.
|
||||
///
|
||||
/// Useful to write cross-platform async code!
|
||||
pub trait MaybeSend: Send {}
|
||||
|
||||
impl<T> MaybeSend for T where T: Send {}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod platform {
|
||||
/// An extension trait that enforces `Send` only on native platforms.
|
||||
///
|
||||
/// Useful to write cross-platform async code!
|
||||
pub trait MaybeSend {}
|
||||
|
||||
impl<T> MaybeSend for T {}
|
||||
}
|
||||
|
||||
pub use platform::MaybeSend;
|
||||
|
|
@ -21,6 +21,7 @@ web-colors = []
|
|||
|
||||
[dependencies]
|
||||
iced_core.workspace = true
|
||||
iced_futures.workspace = true
|
||||
|
||||
bitflags.workspace = true
|
||||
bytemuck.workspace = true
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@
|
|||
//! surfaces.
|
||||
use crate::{Error, Viewport};
|
||||
|
||||
use iced_core::Color;
|
||||
use crate::core::Color;
|
||||
use crate::futures::{MaybeSend, MaybeSync};
|
||||
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
||||
use thiserror::Error;
|
||||
|
||||
/// A graphics compositor that can draw to windows.
|
||||
|
|
@ -19,9 +20,9 @@ pub trait Compositor: Sized {
|
|||
type Surface;
|
||||
|
||||
/// Creates a new [`Compositor`].
|
||||
fn new<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn new<W: Window + Clone>(
|
||||
settings: Self::Settings,
|
||||
compatible_window: Option<&W>,
|
||||
compatible_window: W,
|
||||
) -> Result<Self, Error>;
|
||||
|
||||
/// Creates a [`Self::Renderer`] for the [`Compositor`].
|
||||
|
|
@ -30,9 +31,9 @@ pub trait Compositor: Sized {
|
|||
/// Crates a new [`Surface`] for the given window.
|
||||
///
|
||||
/// [`Surface`]: Self::Surface
|
||||
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn create_surface<W: Window + Clone>(
|
||||
&mut self,
|
||||
window: &W,
|
||||
window: W,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Self::Surface;
|
||||
|
|
@ -77,6 +78,20 @@ pub trait Compositor: Sized {
|
|||
) -> Vec<u8>;
|
||||
}
|
||||
|
||||
/// A window that can be used in a [`Compositor`].
|
||||
///
|
||||
/// This is just a convenient super trait of the `raw-window-handle`
|
||||
/// traits.
|
||||
pub trait Window:
|
||||
HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
|
||||
{
|
||||
}
|
||||
|
||||
impl<T> Window for T where
|
||||
T: HasWindowHandle + HasDisplayHandle + MaybeSend + MaybeSync + 'static
|
||||
{
|
||||
}
|
||||
|
||||
/// Result of an unsuccessful call to [`Compositor::present`].
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Error)]
|
||||
pub enum SurfaceError {
|
||||
|
|
|
|||
|
|
@ -50,3 +50,4 @@ pub use transformation::Transformation;
|
|||
pub use viewport::Viewport;
|
||||
|
||||
pub use iced_core as core;
|
||||
pub use iced_futures as futures;
|
||||
|
|
|
|||
|
|
@ -27,5 +27,4 @@ iced_wgpu.workspace = true
|
|||
iced_wgpu.optional = true
|
||||
|
||||
log.workspace = true
|
||||
raw-window-handle.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use crate::core::Color;
|
||||
use crate::graphics::compositor::{Information, SurfaceError};
|
||||
use crate::graphics::compositor::{Information, SurfaceError, Window};
|
||||
use crate::graphics::{Error, Viewport};
|
||||
use crate::{Renderer, Settings};
|
||||
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
use std::env;
|
||||
|
||||
pub enum Compositor<Theme> {
|
||||
|
|
@ -15,7 +14,7 @@ pub enum Compositor<Theme> {
|
|||
pub enum Surface {
|
||||
TinySkia(iced_tiny_skia::window::Surface),
|
||||
#[cfg(feature = "wgpu")]
|
||||
Wgpu(iced_wgpu::window::Surface),
|
||||
Wgpu(iced_wgpu::window::Surface<'static>),
|
||||
}
|
||||
|
||||
impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
||||
|
|
@ -23,9 +22,9 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
|||
type Renderer = Renderer<Theme>;
|
||||
type Surface = Surface;
|
||||
|
||||
fn new<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn new<W: Window + Clone>(
|
||||
settings: Self::Settings,
|
||||
compatible_window: Option<&W>,
|
||||
compatible_window: W,
|
||||
) -> Result<Self, Error> {
|
||||
let candidates =
|
||||
Candidate::list_from_env().unwrap_or(Candidate::default_list());
|
||||
|
|
@ -33,7 +32,7 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
|||
let mut error = Error::GraphicsAdapterNotFound;
|
||||
|
||||
for candidate in candidates {
|
||||
match candidate.build(settings, compatible_window) {
|
||||
match candidate.build(settings, compatible_window.clone()) {
|
||||
Ok(compositor) => return Ok(compositor),
|
||||
Err(new_error) => {
|
||||
error = new_error;
|
||||
|
|
@ -56,9 +55,9 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn create_surface<W: Window + Clone>(
|
||||
&mut self,
|
||||
window: &W,
|
||||
window: W,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Surface {
|
||||
|
|
@ -226,10 +225,10 @@ impl Candidate {
|
|||
)
|
||||
}
|
||||
|
||||
fn build<Theme, W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn build<Theme, W: Window>(
|
||||
self,
|
||||
settings: Settings,
|
||||
_compatible_window: Option<&W>,
|
||||
_compatible_window: W,
|
||||
) -> Result<Compositor<Theme>, Error> {
|
||||
match self {
|
||||
Self::TinySkia => {
|
||||
|
|
@ -238,6 +237,7 @@ impl Candidate {
|
|||
default_font: settings.default_font,
|
||||
default_text_size: settings.default_text_size,
|
||||
},
|
||||
_compatible_window,
|
||||
);
|
||||
|
||||
Ok(Compositor::TinySkia(compositor))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ bytemuck.workspace = true
|
|||
cosmic-text.workspace = true
|
||||
kurbo.workspace = true
|
||||
log.workspace = true
|
||||
raw-window-handle.workspace = true
|
||||
rustc-hash.workspace = true
|
||||
softbuffer.workspace = true
|
||||
tiny-skia.workspace = true
|
||||
|
|
|
|||
|
|
@ -4,20 +4,25 @@ use crate::graphics::damage;
|
|||
use crate::graphics::{Error, Viewport};
|
||||
use crate::{Backend, Primitive, Renderer, Settings};
|
||||
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
use std::collections::VecDeque;
|
||||
use std::marker::PhantomData;
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
pub struct Compositor<Theme> {
|
||||
context: softbuffer::Context<Box<dyn compositor::Window>>,
|
||||
settings: Settings,
|
||||
_theme: PhantomData<Theme>,
|
||||
}
|
||||
|
||||
pub struct Surface {
|
||||
window: softbuffer::GraphicsContext,
|
||||
buffer: Vec<u32>,
|
||||
window: softbuffer::Surface<
|
||||
Box<dyn compositor::Window>,
|
||||
Box<dyn compositor::Window>,
|
||||
>,
|
||||
clip_mask: tiny_skia::Mask,
|
||||
primitives: Option<Vec<Primitive>>,
|
||||
primitive_stack: VecDeque<Vec<Primitive>>,
|
||||
background_color: Color,
|
||||
max_age: u8,
|
||||
}
|
||||
|
||||
impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
||||
|
|
@ -25,11 +30,11 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
|||
type Renderer = Renderer<Theme>;
|
||||
type Surface = Surface;
|
||||
|
||||
fn new<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn new<W: compositor::Window>(
|
||||
settings: Self::Settings,
|
||||
_compatible_window: Option<&W>,
|
||||
compatible_window: W,
|
||||
) -> Result<Self, Error> {
|
||||
Ok(new(settings))
|
||||
Ok(new(settings, compatible_window))
|
||||
}
|
||||
|
||||
fn create_renderer(&self) -> Self::Renderer {
|
||||
|
|
@ -40,37 +45,49 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
|||
)
|
||||
}
|
||||
|
||||
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn create_surface<W: compositor::Window + Clone>(
|
||||
&mut self,
|
||||
window: &W,
|
||||
window: W,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Surface {
|
||||
#[allow(unsafe_code)]
|
||||
let window =
|
||||
unsafe { softbuffer::GraphicsContext::new(window, window) }
|
||||
.expect("Create softbuffer for window");
|
||||
) -> Self::Surface {
|
||||
let window = softbuffer::Surface::new(
|
||||
&self.context,
|
||||
Box::new(window.clone()) as _,
|
||||
)
|
||||
.expect("Create softbuffer surface for window");
|
||||
|
||||
Surface {
|
||||
let mut surface = Surface {
|
||||
window,
|
||||
buffer: vec![0; width as usize * height as usize],
|
||||
clip_mask: tiny_skia::Mask::new(width, height)
|
||||
.expect("Create clip mask"),
|
||||
primitives: None,
|
||||
primitive_stack: VecDeque::new(),
|
||||
background_color: Color::BLACK,
|
||||
}
|
||||
max_age: 0,
|
||||
};
|
||||
|
||||
self.configure_surface(&mut surface, width, height);
|
||||
|
||||
surface
|
||||
}
|
||||
|
||||
fn configure_surface(
|
||||
&mut self,
|
||||
surface: &mut Surface,
|
||||
surface: &mut Self::Surface,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) {
|
||||
surface.buffer.resize((width * height) as usize, 0);
|
||||
surface
|
||||
.window
|
||||
.resize(
|
||||
NonZeroU32::new(width).expect("Non-zero width"),
|
||||
NonZeroU32::new(height).expect("Non-zero height"),
|
||||
)
|
||||
.expect("Resize surface");
|
||||
|
||||
surface.clip_mask =
|
||||
tiny_skia::Mask::new(width, height).expect("Create clip mask");
|
||||
surface.primitives = None;
|
||||
surface.primitive_stack.clear();
|
||||
}
|
||||
|
||||
fn fetch_information(&self) -> Information {
|
||||
|
|
@ -121,8 +138,16 @@ impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new<Theme>(settings: Settings) -> Compositor<Theme> {
|
||||
pub fn new<W: compositor::Window, Theme>(
|
||||
settings: Settings,
|
||||
compatible_window: W,
|
||||
) -> Compositor<Theme> {
|
||||
#[allow(unsafe_code)]
|
||||
let context = softbuffer::Context::new(Box::new(compatible_window) as _)
|
||||
.expect("Create softbuffer context");
|
||||
|
||||
Compositor {
|
||||
context,
|
||||
settings,
|
||||
_theme: PhantomData,
|
||||
}
|
||||
|
|
@ -139,16 +164,25 @@ pub fn present<T: AsRef<str>>(
|
|||
let physical_size = viewport.physical_size();
|
||||
let scale_factor = viewport.scale_factor() as f32;
|
||||
|
||||
let mut pixels = tiny_skia::PixmapMut::from_bytes(
|
||||
bytemuck::cast_slice_mut(&mut surface.buffer),
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
)
|
||||
.expect("Create pixel map");
|
||||
let mut buffer = surface
|
||||
.window
|
||||
.buffer_mut()
|
||||
.map_err(|_| compositor::SurfaceError::Lost)?;
|
||||
|
||||
let damage = surface
|
||||
.primitives
|
||||
.as_deref()
|
||||
let last_primitives = {
|
||||
let age = buffer.age();
|
||||
|
||||
surface.max_age = surface.max_age.max(age);
|
||||
surface.primitive_stack.truncate(surface.max_age as usize);
|
||||
|
||||
if age > 0 {
|
||||
surface.primitive_stack.get(age as usize - 1)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let damage = last_primitives
|
||||
.and_then(|last_primitives| {
|
||||
(surface.background_color == background_color)
|
||||
.then(|| damage::list(last_primitives, primitives))
|
||||
|
|
@ -159,11 +193,18 @@ pub fn present<T: AsRef<str>>(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
surface.primitives = Some(primitives.to_vec());
|
||||
surface.primitive_stack.push_front(primitives.to_vec());
|
||||
surface.background_color = background_color;
|
||||
|
||||
let damage = damage::group(damage, scale_factor, physical_size);
|
||||
|
||||
let mut pixels = tiny_skia::PixmapMut::from_bytes(
|
||||
bytemuck::cast_slice_mut(&mut buffer),
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
)
|
||||
.expect("Create pixel map");
|
||||
|
||||
backend.draw(
|
||||
&mut pixels,
|
||||
&mut surface.clip_mask,
|
||||
|
|
@ -174,13 +215,7 @@ pub fn present<T: AsRef<str>>(
|
|||
overlay,
|
||||
);
|
||||
|
||||
surface.window.set_buffer(
|
||||
&surface.buffer,
|
||||
physical_size.width as u16,
|
||||
physical_size.height as u16,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
buffer.present().map_err(|_| compositor::SurfaceError::Lost)
|
||||
}
|
||||
|
||||
pub fn screenshot<T: AsRef<str>>(
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ glyphon.workspace = true
|
|||
guillotiere.workspace = true
|
||||
log.workspace = true
|
||||
once_cell.workspace = true
|
||||
raw-window-handle.workspace = true
|
||||
wgpu.workspace = true
|
||||
|
||||
lyon.workspace = true
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ use crate::graphics::compositor;
|
|||
use crate::graphics::{Error, Viewport};
|
||||
use crate::{Backend, Primitive, Renderer, Settings};
|
||||
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// A window graphics backend for iced powered by `wgpu`.
|
||||
|
|
@ -26,9 +24,9 @@ impl<Theme> Compositor<Theme> {
|
|||
/// Requests a new [`Compositor`] with the given [`Settings`].
|
||||
///
|
||||
/// Returns `None` if no compatible graphics adapter could be found.
|
||||
pub async fn request<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
pub async fn request<W: compositor::Window>(
|
||||
settings: Settings,
|
||||
compatible_window: Option<&W>,
|
||||
compatible_window: Option<W>,
|
||||
) -> Option<Self> {
|
||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||
backends: settings.internal_backend,
|
||||
|
|
@ -41,14 +39,15 @@ impl<Theme> Compositor<Theme> {
|
|||
if log::max_level() >= log::LevelFilter::Info {
|
||||
let available_adapters: Vec<_> = instance
|
||||
.enumerate_adapters(settings.internal_backend)
|
||||
.map(|adapter| adapter.get_info())
|
||||
.iter()
|
||||
.map(wgpu::Adapter::get_info)
|
||||
.collect();
|
||||
log::info!("Available adapters: {available_adapters:#?}");
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
let compatible_surface = compatible_window
|
||||
.and_then(|window| unsafe { instance.create_surface(window).ok() });
|
||||
.and_then(|window| instance.create_surface(window).ok());
|
||||
|
||||
let adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
|
|
@ -100,14 +99,14 @@ impl<Theme> Compositor<Theme> {
|
|||
|
||||
let (device, queue) =
|
||||
loop {
|
||||
let limits = limits.next()?;
|
||||
let required_limits = limits.next()?;
|
||||
let device = adapter.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: Some(
|
||||
"iced_wgpu::window::compositor device descriptor",
|
||||
),
|
||||
features: wgpu::Features::empty(),
|
||||
limits,
|
||||
required_features: wgpu::Features::empty(),
|
||||
required_limits,
|
||||
},
|
||||
None,
|
||||
).await.ok();
|
||||
|
|
@ -136,13 +135,13 @@ impl<Theme> Compositor<Theme> {
|
|||
|
||||
/// Creates a [`Compositor`] and its [`Backend`] for the given [`Settings`] and
|
||||
/// window.
|
||||
pub fn new<Theme, W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
pub fn new<W: compositor::Window, Theme>(
|
||||
settings: Settings,
|
||||
compatible_window: Option<&W>,
|
||||
compatible_window: W,
|
||||
) -> Result<Compositor<Theme>, Error> {
|
||||
let compositor = futures::executor::block_on(Compositor::request(
|
||||
settings,
|
||||
compatible_window,
|
||||
Some(compatible_window),
|
||||
))
|
||||
.ok_or(Error::GraphicsAdapterNotFound)?;
|
||||
|
||||
|
|
@ -153,7 +152,7 @@ pub fn new<Theme, W: HasRawWindowHandle + HasRawDisplayHandle>(
|
|||
pub fn present<Theme, T: AsRef<str>>(
|
||||
compositor: &mut Compositor<Theme>,
|
||||
backend: &mut Backend,
|
||||
surface: &mut wgpu::Surface,
|
||||
surface: &mut wgpu::Surface<'static>,
|
||||
primitives: &[Primitive],
|
||||
viewport: &Viewport,
|
||||
background_color: Color,
|
||||
|
|
@ -207,11 +206,11 @@ pub fn present<Theme, T: AsRef<str>>(
|
|||
impl<Theme> graphics::Compositor for Compositor<Theme> {
|
||||
type Settings = Settings;
|
||||
type Renderer = Renderer<Theme>;
|
||||
type Surface = wgpu::Surface;
|
||||
type Surface = wgpu::Surface<'static>;
|
||||
|
||||
fn new<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn new<W: compositor::Window>(
|
||||
settings: Self::Settings,
|
||||
compatible_window: Option<&W>,
|
||||
compatible_window: W,
|
||||
) -> Result<Self, Error> {
|
||||
new(settings, compatible_window)
|
||||
}
|
||||
|
|
@ -224,14 +223,15 @@ impl<Theme> graphics::Compositor for Compositor<Theme> {
|
|||
)
|
||||
}
|
||||
|
||||
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
||||
fn create_surface<W: compositor::Window>(
|
||||
&mut self,
|
||||
window: &W,
|
||||
window: W,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> wgpu::Surface {
|
||||
#[allow(unsafe_code)]
|
||||
let mut surface = unsafe { self.instance.create_surface(window) }
|
||||
) -> Self::Surface {
|
||||
let mut surface = self
|
||||
.instance
|
||||
.create_surface(window)
|
||||
.expect("Create surface");
|
||||
|
||||
self.configure_surface(&mut surface, width, height);
|
||||
|
|
@ -255,6 +255,7 @@ impl<Theme> graphics::Compositor for Compositor<Theme> {
|
|||
height,
|
||||
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
||||
view_formats: vec![],
|
||||
desired_maximum_frame_latency: 2,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ use crate::{Clipboard, Error, Proxy, Settings};
|
|||
use futures::channel::mpsc;
|
||||
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// An interactive, native cross-platform application.
|
||||
///
|
||||
|
|
@ -149,9 +150,11 @@ where
|
|||
|
||||
log::debug!("Window builder: {builder:#?}");
|
||||
|
||||
let window = builder
|
||||
.build(&event_loop)
|
||||
.map_err(Error::WindowCreationFailed)?;
|
||||
let window = Arc::new(
|
||||
builder
|
||||
.build(&event_loop)
|
||||
.map_err(Error::WindowCreationFailed)?,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
|
|
@ -183,7 +186,7 @@ where
|
|||
};
|
||||
}
|
||||
|
||||
let compositor = C::new(compositor_settings, Some(&window))?;
|
||||
let compositor = C::new(compositor_settings, window.clone())?;
|
||||
let mut renderer = compositor.create_renderer();
|
||||
|
||||
for font in settings.fonts {
|
||||
|
|
@ -248,7 +251,7 @@ async fn run_instance<A, E, C>(
|
|||
>,
|
||||
mut control_sender: mpsc::UnboundedSender<winit::event_loop::ControlFlow>,
|
||||
init_command: Command<A::Message>,
|
||||
window: winit::window::Window,
|
||||
window: Arc<winit::window::Window>,
|
||||
should_be_visible: bool,
|
||||
exit_on_close_request: bool,
|
||||
) where
|
||||
|
|
@ -268,7 +271,7 @@ async fn run_instance<A, E, C>(
|
|||
let mut clipboard = Clipboard::connect(&window);
|
||||
let mut cache = user_interface::Cache::default();
|
||||
let mut surface = compositor.create_surface(
|
||||
&window,
|
||||
window.clone(),
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ enum State {
|
|||
impl Clipboard {
|
||||
/// Creates a new [`Clipboard`] for the given window.
|
||||
pub fn connect(window: &winit::window::Window) -> Clipboard {
|
||||
let state = window_clipboard::Clipboard::connect(window)
|
||||
#[allow(unsafe_code)]
|
||||
let state = unsafe { window_clipboard::Clipboard::connect(window) }
|
||||
.ok()
|
||||
.map(State::Connected)
|
||||
.unwrap_or(State::Unavailable);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ use crate::{Clipboard, Error, Proxy, Settings};
|
|||
|
||||
use std::collections::HashMap;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
/// An interactive, native, cross-platform, multi-windowed application.
|
||||
|
|
@ -150,9 +151,11 @@ where
|
|||
|
||||
log::info!("Window builder: {:#?}", builder);
|
||||
|
||||
let main_window = builder
|
||||
.build(&event_loop)
|
||||
.map_err(Error::WindowCreationFailed)?;
|
||||
let main_window = Arc::new(
|
||||
builder
|
||||
.build(&event_loop)
|
||||
.map_err(Error::WindowCreationFailed)?,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
|
|
@ -184,7 +187,7 @@ where
|
|||
};
|
||||
}
|
||||
|
||||
let mut compositor = C::new(compositor_settings, Some(&main_window))?;
|
||||
let mut compositor = C::new(compositor_settings, main_window.clone())?;
|
||||
|
||||
let mut window_manager = WindowManager::new();
|
||||
let _ = window_manager.insert(
|
||||
|
|
@ -388,7 +391,7 @@ async fn run_instance<A, E, C>(
|
|||
} => {
|
||||
let window = window_manager.insert(
|
||||
id,
|
||||
window,
|
||||
Arc::new(window),
|
||||
&application,
|
||||
&mut compositor,
|
||||
exit_on_close_request,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use crate::multi_window::{Application, State};
|
|||
use crate::style::application::StyleSheet;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use winit::monitor::MonitorHandle;
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
|
|
@ -34,7 +35,7 @@ where
|
|||
pub fn insert(
|
||||
&mut self,
|
||||
id: Id,
|
||||
window: winit::window::Window,
|
||||
window: Arc<winit::window::Window>,
|
||||
application: &A,
|
||||
compositor: &mut C,
|
||||
exit_on_close_request: bool,
|
||||
|
|
@ -43,7 +44,7 @@ where
|
|||
let viewport_version = state.viewport_version();
|
||||
let physical_size = state.physical_size();
|
||||
let surface = compositor.create_surface(
|
||||
&window,
|
||||
window.clone(),
|
||||
physical_size.width,
|
||||
physical_size.height,
|
||||
);
|
||||
|
|
@ -122,7 +123,7 @@ where
|
|||
C: Compositor<Renderer = A::Renderer>,
|
||||
<A::Renderer as crate::core::Renderer>::Theme: StyleSheet,
|
||||
{
|
||||
pub raw: winit::window::Window,
|
||||
pub raw: Arc<winit::window::Window>,
|
||||
pub state: State<A>,
|
||||
pub viewport_version: u64,
|
||||
pub exit_on_close_request: bool,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue