Implement async Compositor::request in iced_wgpu

This commit is contained in:
Héctor Ramón Jiménez 2020-05-29 23:08:34 +02:00
parent ab0ee1a8d0
commit 0691ec3195

View file

@ -1,4 +1,4 @@
use crate::{Renderer, Settings}; use crate::{Backend, Renderer, Settings};
use iced_graphics::Viewport; use iced_graphics::Viewport;
use iced_native::{futures, mouse}; use iced_native::{futures, mouse};
@ -7,19 +7,19 @@ use raw_window_handle::HasRawWindowHandle;
/// A window graphics backend for iced powered by `wgpu`. /// A window graphics backend for iced powered by `wgpu`.
#[derive(Debug)] #[derive(Debug)]
pub struct Compositor { pub struct Compositor {
settings: Settings,
device: wgpu::Device, device: wgpu::Device,
queue: wgpu::Queue, queue: wgpu::Queue,
format: wgpu::TextureFormat,
} }
impl iced_graphics::window::Compositor for Compositor { impl Compositor {
type Settings = Settings; /// Requests a new [`Compositor`] with the given [`Settings`].
type Renderer = Renderer; ///
type Surface = wgpu::Surface; /// Returns `None` if no compatible graphics adapter could be found.
type SwapChain = wgpu::SwapChain; ///
/// [`Compositor`]: struct.Compositor.html
fn new(settings: Self::Settings) -> (Self, Renderer) { /// [`Settings`]: struct.Settings.html
let (mut device, queue) = futures::executor::block_on(async { pub async fn request(settings: Settings) -> Option<Self> {
let adapter = wgpu::Adapter::request( let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions { &wgpu::RequestAdapterOptions {
power_preference: if settings.antialiasing.is_none() { power_preference: if settings.antialiasing.is_none() {
@ -31,30 +31,46 @@ impl iced_graphics::window::Compositor for Compositor {
}, },
wgpu::BackendBit::PRIMARY, wgpu::BackendBit::PRIMARY,
) )
.await .await?;
.expect("Request adapter");
adapter let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor { .request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions { extensions: wgpu::Extensions {
anisotropic_filtering: false, anisotropic_filtering: false,
}, },
limits: wgpu::Limits { max_bind_groups: 2 }, limits: wgpu::Limits { max_bind_groups: 2 },
}) })
.await .await;
});
let renderer = Some(Compositor {
Renderer::new(crate::Backend::new(&mut device, settings)); settings,
(
Self {
device, device,
queue, queue,
format: settings.format, })
}, }
renderer,
) /// Creates a new rendering [`Backend`] for this [`Compositor`].
///
/// [`Compositor`]: struct.Compositor.html
/// [`Backend`]: struct.Backend.html
pub fn create_backend(&self) -> Backend {
Backend::new(&self.device, self.settings)
}
}
impl iced_graphics::window::Compositor for Compositor {
type Settings = Settings;
type Renderer = Renderer;
type Surface = wgpu::Surface;
type SwapChain = wgpu::SwapChain;
fn new(settings: Self::Settings) -> (Self, Renderer) {
let compositor = futures::executor::block_on(Self::request(settings))
.expect("Could not find a suitable graphics adapter");
let backend = compositor.create_backend();
(compositor, Renderer::new(backend))
} }
fn create_surface<W: HasRawWindowHandle>( fn create_surface<W: HasRawWindowHandle>(
@ -74,7 +90,7 @@ impl iced_graphics::window::Compositor for Compositor {
surface, surface,
&wgpu::SwapChainDescriptor { &wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: self.format, format: self.settings.format,
width, width,
height, height,
present_mode: wgpu::PresentMode::Mailbox, present_mode: wgpu::PresentMode::Mailbox,