Merge pull request #2430 from iced-rs/reuse-glyphon-pipeline-state

Reuse `glyphon::Pipeline` state in `iced_wgpu`
This commit is contained in:
Héctor Ramón 2024-05-08 19:43:07 +02:00 committed by GitHub
commit f1beb56a9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 50 additions and 22 deletions

View file

@ -142,7 +142,7 @@ cosmic-text = "0.10"
dark-light = "1.0"
futures = "0.3"
glam = "0.25"
glyphon = { git = "https://github.com/hecrj/glyphon.git", rev = "ceed55403ce53e120ce9d1fae17dcfe388726118" }
glyphon = { git = "https://github.com/hecrj/glyphon.git", rev = "f07e7bab705e69d39a5e6e52c73039a93c4552f8" }
guillotiere = "0.6"
half = "2.2"
image = "0.24"

View file

@ -79,6 +79,7 @@ pub struct Renderer {
triangle_storage: triangle::Storage,
text_storage: text::Storage,
text_viewport: text::Viewport,
// TODO: Centralize all the image feature handling
#[cfg(any(feature = "svg", feature = "image"))]
@ -87,8 +88,8 @@ pub struct Renderer {
impl Renderer {
pub fn new(
_device: &wgpu::Device,
_engine: &Engine,
device: &wgpu::Device,
engine: &Engine,
default_font: Font,
default_text_size: Pixels,
) -> Self {
@ -99,10 +100,11 @@ impl Renderer {
triangle_storage: triangle::Storage::new(),
text_storage: text::Storage::new(),
text_viewport: engine.text_pipeline.create_viewport(device),
#[cfg(any(feature = "svg", feature = "image"))]
image_cache: std::cell::RefCell::new(
_engine.create_image_cache(_device),
engine.create_image_cache(device),
),
}
}
@ -141,6 +143,8 @@ impl Renderer {
) {
let scale_factor = viewport.scale_factor() as f32;
self.text_viewport.update(queue, viewport.physical_size());
for layer in self.layers.iter_mut() {
if !layer.quads.is_empty() {
engine.quad_pipeline.prepare(
@ -182,12 +186,12 @@ impl Renderer {
engine.text_pipeline.prepare(
device,
queue,
&self.text_viewport,
encoder,
&mut self.text_storage,
&layer.text,
layer.bounds,
Transformation::scale(scale_factor),
viewport.physical_size(),
);
}
@ -357,6 +361,7 @@ impl Renderer {
if !layer.text.is_empty() {
text_layer += engine.text_pipeline.render(
&self.text_viewport,
&self.text_storage,
text_layer,
&layer.text,

View file

@ -113,12 +113,13 @@ impl Storage {
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
viewport: &glyphon::Viewport,
encoder: &mut wgpu::CommandEncoder,
format: wgpu::TextureFormat,
state: &glyphon::Cache,
cache: &Cache,
new_transformation: Transformation,
bounds: Rectangle,
target_size: Size<u32>,
) {
let group_count = self.groups.len();
@ -131,7 +132,7 @@ impl Storage {
Group {
atlas: glyphon::TextAtlas::with_color_mode(
device, queue, format, COLOR_MODE,
device, queue, state, format, COLOR_MODE,
),
version: 0,
should_trim: false,
@ -151,6 +152,7 @@ impl Storage {
let _ = prepare(
device,
queue,
viewport,
encoder,
&mut upload.renderer,
&mut group.atlas,
@ -158,7 +160,6 @@ impl Storage {
&cache.text,
bounds,
new_transformation,
target_size,
);
}
@ -188,6 +189,7 @@ impl Storage {
let _ = prepare(
device,
queue,
viewport,
encoder,
&mut renderer,
&mut group.atlas,
@ -195,7 +197,6 @@ impl Storage {
&cache.text,
bounds,
new_transformation,
target_size,
);
}
@ -257,8 +258,23 @@ impl Storage {
}
}
pub struct Viewport(glyphon::Viewport);
impl Viewport {
pub fn update(&mut self, queue: &wgpu::Queue, resolution: Size<u32>) {
self.0.update(
queue,
glyphon::Resolution {
width: resolution.width,
height: resolution.height,
},
);
}
}
#[allow(missing_debug_implementations)]
pub struct Pipeline {
state: glyphon::Cache,
format: wgpu::TextureFormat,
atlas: glyphon::TextAtlas,
renderers: Vec<glyphon::TextRenderer>,
@ -272,12 +288,16 @@ impl Pipeline {
queue: &wgpu::Queue,
format: wgpu::TextureFormat,
) -> Self {
let state = glyphon::Cache::new(device);
let atlas = glyphon::TextAtlas::with_color_mode(
device, queue, &state, format, COLOR_MODE,
);
Pipeline {
state,
format,
renderers: Vec::new(),
atlas: glyphon::TextAtlas::with_color_mode(
device, queue, format, COLOR_MODE,
),
atlas,
prepare_layer: 0,
cache: BufferCache::new(),
}
@ -287,12 +307,12 @@ impl Pipeline {
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
viewport: &Viewport,
encoder: &mut wgpu::CommandEncoder,
storage: &mut Storage,
batch: &Batch,
layer_bounds: Rectangle,
layer_transformation: Transformation,
target_size: Size<u32>,
) {
for item in batch {
match item {
@ -313,6 +333,7 @@ impl Pipeline {
let result = prepare(
device,
queue,
&viewport.0,
encoder,
renderer,
&mut self.atlas,
@ -320,7 +341,6 @@ impl Pipeline {
text,
layer_bounds * layer_transformation,
layer_transformation * *transformation,
target_size,
);
match result {
@ -341,12 +361,13 @@ impl Pipeline {
storage.prepare(
device,
queue,
&viewport.0,
encoder,
self.format,
&self.state,
cache,
layer_transformation * *transformation,
layer_bounds * layer_transformation,
target_size,
);
}
}
@ -355,6 +376,7 @@ impl Pipeline {
pub fn render<'a>(
&'a self,
viewport: &'a Viewport,
storage: &'a Storage,
start: usize,
batch: &'a Batch,
@ -376,7 +398,7 @@ impl Pipeline {
let renderer = &self.renderers[start + layer_count];
renderer
.render(&self.atlas, render_pass)
.render(&self.atlas, &viewport.0, render_pass)
.expect("Render text");
layer_count += 1;
@ -385,7 +407,7 @@ impl Pipeline {
if let Some((atlas, upload)) = storage.get(cache) {
upload
.renderer
.render(atlas, render_pass)
.render(atlas, &viewport.0, render_pass)
.expect("Render cached text");
}
}
@ -395,6 +417,10 @@ impl Pipeline {
layer_count
}
pub fn create_viewport(&self, device: &wgpu::Device) -> Viewport {
Viewport(glyphon::Viewport::new(device, &self.state))
}
pub fn end_frame(&mut self) {
self.atlas.trim();
self.cache.trim();
@ -406,6 +432,7 @@ impl Pipeline {
fn prepare(
device: &wgpu::Device,
queue: &wgpu::Queue,
viewport: &glyphon::Viewport,
encoder: &mut wgpu::CommandEncoder,
renderer: &mut glyphon::TextRenderer,
atlas: &mut glyphon::TextAtlas,
@ -413,7 +440,6 @@ fn prepare(
sections: &[Text],
layer_bounds: Rectangle,
layer_transformation: Transformation,
target_size: Size<u32>,
) -> Result<(), glyphon::PrepareError> {
let mut font_system = font_system().write().expect("Write font system");
let font_system = font_system.raw();
@ -610,10 +636,7 @@ fn prepare(
encoder,
font_system,
atlas,
glyphon::Resolution {
width: target_size.width,
height: target_size.height,
},
viewport,
text_areas,
&mut glyphon::SwashCache::new(),
)