diff options
Diffstat (limited to 'wgpu')
34 files changed, 276 insertions, 496 deletions
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index b4173413..586f97d3 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_wgpu" -version = "0.4.0" +version = "0.5.1" authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] edition = "2021" description = "A wgpu renderer for Iced" @@ -28,8 +28,8 @@ spirv = ["wgpu/spirv"] webgl = ["wgpu/webgl"] [dependencies] -wgpu = "0.12" -wgpu_glyph = "0.16" +wgpu = "0.13" +wgpu_glyph = "0.17" glyph_brush = "0.7" raw-window-handle = "0.4" log = "0.4" @@ -39,15 +39,15 @@ kamadak-exif = "0.5" bitflags = "1.2" [dependencies.bytemuck] -version = "1.4" +version = "1.9" features = ["derive"] [dependencies.iced_native] -version = "0.4" +version = "0.5" path = "../native" [dependencies.iced_graphics] -version = "0.2" +version = "0.3" path = "../graphics" features = ["font-fallback", "font-icons"] diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 05b4af9b..8c875254 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -93,7 +93,7 @@ impl Backend { &layer, staging_belt, encoder, - &frame, + frame, target_size.width, target_size.height, ); @@ -230,7 +230,6 @@ impl Backend { wgpu_glyph::VerticalAlign::Bottom } }), - ..Default::default() }; self.text_pipeline.queue(text); diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index 0fefbfaf..d964aed7 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -136,7 +136,7 @@ impl Pipeline { }); let shader = - device.create_shader_module(&wgpu::ShaderModuleDescriptor { + device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu::image::shader"), source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( include_str!("shader/image.wgsl"), @@ -176,7 +176,7 @@ impl Pipeline { fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "fs_main", - targets: &[wgpu::ColorTargetState { + targets: &[Some(wgpu::ColorTargetState { format, blend: Some(wgpu::BlendState { color: wgpu::BlendComponent { @@ -191,7 +191,7 @@ impl Pipeline { }, }), write_mask: wgpu::ColorWrites::ALL, - }], + })], }), primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleList, @@ -236,7 +236,7 @@ impl Pipeline { entries: &[wgpu::BindGroupEntry { binding: 0, resource: wgpu::BindingResource::TextureView( - &texture_atlas.view(), + texture_atlas.view(), ), }], }); @@ -264,7 +264,7 @@ impl Pipeline { #[cfg(feature = "image_rs")] pub fn dimensions(&self, handle: &image::Handle) -> (u32, u32) { let mut cache = self.raster_cache.borrow_mut(); - let memory = cache.load(&handle); + let memory = cache.load(handle); memory.dimensions() } @@ -272,7 +272,7 @@ impl Pipeline { #[cfg(feature = "svg")] pub fn viewport_dimensions(&self, handle: &svg::Handle) -> (u32, u32) { let mut cache = self.vector_cache.borrow_mut(); - let svg = cache.load(&handle); + let svg = cache.load(handle); svg.viewport_dimensions() } @@ -358,7 +358,7 @@ impl Pipeline { entries: &[wgpu::BindGroupEntry { binding: 0, resource: wgpu::BindingResource::TextureView( - &self.texture_atlas.view(), + self.texture_atlas.view(), ), }], }); @@ -406,14 +406,16 @@ impl Pipeline { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("iced_wgpu::image render pass"), - color_attachments: &[wgpu::RenderPassColorAttachment { - view: target, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Load, - store: true, + color_attachments: &[Some( + wgpu::RenderPassColorAttachment { + view: target, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: true, + }, }, - }], + )], depth_stencil_attachment: None, }); diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index c1347e55..953dd4e2 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -113,13 +113,7 @@ impl Atlas { match &entry { Entry::Contiguous(allocation) => { self.upload_allocation( - &buffer, - width, - height, - padding, - 0, - &allocation, - encoder, + &buffer, width, height, padding, 0, allocation, encoder, ); } Entry::Fragmented { fragments, .. } => { diff --git a/wgpu/src/image/atlas/layer.rs b/wgpu/src/image/atlas/layer.rs index b1084ed9..cf089601 100644 --- a/wgpu/src/image/atlas/layer.rs +++ b/wgpu/src/image/atlas/layer.rs @@ -9,9 +9,6 @@ pub enum Layer { impl Layer { pub fn is_empty(&self) -> bool { - match self { - Layer::Empty => true, - _ => false, - } + matches!(self, Layer::Empty) } } diff --git a/wgpu/src/image/raster.rs b/wgpu/src/image/raster.rs index ec5e911f..2b4d4af3 100644 --- a/wgpu/src/image/raster.rs +++ b/wgpu/src/image/raster.rs @@ -59,7 +59,7 @@ impl Cache { } } image::Data::Bytes(bytes) => { - if let Ok(image) = image_rs::load_from_memory(&bytes) { + if let Ok(image) = image_rs::load_from_memory(bytes) { let operation = Operation::from_exif(&mut std::io::Cursor::new(bytes)) .ok() @@ -103,7 +103,7 @@ impl Cache { if let Memory::Host(image) = memory { let (width, height) = image.dimensions(); - let entry = atlas.upload(width, height, &image, device, encoder)?; + let entry = atlas.upload(width, height, image, device, encoder)?; *memory = Memory::Device(entry); } diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs index 4c830913..b08a0aa2 100644 --- a/wgpu/src/image/vector.rs +++ b/wgpu/src/image/vector.rs @@ -60,7 +60,7 @@ impl Cache { } svg::Data::Bytes(bytes) => { match usvg::Tree::from_data( - &bytes, + bytes, &usvg::Options::default().to_ref(), ) { Ok(tree) => Svg::Loaded(tree), @@ -112,7 +112,7 @@ impl Cache { // It would be cool to be able to smooth resize the `svg` example. let mut img = tiny_skia::Pixmap::new(width, height)?; - let _ = resvg::render( + resvg::render( tree, if width > height { usvg::FitTo::Width(width) diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index fb03854b..3a98c6bd 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -16,23 +16,30 @@ //! - Meshes of triangles, useful to draw geometry freely. //! //! [Iced]: https://github.com/iced-rs/iced -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/master/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs //! [WebGPU API]: https://gpuweb.github.io/gpuweb/ //! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] -#![deny(missing_docs)] -#![deny(missing_debug_implementations)] -#![deny(unused_results)] -#![deny(unsafe_code)] +#![deny( + missing_debug_implementations, + missing_docs, + unsafe_code, + unused_results, + clippy::extra_unused_lifetimes, + clippy::from_over_into, + clippy::needless_borrow, + clippy::new_without_default, + clippy::useless_conversion +)] #![forbid(rust_2018_idioms)] +#![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_cfg))] pub mod settings; pub mod triangle; -pub mod widget; pub mod window; mod backend; @@ -40,14 +47,12 @@ mod quad; mod text; pub use iced_graphics::{Antialiasing, Color, Error, Primitive, Viewport}; +pub use iced_native::Theme; pub use wgpu; pub use backend::Backend; pub use settings::Settings; -#[doc(no_inline)] -pub use widget::*; - pub(crate) use iced_graphics::Transformation; #[cfg(any(feature = "image_rs", feature = "svg"))] @@ -57,4 +62,5 @@ mod image; /// /// [`wgpu`]: https://github.com/gfx-rs/wgpu-rs /// [`iced`]: https://github.com/iced-rs/iced -pub type Renderer = iced_graphics::Renderer<Backend>; +pub type Renderer<Theme = iced_native::Theme> = + iced_graphics::Renderer<Backend, Theme>; diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 22f3b815..a117df64 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -59,7 +59,7 @@ impl Pipeline { }); let shader = - device.create_shader_module(&wgpu::ShaderModuleDescriptor { + device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu::quad::shader"), source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( include_str!("shader/quad.wgsl"), @@ -100,7 +100,7 @@ impl Pipeline { fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "fs_main", - targets: &[wgpu::ColorTargetState { + targets: &[Some(wgpu::ColorTargetState { format, blend: Some(wgpu::BlendState { color: wgpu::BlendComponent { @@ -115,7 +115,7 @@ impl Pipeline { }, }), write_mask: wgpu::ColorWrites::ALL, - }], + })], }), primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleList, @@ -211,14 +211,16 @@ impl Pipeline { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("iced_wgpu::quad render pass"), - color_attachments: &[wgpu::RenderPassColorAttachment { - view: target, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Load, - store: true, + color_attachments: &[Some( + wgpu::RenderPassColorAttachment { + view: target, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: true, + }, }, - }], + )], depth_stencil_attachment: None, }); diff --git a/wgpu/src/settings.rs b/wgpu/src/settings.rs index 23b55904..7bc752ff 100644 --- a/wgpu/src/settings.rs +++ b/wgpu/src/settings.rs @@ -63,7 +63,7 @@ impl Settings { impl Default for Settings { fn default() -> Settings { Settings { - present_mode: wgpu::PresentMode::Mailbox, + present_mode: wgpu::PresentMode::AutoVsync, internal_backend: wgpu::Backends::all(), default_font: None, default_text_size: 20, diff --git a/wgpu/src/shader/blit.wgsl b/wgpu/src/shader/blit.wgsl index f8f6e2d4..c2ea223f 100644 --- a/wgpu/src/shader/blit.wgsl +++ b/wgpu/src/shader/blit.wgsl @@ -16,19 +16,19 @@ var<private> uvs: array<vec2<f32>, 6> = array<vec2<f32>, 6>( vec2<f32>(1.0, 1.0) ); -[[group(0), binding(0)]] var u_sampler: sampler; -[[group(1), binding(0)]] var u_texture: texture_2d<f32>; +@group(0) @binding(0) var u_sampler: sampler; +@group(1) @binding(0) var u_texture: texture_2d<f32>; struct VertexInput { - [[builtin(vertex_index)]] vertex_index: u32; -}; + @builtin(vertex_index) vertex_index: u32, +} struct VertexOutput { - [[builtin(position)]] position: vec4<f32>; - [[location(0)]] uv: vec2<f32>; -}; + @builtin(position) position: vec4<f32>, + @location(0) uv: vec2<f32>, +} -[[stage(vertex)]] +@vertex fn vs_main(input: VertexInput) -> VertexOutput { var out: VertexOutput; out.uv = uvs[input.vertex_index]; @@ -37,7 +37,7 @@ fn vs_main(input: VertexInput) -> VertexOutput { return out; } -[[stage(fragment)]] -fn fs_main(input: VertexOutput) -> [[location(0)]] vec4<f32> { +@fragment +fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> { return textureSample(u_texture, u_sampler, input.uv); } diff --git a/wgpu/src/shader/image.wgsl b/wgpu/src/shader/image.wgsl index ff304422..5e22cdf4 100644 --- a/wgpu/src/shader/image.wgsl +++ b/wgpu/src/shader/image.wgsl @@ -1,27 +1,27 @@ struct Globals { - transform: mat4x4<f32>; -}; + transform: mat4x4<f32>, +} -[[group(0), binding(0)]] var<uniform> globals: Globals; -[[group(0), binding(1)]] var u_sampler: sampler; -[[group(1), binding(0)]] var u_texture: texture_2d_array<f32>; +@group(0) @binding(0) var<uniform> globals: Globals; +@group(0) @binding(1) var u_sampler: sampler; +@group(1) @binding(0) var u_texture: texture_2d_array<f32>; struct VertexInput { - [[location(0)]] v_pos: vec2<f32>; - [[location(1)]] pos: vec2<f32>; - [[location(2)]] scale: vec2<f32>; - [[location(3)]] atlas_pos: vec2<f32>; - [[location(4)]] atlas_scale: vec2<f32>; - [[location(5)]] layer: i32; -}; + @location(0) v_pos: vec2<f32>, + @location(1) pos: vec2<f32>, + @location(2) scale: vec2<f32>, + @location(3) atlas_pos: vec2<f32>, + @location(4) atlas_scale: vec2<f32>, + @location(5) layer: i32, +} struct VertexOutput { - [[builtin(position)]] position: vec4<f32>; - [[location(0)]] uv: vec2<f32>; - [[location(1)]] layer: f32; // this should be an i32, but naga currently reads that as requiring interpolation. -}; + @builtin(position) position: vec4<f32>, + @location(0) uv: vec2<f32>, + @location(1) layer: f32, // this should be an i32, but naga currently reads that as requiring interpolation. +} -[[stage(vertex)]] +@vertex fn vs_main(input: VertexInput) -> VertexOutput { var out: VertexOutput; @@ -40,7 +40,7 @@ fn vs_main(input: VertexInput) -> VertexOutput { return out; } -[[stage(fragment)]] -fn fs_main(input: VertexOutput) -> [[location(0)]] vec4<f32> { +@fragment +fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> { return textureSample(u_texture, u_sampler, input.uv, i32(input.layer)); } diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index 73f5d597..73edd97c 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -1,31 +1,31 @@ struct Globals { - transform: mat4x4<f32>; - scale: f32; -}; + transform: mat4x4<f32>, + scale: f32, +} -[[group(0), binding(0)]] var<uniform> globals: Globals; +@group(0) @binding(0) var<uniform> globals: Globals; struct VertexInput { - [[location(0)]] v_pos: vec2<f32>; - [[location(1)]] pos: vec2<f32>; - [[location(2)]] scale: vec2<f32>; - [[location(3)]] color: vec4<f32>; - [[location(4)]] border_color: vec4<f32>; - [[location(5)]] border_radius: f32; - [[location(6)]] border_width: f32; -}; + @location(0) v_pos: vec2<f32>, + @location(1) pos: vec2<f32>, + @location(2) scale: vec2<f32>, + @location(3) color: vec4<f32>, + @location(4) border_color: vec4<f32>, + @location(5) border_radius: f32, + @location(6) border_width: f32, +} struct VertexOutput { - [[builtin(position)]] position: vec4<f32>; - [[location(0)]] color: vec4<f32>; - [[location(1)]] border_color: vec4<f32>; - [[location(2)]] pos: vec2<f32>; - [[location(3)]] scale: vec2<f32>; - [[location(4)]] border_radius: f32; - [[location(5)]] border_width: f32; -}; - -[[stage(vertex)]] + @builtin(position) position: vec4<f32>, + @location(0) color: vec4<f32>, + @location(1) border_color: vec4<f32>, + @location(2) pos: vec2<f32>, + @location(3) scale: vec2<f32>, + @location(4) border_radius: f32, + @location(5) border_width: f32, +} + +@vertex fn vs_main(input: VertexInput) -> VertexOutput { var out: VertexOutput; @@ -77,10 +77,10 @@ fn distance_alg( } -[[stage(fragment)]] +@fragment fn fs_main( input: VertexOutput -) -> [[location(0)]] vec4<f32> { +) -> @location(0) vec4<f32> { var mixed_color: vec4<f32> = input.color; if (input.border_width > 0.0) { @@ -96,7 +96,7 @@ fn fs_main( internal_border ); - var border_mix: f32 = smoothStep( + var border_mix: f32 = smoothstep( max(internal_border - 0.5, 0.0), internal_border + 0.5, internal_distance @@ -112,7 +112,7 @@ fn fs_main( input.border_radius ); - var radius_alpha: f32 = 1.0 - smoothStep( + var radius_alpha: f32 = 1.0 - smoothstep( max(input.border_radius - 0.5, 0.0), input.border_radius + 0.5, dist); diff --git a/wgpu/src/shader/triangle.wgsl b/wgpu/src/shader/triangle.wgsl index 61d9c5a4..b24402f8 100644 --- a/wgpu/src/shader/triangle.wgsl +++ b/wgpu/src/shader/triangle.wgsl @@ -1,20 +1,20 @@ struct Globals { - transform: mat4x4<f32>; -}; + transform: mat4x4<f32>, +} -[[group(0), binding(0)]] var<uniform> globals: Globals; +@group(0) @binding(0) var<uniform> globals: Globals; struct VertexInput { - [[location(0)]] position: vec2<f32>; - [[location(1)]] color: vec4<f32>; -}; + @location(0) position: vec2<f32>, + @location(1) color: vec4<f32>, +} struct VertexOutput { - [[builtin(position)]] position: vec4<f32>; - [[location(0)]] color: vec4<f32>; -}; + @builtin(position) position: vec4<f32>, + @location(0) color: vec4<f32>, +} -[[stage(vertex)]] +@vertex fn vs_main(input: VertexInput) -> VertexOutput { var out: VertexOutput; @@ -24,7 +24,7 @@ fn vs_main(input: VertexInput) -> VertexOutput { return out; } -[[stage(fragment)]] -fn fs_main(input: VertexOutput) -> [[location(0)]] vec4<f32> { +@fragment +fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> { return input.color; } diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 45f1f2de..e17b84c1 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -188,7 +188,8 @@ impl Pipeline { } b_count += utf8_len; } - return byte_index; + + byte_index }; if !nearest_only { diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index c702243b..fd06dddf 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -132,7 +132,7 @@ impl Pipeline { }); let shader = - device.create_shader_module(&wgpu::ShaderModuleDescriptor { + device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu::triangle::shader"), source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( include_str!("shader/triangle.wgsl"), @@ -160,22 +160,11 @@ impl Pipeline { fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "fs_main", - targets: &[wgpu::ColorTargetState { + targets: &[Some(wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState { - color: wgpu::BlendComponent { - src_factor: wgpu::BlendFactor::SrcAlpha, - dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, - operation: wgpu::BlendOperation::Add, - }, - alpha: wgpu::BlendComponent { - src_factor: wgpu::BlendFactor::One, - dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, - operation: wgpu::BlendOperation::Add, - }, - }), + blend: Some(wgpu::BlendState::ALPHA_BLENDING), write_mask: wgpu::ColorWrites::ALL, - }], + })], }), primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleList, @@ -184,9 +173,7 @@ impl Pipeline { }, depth_stencil: None, multisample: wgpu::MultisampleState { - count: u32::from( - antialiasing.map(|a| a.sample_count()).unwrap_or(1), - ), + count: antialiasing.map(|a| a.sample_count()).unwrap_or(1), mask: !0, alpha_to_coverage_enabled: false, }, @@ -283,47 +270,43 @@ impl Pipeline { let vertices = bytemuck::cast_slice(&mesh.buffers.vertices); let indices = bytemuck::cast_slice(&mesh.buffers.indices); - match ( + if let (Some(vertices_size), Some(indices_size)) = ( wgpu::BufferSize::new(vertices.len() as u64), wgpu::BufferSize::new(indices.len() as u64), ) { - (Some(vertices_size), Some(indices_size)) => { - { - let mut vertex_buffer = staging_belt.write_buffer( - encoder, - &self.vertex_buffer.raw, - (std::mem::size_of::<Vertex2D>() * last_vertex) - as u64, - vertices_size, - device, - ); - - vertex_buffer.copy_from_slice(vertices); - } - - { - let mut index_buffer = staging_belt.write_buffer( - encoder, - &self.index_buffer.raw, - (std::mem::size_of::<u32>() * last_index) as u64, - indices_size, - device, - ); - - index_buffer.copy_from_slice(indices); - } - - uniforms.push(transform); - offsets.push(( - last_vertex as u64, - last_index as u64, - mesh.buffers.indices.len(), - )); - - last_vertex += mesh.buffers.vertices.len(); - last_index += mesh.buffers.indices.len(); + { + let mut vertex_buffer = staging_belt.write_buffer( + encoder, + &self.vertex_buffer.raw, + (std::mem::size_of::<Vertex2D>() * last_vertex) as u64, + vertices_size, + device, + ); + + vertex_buffer.copy_from_slice(vertices); } - _ => {} + + { + let mut index_buffer = staging_belt.write_buffer( + encoder, + &self.index_buffer.raw, + (std::mem::size_of::<u32>() * last_index) as u64, + indices_size, + device, + ); + + index_buffer.copy_from_slice(indices); + } + + uniforms.push(transform); + offsets.push(( + last_vertex as u64, + last_index as u64, + mesh.buffers.indices.len(), + )); + + last_vertex += mesh.buffers.vertices.len(); + last_index += mesh.buffers.indices.len(); } } @@ -361,11 +344,13 @@ impl Pipeline { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("iced_wgpu::triangle render pass"), - color_attachments: &[wgpu::RenderPassColorAttachment { - view: attachment, - resolve_target, - ops: wgpu::Operations { load, store: true }, - }], + color_attachments: &[Some( + wgpu::RenderPassColorAttachment { + view: attachment, + resolve_target, + ops: wgpu::Operations { load, store: true }, + }, + )], depth_stencil_attachment: None, }); diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs index 9fb87544..a3016ff8 100644 --- a/wgpu/src/triangle/msaa.rs +++ b/wgpu/src/triangle/msaa.rs @@ -74,7 +74,7 @@ impl Blit { }); let shader = - device.create_shader_module(&wgpu::ShaderModuleDescriptor { + device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu::triangle::blit_shader"), source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( include_str!("../shader/blit.wgsl"), @@ -93,22 +93,13 @@ impl Blit { fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "fs_main", - targets: &[wgpu::ColorTargetState { + targets: &[Some(wgpu::ColorTargetState { format, - blend: Some(wgpu::BlendState { - color: wgpu::BlendComponent { - src_factor: wgpu::BlendFactor::SrcAlpha, - dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, - operation: wgpu::BlendOperation::Add, - }, - alpha: wgpu::BlendComponent { - src_factor: wgpu::BlendFactor::One, - dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, - operation: wgpu::BlendOperation::Add, - }, - }), + blend: Some( + wgpu::BlendState::PREMULTIPLIED_ALPHA_BLENDING, + ), write_mask: wgpu::ColorWrites::ALL, - }], + })], }), primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleList, @@ -143,7 +134,7 @@ impl Blit { match &mut self.targets { None => { self.targets = Some(Targets::new( - &device, + device, self.format, &self.texture_layout, self.sample_count, @@ -154,7 +145,7 @@ impl Blit { Some(targets) => { if targets.width != width || targets.height != height { self.targets = Some(Targets::new( - &device, + device, self.format, &self.texture_layout, self.sample_count, @@ -178,14 +169,14 @@ impl Blit { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("iced_wgpu::triangle::msaa render pass"), - color_attachments: &[wgpu::RenderPassColorAttachment { + color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: target, resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Load, store: true, }, - }], + })], depth_stencil_attachment: None, }); diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs deleted file mode 100644 index 99ae0ac2..00000000 --- a/wgpu/src/widget.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Use the widgets supported out-of-the-box. -//! -//! # Re-exports -//! For convenience, the contents of this module are available at the root -//! module. Therefore, you can directly type: -//! -//! ``` -//! use iced_wgpu::{button, Button}; -//! ``` -use crate::Renderer; - -pub mod button; -pub mod checkbox; -pub mod container; -pub mod pane_grid; -pub mod pick_list; -pub mod progress_bar; -pub mod radio; -pub mod rule; -pub mod scrollable; -pub mod slider; -pub mod text_input; -pub mod toggler; -pub mod tooltip; - -#[doc(no_inline)] -pub use button::Button; -#[doc(no_inline)] -pub use checkbox::Checkbox; -#[doc(no_inline)] -pub use container::Container; -#[doc(no_inline)] -pub use pane_grid::PaneGrid; -#[doc(no_inline)] -pub use pick_list::PickList; -#[doc(no_inline)] -pub use progress_bar::ProgressBar; -#[doc(no_inline)] -pub use radio::Radio; -#[doc(no_inline)] -pub use rule::Rule; -#[doc(no_inline)] -pub use scrollable::Scrollable; -#[doc(no_inline)] -pub use slider::Slider; -#[doc(no_inline)] -pub use text_input::TextInput; -#[doc(no_inline)] -pub use toggler::Toggler; -#[doc(no_inline)] -pub use tooltip::Tooltip; - -#[cfg(feature = "canvas")] -#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))] -pub mod canvas; - -#[cfg(feature = "canvas")] -#[doc(no_inline)] -pub use canvas::Canvas; - -#[cfg(feature = "qr_code")] -#[cfg_attr(docsrs, doc(cfg(feature = "qr_code")))] -pub mod qr_code; - -#[cfg(feature = "qr_code")] -#[doc(no_inline)] -pub use qr_code::QRCode; - -pub use iced_native::widget::Space; - -/// A container that distributes its contents vertically. -pub type Column<'a, Message> = - iced_native::widget::Column<'a, Message, Renderer>; - -/// A container that distributes its contents horizontally. -pub type Row<'a, Message> = iced_native::widget::Row<'a, Message, Renderer>; - -/// A paragraph of text. -pub type Text = iced_native::widget::Text<Renderer>; diff --git a/wgpu/src/widget/button.rs b/wgpu/src/widget/button.rs deleted file mode 100644 index f11ff25e..00000000 --- a/wgpu/src/widget/button.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Allow your users to perform actions by pressing a button. -//! -//! A [`Button`] has some local [`State`]. -use crate::Renderer; - -pub use iced_graphics::button::{Style, StyleSheet}; -pub use iced_native::widget::button::State; - -/// A widget that produces a message when clicked. -/// -/// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`. -pub type Button<'a, Message> = - iced_native::widget::Button<'a, Message, Renderer>; diff --git a/wgpu/src/widget/canvas.rs b/wgpu/src/widget/canvas.rs deleted file mode 100644 index 399dd19c..00000000 --- a/wgpu/src/widget/canvas.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Draw 2D graphics for your users. -//! -//! A [`Canvas`] widget can be used to draw different kinds of 2D shapes in a -//! [`Frame`]. It can be used for animation, data visualization, game graphics, -//! and more! -pub use iced_graphics::canvas::*; diff --git a/wgpu/src/widget/checkbox.rs b/wgpu/src/widget/checkbox.rs deleted file mode 100644 index 76d572d9..00000000 --- a/wgpu/src/widget/checkbox.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Show toggle controls using checkboxes. -use crate::Renderer; - -pub use iced_graphics::checkbox::{Style, StyleSheet}; - -/// A box that can be checked. -/// -/// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`. -pub type Checkbox<'a, Message> = - iced_native::widget::Checkbox<'a, Message, Renderer>; diff --git a/wgpu/src/widget/container.rs b/wgpu/src/widget/container.rs deleted file mode 100644 index c16db50d..00000000 --- a/wgpu/src/widget/container.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Decorate content and apply alignment. -use crate::Renderer; - -pub use iced_graphics::container::{Style, StyleSheet}; - -/// An element decorating some content. -/// -/// This is an alias of an `iced_native` container with a default -/// `Renderer`. -pub type Container<'a, Message> = - iced_native::widget::Container<'a, Message, Renderer>; diff --git a/wgpu/src/widget/pane_grid.rs b/wgpu/src/widget/pane_grid.rs deleted file mode 100644 index 38bdb672..00000000 --- a/wgpu/src/widget/pane_grid.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Let your users split regions of your application and organize layout dynamically. -//! -//! [](https://gfycat.com/mixedflatjellyfish) -//! -//! # Example -//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing, -//! drag and drop, and hotkey support. -//! -//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.3/examples/pane_grid -use crate::Renderer; - -pub use iced_graphics::pane_grid::{ - Axis, Configuration, Direction, DragEvent, Line, Node, Pane, ResizeEvent, - Split, State, StyleSheet, -}; - -/// A collection of panes distributed using either vertical or horizontal splits -/// to completely fill the space available. -/// -/// [](https://gfycat.com/mixedflatjellyfish) -/// -/// This is an alias of an `iced_native` pane grid with an `iced_wgpu::Renderer`. -pub type PaneGrid<'a, Message> = - iced_native::widget::PaneGrid<'a, Message, Renderer>; - -/// The content of a [`Pane`]. -pub type Content<'a, Message> = - iced_native::widget::pane_grid::Content<'a, Message, Renderer>; - -/// The title bar of a [`Pane`]. -pub type TitleBar<'a, Message> = - iced_native::widget::pane_grid::TitleBar<'a, Message, Renderer>; diff --git a/wgpu/src/widget/pick_list.rs b/wgpu/src/widget/pick_list.rs deleted file mode 100644 index 4d93be68..00000000 --- a/wgpu/src/widget/pick_list.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Display a dropdown list of selectable values. -pub use iced_native::widget::pick_list::State; - -pub use iced_graphics::overlay::menu::Style as Menu; -pub use iced_graphics::pick_list::{Style, StyleSheet}; - -/// A widget allowing the selection of a single value from a list of options. -pub type PickList<'a, T, Message> = - iced_native::widget::PickList<'a, T, Message, crate::Renderer>; diff --git a/wgpu/src/widget/progress_bar.rs b/wgpu/src/widget/progress_bar.rs deleted file mode 100644 index 88391ccb..00000000 --- a/wgpu/src/widget/progress_bar.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Allow your users to visually track the progress of a computation. -//! -//! A [`ProgressBar`] has a range of possible values and a current value, -//! as well as a length, height and style. -pub use iced_graphics::progress_bar::*; diff --git a/wgpu/src/widget/qr_code.rs b/wgpu/src/widget/qr_code.rs deleted file mode 100644 index 7b1c2408..00000000 --- a/wgpu/src/widget/qr_code.rs +++ /dev/null @@ -1,2 +0,0 @@ -//! Encode and display information in a QR code. -pub use iced_graphics::qr_code::*; diff --git a/wgpu/src/widget/radio.rs b/wgpu/src/widget/radio.rs deleted file mode 100644 index 9ef1d7a5..00000000 --- a/wgpu/src/widget/radio.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Create choices using radio buttons. -use crate::Renderer; - -pub use iced_graphics::radio::{Style, StyleSheet}; - -/// A circular button representing a choice. -/// -/// This is an alias of an `iced_native` radio button with an -/// `iced_wgpu::Renderer`. -pub type Radio<'a, Message> = iced_native::widget::Radio<'a, Message, Renderer>; diff --git a/wgpu/src/widget/rule.rs b/wgpu/src/widget/rule.rs deleted file mode 100644 index 40281773..00000000 --- a/wgpu/src/widget/rule.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Display a horizontal or vertical rule for dividing content. - -pub use iced_graphics::rule::*; diff --git a/wgpu/src/widget/scrollable.rs b/wgpu/src/widget/scrollable.rs deleted file mode 100644 index d5635ec5..00000000 --- a/wgpu/src/widget/scrollable.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Navigate an endless amount of content with a scrollbar. -use crate::Renderer; - -pub use iced_graphics::scrollable::{Scrollbar, Scroller, StyleSheet}; -pub use iced_native::widget::scrollable::State; - -/// A widget that can vertically display an infinite amount of content -/// with a scrollbar. -/// -/// This is an alias of an `iced_native` scrollable with a default -/// `Renderer`. -pub type Scrollable<'a, Message> = - iced_native::widget::Scrollable<'a, Message, Renderer>; diff --git a/wgpu/src/widget/slider.rs b/wgpu/src/widget/slider.rs deleted file mode 100644 index 2fb3d5d9..00000000 --- a/wgpu/src/widget/slider.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Display an interactive selector of a single value from a range of values. -//! -//! A [`Slider`] has some local [`State`]. -pub use iced_graphics::slider::{Handle, HandleShape, Style, StyleSheet}; -pub use iced_native::widget::slider::{Slider, State}; diff --git a/wgpu/src/widget/text_input.rs b/wgpu/src/widget/text_input.rs deleted file mode 100644 index 5560e3e0..00000000 --- a/wgpu/src/widget/text_input.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Display fields that can be filled with text. -//! -//! A [`TextInput`] has some local [`State`]. -use crate::Renderer; - -pub use iced_graphics::text_input::{Style, StyleSheet}; -pub use iced_native::widget::text_input::State; - -/// A field that can be filled with text. -/// -/// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`. -pub type TextInput<'a, Message> = - iced_native::widget::TextInput<'a, Message, Renderer>; diff --git a/wgpu/src/widget/toggler.rs b/wgpu/src/widget/toggler.rs deleted file mode 100644 index 7ef5e22e..00000000 --- a/wgpu/src/widget/toggler.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Show toggle controls using togglers. -use crate::Renderer; - -pub use iced_graphics::toggler::{Style, StyleSheet}; - -/// A toggler that can be toggled -/// -/// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`. -pub type Toggler<'a, Message> = - iced_native::widget::Toggler<'a, Message, Renderer>; diff --git a/wgpu/src/widget/tooltip.rs b/wgpu/src/widget/tooltip.rs deleted file mode 100644 index c6af3903..00000000 --- a/wgpu/src/widget/tooltip.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Display a widget over another. -/// A widget allowing the selection of a single value from a list of options. -pub type Tooltip<'a, Message> = - iced_native::widget::Tooltip<'a, Message, crate::Renderer>; - -pub use iced_native::widget::tooltip::Position; 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) } }, } |