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" dark-light = "1.0"
futures = "0.3" futures = "0.3"
glam = "0.25" 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" guillotiere = "0.6"
half = "2.2" half = "2.2"
image = "0.24" image = "0.24"

View file

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

View file

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