1#![allow(
3 clippy::collapsible_if,
4 clippy::too_many_arguments,
5 clippy::type_complexity,
6 clippy::get_first,
7 clippy::unnecessary_cast,
8 clippy::useless_conversion,
9 clippy::manual_clamp,
10 clippy::assign_op_pattern,
11 clippy::needless_borrow,
12 clippy::or_fun_call,
13 clippy::collapsible_match,
14 clippy::needless_range_loop,
15 clippy::manual_ok_or,
16 clippy::or_then_unwrap,
17 clippy::map_unwrap_or,
18 clippy::unnecessary_map_or,
19 clippy::unwrap_or_default,
20 clippy::manual_is_multiple_of,
21 clippy::manual_slice_size_calculation,
22 clippy::excessive_precision,
23 clippy::identity_op,
24 clippy::new_without_default,
25 clippy::needless_update,
26 clippy::empty_line_after_doc_comments,
27 clippy::doc_lazy_continuation,
28 clippy::field_reassign_with_default,
29 clippy::option_map_or_none
30)]
31
32use std::sync::Arc;
33
34use anyhow::Result;
35
36pub use wgpu;
38
39mod allocator;
40pub use allocator::{OwnedBuffer, OwnedTexture, RenderAllocator};
41
42pub struct GraphicsEngine {
44 device: Arc<wgpu::Device>,
45 queue: Arc<wgpu::Queue>,
46 allocator: RenderAllocator,
47}
48
49impl GraphicsEngine {
50 pub fn new(device: wgpu::Device, queue: wgpu::Queue) -> Self {
52 let device = Arc::new(device);
53 let queue = Arc::new(queue);
54 let allocator = RenderAllocator::new(device.clone());
55 Self {
56 device,
57 queue,
58 allocator,
59 }
60 }
61
62 pub fn device(&self) -> Arc<wgpu::Device> {
64 self.device.clone()
65 }
66
67 pub fn queue(&self) -> Arc<wgpu::Queue> {
69 self.queue.clone()
70 }
71
72 pub fn allocator(&self) -> &RenderAllocator {
74 &self.allocator
75 }
76 pub fn allocator_mut(&mut self) -> &mut RenderAllocator {
77 &mut self.allocator
78 }
79
80 pub fn render_dummy(&self) -> Result<()> {
82 let _ = (&self.device, &self.queue);
84 Ok(())
85 }
86}
87
88pub fn choose_srgb_surface_format(
90 adapter: &wgpu::Adapter,
91 surface: &wgpu::Surface,
92) -> wgpu::TextureFormat {
93 let caps = surface.get_capabilities(adapter);
94 caps.formats
95 .iter()
96 .copied()
97 .find(|f| f.is_srgb())
98 .unwrap_or(caps.formats[0])
99}
100
101pub fn make_surface_config(
103 adapter: &wgpu::Adapter,
104 surface: &wgpu::Surface,
105 width: u32,
106 height: u32,
107) -> wgpu::SurfaceConfiguration {
108 let caps = surface.get_capabilities(adapter);
109 let format = choose_srgb_surface_format(adapter, surface);
110 let present_mode = caps
111 .present_modes
112 .iter()
113 .copied()
114 .find(|m| *m == wgpu::PresentMode::Fifo)
115 .unwrap_or(caps.present_modes[0]);
116 let alpha_mode = caps
117 .alpha_modes
118 .iter()
119 .copied()
120 .find(|m| *m == wgpu::CompositeAlphaMode::Opaque)
121 .unwrap_or(caps.alpha_modes[0]);
122 wgpu::SurfaceConfiguration {
123 usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
124 format,
125 width,
126 height,
127 present_mode,
128 alpha_mode,
129 view_formats: vec![],
130 desired_maximum_frame_latency: 1,
131 }
132}
133
134mod color; mod display_list;
137mod dpi;
138mod hit_test;
139mod image_cache;
140mod painter;
141mod pass_manager;
142mod pipeline;
143mod scene;
144mod svg;
145mod text;
146mod text_layout;
147mod upload;
148
149pub use display_list::*;
150pub use dpi::*;
151pub use hit_test::*;
152pub use image_cache::*;
153pub use painter::*;
154pub use pass_manager::Background as RootBackground;
155pub use pass_manager::*;
156pub use pipeline::Blitter;
157pub use pipeline::*;
158pub use scene::*;
159pub use svg::*;
160pub use text::*;
161pub use text_layout::*;
162pub use upload::*;
163
164#[cfg(feature = "pdf_export")]
166mod pdf_backend;
167#[cfg(feature = "pdf_export")]
168pub use pdf_backend::render_display_list_to_pdf;