Remove Compositor window generic
And update `glyphon` and `window_clipboard`
This commit is contained in:
parent
7289b6091b
commit
8bf2386972
18 changed files with 126 additions and 114 deletions
10
Cargo.toml
10
Cargo.toml
|
|
@ -128,10 +128,7 @@ bytemuck = { version = "1.0", features = ["derive"] }
|
||||||
cosmic-text = "0.10"
|
cosmic-text = "0.10"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
glam = "0.24"
|
glam = "0.24"
|
||||||
# glyphon = "0.4"
|
glyphon = "0.5"
|
||||||
# TODO update for wgpu 0.19
|
|
||||||
# https://github.com/grovesNL/glyphon/pull/80
|
|
||||||
glyphon = { git = "https://github.com/EggShark/glyphon" }
|
|
||||||
guillotiere = "0.6"
|
guillotiere = "0.6"
|
||||||
half = "2.2"
|
half = "2.2"
|
||||||
image = "0.24"
|
image = "0.24"
|
||||||
|
|
@ -165,6 +162,5 @@ web-sys = "0.3"
|
||||||
web-time = "0.2"
|
web-time = "0.2"
|
||||||
wgpu = "0.19"
|
wgpu = "0.19"
|
||||||
winapi = "0.3"
|
winapi = "0.3"
|
||||||
# window_clipboard = "0.3"
|
window_clipboard = "0.4"
|
||||||
window_clipboard = { git = "https://github.com/ids1024/window_clipboard", branch = "raw-window-handle-0.6" }
|
winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5" }
|
||||||
winit = { git = "https://github.com/iced-rs/winit.git", rev = "b91e39ece2c0d378c3b80da7f3ab50e17bb798a5", features = ["rwh_06"] }
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ impl Pipeline {
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
view_formats: &[],
|
view_formats: &[],
|
||||||
},
|
},
|
||||||
|
wgpu::util::TextureDataOrder::LayerMajor,
|
||||||
&normal_map_data,
|
&normal_map_data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -122,6 +123,7 @@ impl Pipeline {
|
||||||
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
usage: wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
view_formats: &[],
|
view_formats: &[],
|
||||||
},
|
},
|
||||||
|
wgpu::util::TextureDataOrder::LayerMajor,
|
||||||
&skybox_data,
|
&skybox_data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ use winit::{
|
||||||
keyboard::ModifiersState,
|
keyboard::ModifiersState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
|
@ -59,6 +61,8 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let window = winit::window::Window::new(&event_loop)?;
|
let window = winit::window::Window::new(&event_loop)?;
|
||||||
|
|
||||||
|
let window = Arc::new(window);
|
||||||
|
|
||||||
let physical_size = window.inner_size();
|
let physical_size = window.inner_size();
|
||||||
let mut viewport = Viewport::with_physical_size(
|
let mut viewport = Viewport::with_physical_size(
|
||||||
Size::new(physical_size.width, physical_size.height),
|
Size::new(physical_size.width, physical_size.height),
|
||||||
|
|
@ -81,7 +85,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
backends: backend,
|
backends: backend,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
let surface = unsafe { instance.create_surface(&window) }?;
|
let surface = instance.create_surface(window.clone())?;
|
||||||
|
|
||||||
let (format, (device, queue)) =
|
let (format, (device, queue)) =
|
||||||
futures::futures::executor::block_on(async {
|
futures::futures::executor::block_on(async {
|
||||||
|
|
@ -115,9 +119,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.request_device(
|
.request_device(
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
features: adapter_features
|
required_features: adapter_features
|
||||||
& wgpu::Features::default(),
|
& wgpu::Features::default(),
|
||||||
limits: needed_limits,
|
required_limits: needed_limits,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
@ -136,6 +140,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
present_mode: wgpu::PresentMode::AutoVsync,
|
present_mode: wgpu::PresentMode::AutoVsync,
|
||||||
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
||||||
view_formats: vec![],
|
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,
|
present_mode: wgpu::PresentMode::AutoVsync,
|
||||||
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
alpha_mode: wgpu::CompositeAlphaMode::Auto,
|
||||||
view_formats: vec![],
|
view_formats: vec![],
|
||||||
|
desired_maximum_frame_latency: 2,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
pub use futures;
|
pub use futures;
|
||||||
pub use iced_core as core;
|
pub use iced_core as core;
|
||||||
|
|
||||||
mod maybe_send;
|
mod maybe;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
|
|
@ -25,7 +25,7 @@ pub mod keyboard;
|
||||||
pub mod subscription;
|
pub mod subscription;
|
||||||
|
|
||||||
pub use executor::Executor;
|
pub use executor::Executor;
|
||||||
pub use maybe_send::MaybeSend;
|
pub use maybe::{MaybeSend, MaybeSync};
|
||||||
pub use platform::*;
|
pub use platform::*;
|
||||||
pub use runtime::Runtime;
|
pub use runtime::Runtime;
|
||||||
pub use subscription::Subscription;
|
pub use subscription::Subscription;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,13 @@ mod platform {
|
||||||
pub trait MaybeSend: Send {}
|
pub trait MaybeSend: Send {}
|
||||||
|
|
||||||
impl<T> MaybeSend for T where T: Send {}
|
impl<T> MaybeSend for T where T: Send {}
|
||||||
|
|
||||||
|
/// An extension trait that enforces `Sync` only on native platforms.
|
||||||
|
///
|
||||||
|
/// Useful to write cross-platform async code!
|
||||||
|
pub trait MaybeSync: Sync {}
|
||||||
|
|
||||||
|
impl<T> MaybeSync for T where T: Sync {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
|
@ -16,6 +23,13 @@ mod platform {
|
||||||
pub trait MaybeSend {}
|
pub trait MaybeSend {}
|
||||||
|
|
||||||
impl<T> MaybeSend for T {}
|
impl<T> MaybeSend for T {}
|
||||||
|
|
||||||
|
/// An extension trait that enforces `Send` only on native platforms.
|
||||||
|
///
|
||||||
|
/// Useful to write cross-platform async code!
|
||||||
|
pub trait MaybeSync {}
|
||||||
|
|
||||||
|
impl<T> MaybeSync for T {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use platform::MaybeSend;
|
pub use platform::{MaybeSend, MaybeSync};
|
||||||
|
|
@ -21,6 +21,7 @@ web-colors = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced_core.workspace = true
|
iced_core.workspace = true
|
||||||
|
iced_futures.workspace = true
|
||||||
|
|
||||||
bitflags.workspace = true
|
bitflags.workspace = true
|
||||||
bytemuck.workspace = true
|
bytemuck.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@
|
||||||
//! surfaces.
|
//! surfaces.
|
||||||
use crate::{Error, Viewport};
|
use crate::{Error, Viewport};
|
||||||
|
|
||||||
use iced_core::Color;
|
use crate::core::Color;
|
||||||
|
use crate::futures::{MaybeSend, MaybeSync};
|
||||||
|
|
||||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// A graphics compositor that can draw to windows.
|
/// A graphics compositor that can draw to windows.
|
||||||
pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized {
|
pub trait Compositor: Sized {
|
||||||
/// The settings of the backend.
|
/// The settings of the backend.
|
||||||
type Settings: Default;
|
type Settings: Default;
|
||||||
|
|
||||||
|
|
@ -19,7 +20,7 @@ pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized {
|
||||||
type Surface;
|
type Surface;
|
||||||
|
|
||||||
/// Creates a new [`Compositor`].
|
/// Creates a new [`Compositor`].
|
||||||
fn new(
|
fn new<W: Window + Clone>(
|
||||||
settings: Self::Settings,
|
settings: Self::Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
) -> Result<Self, Error>;
|
) -> Result<Self, Error>;
|
||||||
|
|
@ -30,7 +31,7 @@ pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized {
|
||||||
/// Crates a new [`Surface`] for the given window.
|
/// Crates a new [`Surface`] for the given window.
|
||||||
///
|
///
|
||||||
/// [`Surface`]: Self::Surface
|
/// [`Surface`]: Self::Surface
|
||||||
fn create_surface(
|
fn create_surface<W: Window + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
window: W,
|
window: W,
|
||||||
width: u32,
|
width: u32,
|
||||||
|
|
@ -77,6 +78,20 @@ pub trait Compositor<W: HasWindowHandle + HasDisplayHandle>: Sized {
|
||||||
) -> Vec<u8>;
|
) -> 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`].
|
/// Result of an unsuccessful call to [`Compositor::present`].
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Error)]
|
#[derive(Clone, PartialEq, Eq, Debug, Error)]
|
||||||
pub enum SurfaceError {
|
pub enum SurfaceError {
|
||||||
|
|
|
||||||
|
|
@ -50,3 +50,4 @@ pub use transformation::Transformation;
|
||||||
pub use viewport::Viewport;
|
pub use viewport::Viewport;
|
||||||
|
|
||||||
pub use iced_core as core;
|
pub use iced_core as core;
|
||||||
|
pub use iced_futures as futures;
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,4 @@ iced_wgpu.workspace = true
|
||||||
iced_wgpu.optional = true
|
iced_wgpu.optional = true
|
||||||
|
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
raw-window-handle.workspace = true
|
|
||||||
thiserror.workspace = true
|
thiserror.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,28 @@
|
||||||
use crate::core::Color;
|
use crate::core::Color;
|
||||||
use crate::graphics::compositor::{Information, SurfaceError};
|
use crate::graphics::compositor::{Information, SurfaceError, Window};
|
||||||
use crate::graphics::{Error, Viewport};
|
use crate::graphics::{Error, Viewport};
|
||||||
use crate::{Renderer, Settings};
|
use crate::{Renderer, Settings};
|
||||||
|
|
||||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
pub enum Compositor<W: HasWindowHandle + HasDisplayHandle, Theme> {
|
pub enum Compositor<Theme> {
|
||||||
TinySkia(iced_tiny_skia::window::Compositor<W, Theme>),
|
TinySkia(iced_tiny_skia::window::Compositor<Theme>),
|
||||||
#[cfg(feature = "wgpu")]
|
#[cfg(feature = "wgpu")]
|
||||||
Wgpu(iced_wgpu::window::Compositor<W, Theme>),
|
Wgpu(iced_wgpu::window::Compositor<Theme>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Surface<W: HasWindowHandle + HasDisplayHandle> {
|
pub enum Surface {
|
||||||
TinySkia(iced_tiny_skia::window::Surface<W>),
|
TinySkia(iced_tiny_skia::window::Surface),
|
||||||
#[cfg(feature = "wgpu")]
|
#[cfg(feature = "wgpu")]
|
||||||
Wgpu(iced_wgpu::window::Surface<'static>),
|
Wgpu(iced_wgpu::window::Surface<'static>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Clone bound
|
impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
||||||
// XXX Send/Sync?
|
|
||||||
// 'static?
|
|
||||||
impl<
|
|
||||||
W: Clone + Send + Sync + HasWindowHandle + HasDisplayHandle + 'static,
|
|
||||||
Theme,
|
|
||||||
> crate::graphics::Compositor<W> for Compositor<W, Theme>
|
|
||||||
{
|
|
||||||
type Settings = Settings;
|
type Settings = Settings;
|
||||||
type Renderer = Renderer<Theme>;
|
type Renderer = Renderer<Theme>;
|
||||||
type Surface = Surface<W>;
|
type Surface = Surface;
|
||||||
|
|
||||||
fn new(
|
fn new<W: Window + Clone>(
|
||||||
settings: Self::Settings,
|
settings: Self::Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
|
@ -63,12 +55,12 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_surface(
|
fn create_surface<W: Window + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
window: W,
|
window: W,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
) -> Surface<W> {
|
) -> Surface {
|
||||||
match self {
|
match self {
|
||||||
Self::TinySkia(compositor) => Surface::TinySkia(
|
Self::TinySkia(compositor) => Surface::TinySkia(
|
||||||
compositor.create_surface(window, width, height),
|
compositor.create_surface(window, width, height),
|
||||||
|
|
@ -82,7 +74,7 @@ impl<
|
||||||
|
|
||||||
fn configure_surface(
|
fn configure_surface(
|
||||||
&mut self,
|
&mut self,
|
||||||
surface: &mut Surface<W>,
|
surface: &mut Surface,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
) {
|
) {
|
||||||
|
|
@ -233,11 +225,11 @@ impl Candidate {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build<Theme, W: HasWindowHandle + HasDisplayHandle + Send + Sync>(
|
fn build<Theme, W: Window>(
|
||||||
self,
|
self,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
_compatible_window: Option<W>,
|
_compatible_window: Option<W>,
|
||||||
) -> Result<Compositor<W, Theme>, Error> {
|
) -> Result<Compositor<Theme>, Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::TinySkia => {
|
Self::TinySkia => {
|
||||||
let compositor = iced_tiny_skia::window::compositor::new(
|
let compositor = iced_tiny_skia::window::compositor::new(
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
//! Build interactive cross-platform applications.
|
//! Build interactive cross-platform applications.
|
||||||
use crate::{Command, Element, Executor, Settings, Subscription};
|
use crate::{Command, Element, Executor, Settings, Subscription};
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub use crate::style::application::{Appearance, StyleSheet};
|
pub use crate::style::application::{Appearance, StyleSheet};
|
||||||
|
|
||||||
/// An interactive cross-platform application.
|
/// An interactive cross-platform application.
|
||||||
|
|
@ -210,10 +208,7 @@ pub trait Application: Sized {
|
||||||
Ok(crate::shell::application::run::<
|
Ok(crate::shell::application::run::<
|
||||||
Instance<Self>,
|
Instance<Self>,
|
||||||
Self::Executor,
|
Self::Executor,
|
||||||
crate::renderer::Compositor<
|
crate::renderer::Compositor<Self::Theme>,
|
||||||
Arc<winit::window::Window>,
|
|
||||||
Self::Theme,
|
|
||||||
>,
|
|
||||||
>(settings.into(), renderer_settings)?)
|
>(settings.into(), renderer_settings)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ bytemuck.workspace = true
|
||||||
cosmic-text.workspace = true
|
cosmic-text.workspace = true
|
||||||
kurbo.workspace = true
|
kurbo.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
raw-window-handle.workspace = true
|
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
softbuffer.workspace = true
|
softbuffer.workspace = true
|
||||||
tiny-skia.workspace = true
|
tiny-skia.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -4,34 +4,33 @@ use crate::graphics::damage;
|
||||||
use crate::graphics::{Error, Viewport};
|
use crate::graphics::{Error, Viewport};
|
||||||
use crate::{Backend, Primitive, Renderer, Settings};
|
use crate::{Backend, Primitive, Renderer, Settings};
|
||||||
|
|
||||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
pub struct Compositor<W: HasDisplayHandle + HasWindowHandle, Theme> {
|
pub struct Compositor<Theme> {
|
||||||
context: Option<softbuffer::Context<W>>,
|
context: Option<softbuffer::Context<Box<dyn compositor::Window>>>,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
_theme: PhantomData<Theme>,
|
_theme: PhantomData<Theme>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Surface<W: HasDisplayHandle + HasWindowHandle> {
|
pub struct Surface {
|
||||||
window: softbuffer::Surface<W, W>,
|
window: softbuffer::Surface<
|
||||||
|
Box<dyn compositor::Window>,
|
||||||
|
Box<dyn compositor::Window>,
|
||||||
|
>,
|
||||||
clip_mask: tiny_skia::Mask,
|
clip_mask: tiny_skia::Mask,
|
||||||
// Primitives of existing buffers, by decreasing age
|
// Primitives of existing buffers, by decreasing age
|
||||||
primitives: VecDeque<Vec<Primitive>>,
|
primitives: VecDeque<Vec<Primitive>>,
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX avoid clone bound?
|
impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
||||||
impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
|
|
||||||
crate::graphics::Compositor<W> for Compositor<W, Theme>
|
|
||||||
{
|
|
||||||
type Settings = Settings;
|
type Settings = Settings;
|
||||||
type Renderer = Renderer<Theme>;
|
type Renderer = Renderer<Theme>;
|
||||||
type Surface = Surface<W>;
|
type Surface = Surface;
|
||||||
|
|
||||||
fn new(
|
fn new<W: compositor::Window>(
|
||||||
settings: Self::Settings,
|
settings: Self::Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
|
@ -46,19 +45,21 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_surface(
|
fn create_surface<W: compositor::Window + Clone>(
|
||||||
&mut self,
|
&mut self,
|
||||||
window: W,
|
window: W,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
) -> Surface<W> {
|
) -> Surface {
|
||||||
let window = if let Some(context) = self.context.as_ref() {
|
let window = if let Some(context) = self.context.as_ref() {
|
||||||
softbuffer::Surface::new(context, window)
|
softbuffer::Surface::new(context, Box::new(window.clone()) as _)
|
||||||
.expect("Create softbuffer surface for window")
|
.expect("Create softbuffer surface for window")
|
||||||
} else {
|
} else {
|
||||||
let context = softbuffer::Context::new(window.clone())
|
let context =
|
||||||
.expect("Create softbuffer context for window");
|
softbuffer::Context::new(Box::new(window.clone()) as _)
|
||||||
softbuffer::Surface::new(&context, window)
|
.expect("Create softbuffer context for window");
|
||||||
|
|
||||||
|
softbuffer::Surface::new(&context, Box::new(window.clone()) as _)
|
||||||
.expect("Create softbuffer surface for window")
|
.expect("Create softbuffer surface for window")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -73,7 +74,7 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
|
||||||
|
|
||||||
fn configure_surface(
|
fn configure_surface(
|
||||||
&mut self,
|
&mut self,
|
||||||
surface: &mut Surface<W>,
|
surface: &mut Surface,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
) {
|
) {
|
||||||
|
|
@ -92,7 +93,7 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
|
||||||
fn present<T: AsRef<str>>(
|
fn present<T: AsRef<str>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut Self::Renderer,
|
renderer: &mut Self::Renderer,
|
||||||
surface: &mut Surface<W>,
|
surface: &mut Surface,
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
overlay: &[T],
|
overlay: &[T],
|
||||||
|
|
@ -130,13 +131,14 @@ impl<W: HasDisplayHandle + HasWindowHandle + Clone, Theme>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<W: HasWindowHandle + HasDisplayHandle, Theme>(
|
pub fn new<W: compositor::Window, Theme>(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
) -> Compositor<W, Theme> {
|
) -> Compositor<Theme> {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
let context =
|
let context = compatible_window
|
||||||
compatible_window.and_then(|w| softbuffer::Context::new(w).ok());
|
.and_then(|w| softbuffer::Context::new(Box::new(w) as _).ok());
|
||||||
|
|
||||||
Compositor {
|
Compositor {
|
||||||
context,
|
context,
|
||||||
settings,
|
settings,
|
||||||
|
|
@ -144,9 +146,9 @@ pub fn new<W: HasWindowHandle + HasDisplayHandle, Theme>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn present<W: HasDisplayHandle + HasWindowHandle, T: AsRef<str>>(
|
pub fn present<T: AsRef<str>>(
|
||||||
backend: &mut Backend,
|
backend: &mut Backend,
|
||||||
surface: &mut Surface<W>,
|
surface: &mut Surface,
|
||||||
primitives: &[Primitive],
|
primitives: &[Primitive],
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
background_color: Color,
|
background_color: Color,
|
||||||
|
|
@ -218,8 +220,8 @@ pub fn present<W: HasDisplayHandle + HasWindowHandle, T: AsRef<str>>(
|
||||||
buffer.present().map_err(|_| compositor::SurfaceError::Lost)
|
buffer.present().map_err(|_| compositor::SurfaceError::Lost)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn screenshot<W: HasDisplayHandle + HasWindowHandle, T: AsRef<str>>(
|
pub fn screenshot<T: AsRef<str>>(
|
||||||
surface: &mut Surface<W>,
|
surface: &mut Surface,
|
||||||
backend: &mut Backend,
|
backend: &mut Backend,
|
||||||
primitives: &[Primitive],
|
primitives: &[Primitive],
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ glyphon.workspace = true
|
||||||
guillotiere.workspace = true
|
guillotiere.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
once_cell.workspace = true
|
once_cell.workspace = true
|
||||||
raw-window-handle.workspace = true
|
|
||||||
wgpu.workspace = true
|
wgpu.workspace = true
|
||||||
|
|
||||||
lyon.workspace = true
|
lyon.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,11 @@ use crate::graphics::compositor;
|
||||||
use crate::graphics::{Error, Viewport};
|
use crate::graphics::{Error, Viewport};
|
||||||
use crate::{Backend, Primitive, Renderer, Settings};
|
use crate::{Backend, Primitive, Renderer, Settings};
|
||||||
|
|
||||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
/// A window graphics backend for iced powered by `wgpu`.
|
/// A window graphics backend for iced powered by `wgpu`.
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct Compositor<W, Theme> {
|
pub struct Compositor<Theme> {
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
instance: wgpu::Instance,
|
instance: wgpu::Instance,
|
||||||
adapter: wgpu::Adapter,
|
adapter: wgpu::Adapter,
|
||||||
|
|
@ -20,16 +18,13 @@ pub struct Compositor<W, Theme> {
|
||||||
queue: wgpu::Queue,
|
queue: wgpu::Queue,
|
||||||
format: wgpu::TextureFormat,
|
format: wgpu::TextureFormat,
|
||||||
theme: PhantomData<Theme>,
|
theme: PhantomData<Theme>,
|
||||||
w: PhantomData<W>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme>
|
impl<Theme> Compositor<Theme> {
|
||||||
Compositor<W, Theme>
|
|
||||||
{
|
|
||||||
/// Requests a new [`Compositor`] with the given [`Settings`].
|
/// Requests a new [`Compositor`] with the given [`Settings`].
|
||||||
///
|
///
|
||||||
/// Returns `None` if no compatible graphics adapter could be found.
|
/// Returns `None` if no compatible graphics adapter could be found.
|
||||||
pub async fn request(
|
pub async fn request<W: compositor::Window>(
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
|
|
@ -45,7 +40,7 @@ impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme>
|
||||||
let available_adapters: Vec<_> = instance
|
let available_adapters: Vec<_> = instance
|
||||||
.enumerate_adapters(settings.internal_backend)
|
.enumerate_adapters(settings.internal_backend)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|adapter| adapter.get_info())
|
.map(wgpu::Adapter::get_info)
|
||||||
.collect();
|
.collect();
|
||||||
log::info!("Available adapters: {available_adapters:#?}");
|
log::info!("Available adapters: {available_adapters:#?}");
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +124,6 @@ impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme>
|
||||||
queue,
|
queue,
|
||||||
format,
|
format,
|
||||||
theme: PhantomData,
|
theme: PhantomData,
|
||||||
w: PhantomData,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,13 +135,10 @@ impl<W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync, Theme>
|
||||||
|
|
||||||
/// Creates a [`Compositor`] and its [`Backend`] for the given [`Settings`] and
|
/// Creates a [`Compositor`] and its [`Backend`] for the given [`Settings`] and
|
||||||
/// window.
|
/// window.
|
||||||
pub fn new<
|
pub fn new<W: compositor::Window, Theme>(
|
||||||
Theme,
|
|
||||||
W: HasWindowHandle + HasDisplayHandle + wgpu::WasmNotSendSync,
|
|
||||||
>(
|
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
) -> Result<Compositor<W, Theme>, Error> {
|
) -> Result<Compositor<Theme>, Error> {
|
||||||
let compositor = futures::executor::block_on(Compositor::request(
|
let compositor = futures::executor::block_on(Compositor::request(
|
||||||
settings,
|
settings,
|
||||||
compatible_window,
|
compatible_window,
|
||||||
|
|
@ -158,8 +149,8 @@ pub fn new<
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Presents the given primitives with the given [`Compositor`] and [`Backend`].
|
/// Presents the given primitives with the given [`Compositor`] and [`Backend`].
|
||||||
pub fn present<W, Theme, T: AsRef<str>>(
|
pub fn present<Theme, T: AsRef<str>>(
|
||||||
compositor: &mut Compositor<W, Theme>,
|
compositor: &mut Compositor<Theme>,
|
||||||
backend: &mut Backend,
|
backend: &mut Backend,
|
||||||
surface: &mut wgpu::Surface<'static>,
|
surface: &mut wgpu::Surface<'static>,
|
||||||
primitives: &[Primitive],
|
primitives: &[Primitive],
|
||||||
|
|
@ -212,17 +203,12 @@ pub fn present<W, Theme, T: AsRef<str>>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<Theme> graphics::Compositor for Compositor<Theme> {
|
||||||
W: HasDisplayHandle + HasWindowHandle + wgpu::WasmNotSendSync + 'static,
|
|
||||||
Theme,
|
|
||||||
> graphics::Compositor<W> for Compositor<W, Theme>
|
|
||||||
{
|
|
||||||
type Settings = Settings;
|
type Settings = Settings;
|
||||||
type Renderer = Renderer<Theme>;
|
type Renderer = Renderer<Theme>;
|
||||||
// XXX generic instead of 'static
|
|
||||||
type Surface = wgpu::Surface<'static>;
|
type Surface = wgpu::Surface<'static>;
|
||||||
|
|
||||||
fn new(
|
fn new<W: compositor::Window>(
|
||||||
settings: Self::Settings,
|
settings: Self::Settings,
|
||||||
compatible_window: Option<W>,
|
compatible_window: Option<W>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
|
@ -237,7 +223,7 @@ impl<
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_surface(
|
fn create_surface<W: compositor::Window>(
|
||||||
&mut self,
|
&mut self,
|
||||||
window: W,
|
window: W,
|
||||||
width: u32,
|
width: u32,
|
||||||
|
|
@ -328,8 +314,8 @@ impl<
|
||||||
/// Renders the current surface to an offscreen buffer.
|
/// Renders the current surface to an offscreen buffer.
|
||||||
///
|
///
|
||||||
/// Returns RGBA bytes of the texture data.
|
/// Returns RGBA bytes of the texture data.
|
||||||
pub fn screenshot<W, Theme, T: AsRef<str>>(
|
pub fn screenshot<Theme, T: AsRef<str>>(
|
||||||
compositor: &Compositor<W, Theme>,
|
compositor: &Compositor<Theme>,
|
||||||
backend: &mut Backend,
|
backend: &mut Backend,
|
||||||
primitives: &[Primitive],
|
primitives: &[Primitive],
|
||||||
viewport: &Viewport,
|
viewport: &Viewport,
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ pub fn run<A, E, C>(
|
||||||
where
|
where
|
||||||
A: Application + 'static,
|
A: Application + 'static,
|
||||||
E: Executor + 'static,
|
E: Executor + 'static,
|
||||||
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static,
|
C: Compositor<Renderer = A::Renderer> + 'static,
|
||||||
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
||||||
{
|
{
|
||||||
use futures::task;
|
use futures::task;
|
||||||
|
|
@ -258,7 +258,7 @@ async fn run_instance<A, E, C>(
|
||||||
) where
|
) where
|
||||||
A: Application + 'static,
|
A: Application + 'static,
|
||||||
E: Executor + 'static,
|
E: Executor + 'static,
|
||||||
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static,
|
C: Compositor<Renderer = A::Renderer> + 'static,
|
||||||
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
||||||
{
|
{
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
|
|
@ -612,7 +612,7 @@ pub fn update<A: Application, C, E: Executor>(
|
||||||
messages: &mut Vec<A::Message>,
|
messages: &mut Vec<A::Message>,
|
||||||
window: &winit::window::Window,
|
window: &winit::window::Window,
|
||||||
) where
|
) where
|
||||||
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static,
|
C: Compositor<Renderer = A::Renderer> + 'static,
|
||||||
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
||||||
{
|
{
|
||||||
for message in messages.drain(..) {
|
for message in messages.drain(..) {
|
||||||
|
|
@ -663,7 +663,7 @@ pub fn run_command<A, C, E>(
|
||||||
) where
|
) where
|
||||||
A: Application,
|
A: Application,
|
||||||
E: Executor,
|
E: Executor,
|
||||||
C: Compositor<Arc<winit::window::Window>, Renderer = A::Renderer> + 'static,
|
C: Compositor<Renderer = A::Renderer> + 'static,
|
||||||
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
<A::Renderer as core::Renderer>::Theme: StyleSheet,
|
||||||
{
|
{
|
||||||
use crate::runtime::command;
|
use crate::runtime::command;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ use crate::{Clipboard, Error, Proxy, Settings};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
/// An interactive, native, cross-platform, multi-windowed application.
|
/// An interactive, native, cross-platform, multi-windowed application.
|
||||||
|
|
@ -150,9 +151,11 @@ where
|
||||||
|
|
||||||
log::info!("Window builder: {:#?}", builder);
|
log::info!("Window builder: {:#?}", builder);
|
||||||
|
|
||||||
let main_window = builder
|
let main_window = Arc::new(
|
||||||
.build(&event_loop)
|
builder
|
||||||
.map_err(Error::WindowCreationFailed)?;
|
.build(&event_loop)
|
||||||
|
.map_err(Error::WindowCreationFailed)?,
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
|
|
@ -184,7 +187,8 @@ where
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut compositor = C::new(compositor_settings, Some(&main_window))?;
|
let mut compositor =
|
||||||
|
C::new(compositor_settings, Some(main_window.clone()))?;
|
||||||
|
|
||||||
let mut window_manager = WindowManager::new();
|
let mut window_manager = WindowManager::new();
|
||||||
let _ = window_manager.insert(
|
let _ = window_manager.insert(
|
||||||
|
|
@ -388,7 +392,7 @@ async fn run_instance<A, E, C>(
|
||||||
} => {
|
} => {
|
||||||
let window = window_manager.insert(
|
let window = window_manager.insert(
|
||||||
id,
|
id,
|
||||||
window,
|
Arc::new(window),
|
||||||
&application,
|
&application,
|
||||||
&mut compositor,
|
&mut compositor,
|
||||||
exit_on_close_request,
|
exit_on_close_request,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use crate::multi_window::{Application, State};
|
||||||
use crate::style::application::StyleSheet;
|
use crate::style::application::StyleSheet;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::sync::Arc;
|
||||||
use winit::monitor::MonitorHandle;
|
use winit::monitor::MonitorHandle;
|
||||||
|
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
|
|
@ -34,7 +35,7 @@ where
|
||||||
pub fn insert(
|
pub fn insert(
|
||||||
&mut self,
|
&mut self,
|
||||||
id: Id,
|
id: Id,
|
||||||
window: winit::window::Window,
|
window: Arc<winit::window::Window>,
|
||||||
application: &A,
|
application: &A,
|
||||||
compositor: &mut C,
|
compositor: &mut C,
|
||||||
exit_on_close_request: bool,
|
exit_on_close_request: bool,
|
||||||
|
|
@ -43,7 +44,7 @@ where
|
||||||
let viewport_version = state.viewport_version();
|
let viewport_version = state.viewport_version();
|
||||||
let physical_size = state.physical_size();
|
let physical_size = state.physical_size();
|
||||||
let surface = compositor.create_surface(
|
let surface = compositor.create_surface(
|
||||||
&window,
|
window.clone(),
|
||||||
physical_size.width,
|
physical_size.width,
|
||||||
physical_size.height,
|
physical_size.height,
|
||||||
);
|
);
|
||||||
|
|
@ -122,7 +123,7 @@ where
|
||||||
C: Compositor<Renderer = A::Renderer>,
|
C: Compositor<Renderer = A::Renderer>,
|
||||||
<A::Renderer as crate::core::Renderer>::Theme: StyleSheet,
|
<A::Renderer as crate::core::Renderer>::Theme: StyleSheet,
|
||||||
{
|
{
|
||||||
pub raw: winit::window::Window,
|
pub raw: Arc<winit::window::Window>,
|
||||||
pub state: State<A>,
|
pub state: State<A>,
|
||||||
pub viewport_version: u64,
|
pub viewport_version: u64,
|
||||||
pub exit_on_close_request: bool,
|
pub exit_on_close_request: bool,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue