summaryrefslogtreecommitdiffstats
path: root/wgpu/src/window
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu/src/window')
-rw-r--r--wgpu/src/window/compositor.rs158
1 files changed, 94 insertions, 64 deletions
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 6feb795b..a36d2a87 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -1,22 +1,27 @@
use crate::{Backend, Color, Error, Renderer, Settings, Viewport};
-use futures::task::SpawnExt;
+use futures::stream::{self, StreamExt};
+
+use iced_graphics::compositor;
use iced_native::futures;
use raw_window_handle::HasRawWindowHandle;
+use std::marker::PhantomData;
+
/// A window graphics backend for iced powered by `wgpu`.
#[allow(missing_debug_implementations)]
-pub struct Compositor {
+pub struct Compositor<Theme> {
settings: Settings,
instance: wgpu::Instance,
+ adapter: wgpu::Adapter,
device: wgpu::Device,
queue: wgpu::Queue,
staging_belt: wgpu::util::StagingBelt,
- local_pool: futures::executor::LocalPool,
format: wgpu::TextureFormat,
+ theme: PhantomData<Theme>,
}
-impl Compositor {
+impl<Theme> Compositor<Theme> {
const CHUNK_SIZE: u64 = 10 * 1024;
/// Requests a new [`Compositor`] with the given [`Settings`].
@@ -28,6 +33,17 @@ impl Compositor {
) -> Option<Self> {
let instance = wgpu::Instance::new(settings.internal_backend);
+ log::info!("{:#?}", settings);
+
+ #[cfg(not(target_arch = "wasm32"))]
+ if log::max_level() >= log::LevelFilter::Info {
+ let available_adapters: Vec<_> = instance
+ .enumerate_adapters(settings.internal_backend)
+ .map(|adapter| adapter.get_info())
+ .collect();
+ log::info!("Available adapters: {:#?}", available_adapters);
+ }
+
#[allow(unsafe_code)]
let compatible_surface = compatible_window
.map(|window| unsafe { instance.create_surface(window) });
@@ -44,45 +60,55 @@ impl Compositor {
})
.await?;
- let format = compatible_surface
- .as_ref()
- .and_then(|surface| surface.get_preferred_format(&adapter))?;
+ log::info!("Selected: {:#?}", adapter.get_info());
+
+ let format = compatible_surface.as_ref().and_then(|surface| {
+ surface.get_supported_formats(&adapter).first().copied()
+ })?;
+
+ log::info!("Selected format: {:?}", format);
#[cfg(target_arch = "wasm32")]
- let limits = wgpu::Limits::downlevel_webgl2_defaults()
- .using_resolution(adapter.limits());
+ let limits = [wgpu::Limits::downlevel_webgl2_defaults()
+ .using_resolution(adapter.limits())];
#[cfg(not(target_arch = "wasm32"))]
- let limits = wgpu::Limits::default();
-
- let (device, queue) = adapter
- .request_device(
- &wgpu::DeviceDescriptor {
- label: Some(
- "iced_wgpu::window::compositor device descriptor",
- ),
- features: wgpu::Features::empty(),
- limits: wgpu::Limits {
- max_bind_groups: 2,
- ..limits
+ let limits =
+ [wgpu::Limits::default(), wgpu::Limits::downlevel_defaults()];
+
+ let limits = limits.into_iter().map(|limits| wgpu::Limits {
+ max_bind_groups: 2,
+ ..limits
+ });
+
+ let (device, queue) = stream::iter(limits)
+ .filter_map(|limits| async {
+ adapter.request_device(
+ &wgpu::DeviceDescriptor {
+ label: Some(
+ "iced_wgpu::window::compositor device descriptor",
+ ),
+ features: wgpu::Features::empty(),
+ limits,
},
- },
- None,
- )
- .await
- .ok()?;
+ None,
+ ).await.ok()
+ })
+ .boxed()
+ .next()
+ .await?;
let staging_belt = wgpu::util::StagingBelt::new(Self::CHUNK_SIZE);
- let local_pool = futures::executor::LocalPool::new();
Some(Compositor {
instance,
settings,
+ adapter,
device,
queue,
staging_belt,
- local_pool,
format,
+ theme: PhantomData,
})
}
@@ -92,20 +118,20 @@ impl Compositor {
}
}
-impl iced_graphics::window::Compositor for Compositor {
+impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
type Settings = Settings;
- type Renderer = Renderer;
+ type Renderer = Renderer<Theme>;
type Surface = wgpu::Surface;
fn new<W: HasRawWindowHandle>(
settings: Self::Settings,
compatible_window: Option<&W>,
- ) -> Result<(Self, Renderer), Error> {
+ ) -> Result<(Self, Self::Renderer), Error> {
let compositor = futures::executor::block_on(Self::request(
settings,
compatible_window,
))
- .ok_or(Error::AdapterNotFound)?;
+ .ok_or(Error::GraphicsAdapterNotFound)?;
let backend = compositor.create_backend();
@@ -140,6 +166,15 @@ impl iced_graphics::window::Compositor for Compositor {
);
}
+ fn fetch_information(&self) -> compositor::Information {
+ let information = self.adapter.get_info();
+
+ compositor::Information {
+ adapter: information.name,
+ backend: format!("{:?}", information.backend),
+ }
+ }
+
fn present<T: AsRef<str>>(
&mut self,
renderer: &mut Self::Renderer,
@@ -147,7 +182,7 @@ impl iced_graphics::window::Compositor for Compositor {
viewport: &Viewport,
background_color: Color,
overlay: &[T],
- ) -> Result<(), iced_graphics::window::SurfaceError> {
+ ) -> Result<(), compositor::SurfaceError> {
match surface.get_current_texture() {
Ok(frame) => {
let mut encoder = self.device.create_command_encoder(
@@ -165,30 +200,32 @@ impl iced_graphics::window::Compositor for Compositor {
label: Some(
"iced_wgpu::window::Compositor render pass",
),
- color_attachments: &[wgpu::RenderPassColorAttachment {
- view,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Clear({
- let [r, g, b, a] =
- background_color.into_linear();
-
- wgpu::Color {
- r: f64::from(r),
- g: f64::from(g),
- b: f64::from(b),
- a: f64::from(a),
- }
- }),
- store: true,
+ color_attachments: &[Some(
+ wgpu::RenderPassColorAttachment {
+ view,
+ resolve_target: None,
+ ops: wgpu::Operations {
+ load: wgpu::LoadOp::Clear({
+ let [r, g, b, a] =
+ background_color.into_linear();
+
+ wgpu::Color {
+ r: f64::from(r),
+ g: f64::from(g),
+ b: f64::from(b),
+ a: f64::from(a),
+ }
+ }),
+ store: true,
+ },
},
- }],
+ )],
depth_stencil_attachment: None,
});
renderer.with_primitives(|backend, primitives| {
backend.present(
- &mut self.device,
+ &self.device,
&mut self.staging_belt,
&mut encoder,
view,
@@ -200,31 +237,24 @@ impl iced_graphics::window::Compositor for Compositor {
// Submit work
self.staging_belt.finish();
- self.queue.submit(Some(encoder.finish()));
+ let _submission = self.queue.submit(Some(encoder.finish()));
frame.present();
// Recall staging buffers
- self.local_pool
- .spawner()
- .spawn(self.staging_belt.recall())
- .expect("Recall staging belt");
-
- self.local_pool.run_until_stalled();
+ self.staging_belt.recall();
Ok(())
}
Err(error) => match error {
wgpu::SurfaceError::Timeout => {
- Err(iced_graphics::window::SurfaceError::Timeout)
+ Err(compositor::SurfaceError::Timeout)
}
wgpu::SurfaceError::Outdated => {
- Err(iced_graphics::window::SurfaceError::Outdated)
- }
- wgpu::SurfaceError::Lost => {
- Err(iced_graphics::window::SurfaceError::Lost)
+ Err(compositor::SurfaceError::Outdated)
}
+ wgpu::SurfaceError::Lost => Err(compositor::SurfaceError::Lost),
wgpu::SurfaceError::OutOfMemory => {
- Err(iced_graphics::window::SurfaceError::OutOfMemory)
+ Err(compositor::SurfaceError::OutOfMemory)
}
},
}