Grow atlas in text::Pipeline when necessary

This commit is contained in:
Héctor Ramón Jiménez 2023-02-08 23:21:04 +01:00
parent ddbf93a82f
commit 05c787c2ef
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
3 changed files with 77 additions and 32 deletions

View file

@ -60,7 +60,7 @@ path = "../graphics"
[dependencies.glyphon] [dependencies.glyphon]
version = "0.2" version = "0.2"
git = "https://github.com/hecrj/glyphon.git" git = "https://github.com/hecrj/glyphon.git"
rev = "ccf19c67e8a4564263626bc6b86b6154540768c4" rev = "541efc5df644b1a25e96113f602a3f6803ce8a07"
[dependencies.tracing] [dependencies.tracing]
version = "0.1.6" version = "0.1.6"

View file

@ -93,10 +93,17 @@ impl Backend {
encoder, encoder,
scale_factor, scale_factor,
transformation, transformation,
target_size,
&layers, &layers,
); );
while !self.prepare_text(
device,
queue,
scale_factor,
target_size,
&layers,
) {}
self.render( self.render(
device, device,
encoder, encoder,
@ -115,6 +122,38 @@ impl Backend {
self.image_pipeline.end_frame(device, queue, encoder); self.image_pipeline.end_frame(device, queue, encoder);
} }
fn prepare_text(
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
scale_factor: f32,
target_size: Size<u32>,
layers: &[Layer<'_>],
) -> bool {
for layer in layers {
let bounds = (layer.bounds * scale_factor).snap();
if bounds.width < 1 || bounds.height < 1 {
continue;
}
if !layer.text.is_empty() {
if !self.text_pipeline.prepare(
device,
queue,
&layer.text,
layer.bounds,
scale_factor,
target_size,
) {
return false;
}
}
}
true
}
fn prepare( fn prepare(
&mut self, &mut self,
device: &wgpu::Device, device: &wgpu::Device,
@ -122,14 +161,13 @@ impl Backend {
_encoder: &mut wgpu::CommandEncoder, _encoder: &mut wgpu::CommandEncoder,
scale_factor: f32, scale_factor: f32,
transformation: Transformation, transformation: Transformation,
target_size: Size<u32>,
layers: &[Layer<'_>], layers: &[Layer<'_>],
) { ) {
for layer in layers { for layer in layers {
let bounds = (layer.bounds * scale_factor).snap(); let bounds = (layer.bounds * scale_factor).snap();
if bounds.width < 1 || bounds.height < 1 { if bounds.width < 1 || bounds.height < 1 {
return; continue;
} }
if !layer.quads.is_empty() { if !layer.quads.is_empty() {
@ -170,17 +208,6 @@ impl Backend {
); );
} }
} }
if !layer.text.is_empty() {
self.text_pipeline.prepare(
device,
queue,
&layer.text,
layer.bounds,
scale_factor,
target_size,
);
}
} }
} }

View file

@ -86,7 +86,7 @@ impl Pipeline {
bounds: Rectangle, bounds: Rectangle,
scale_factor: f32, scale_factor: f32,
target_size: Size<u32>, target_size: Size<u32>,
) { ) -> bool {
self.system.as_mut().unwrap().with_mut(|fields| { self.system.as_mut().unwrap().with_mut(|fields| {
if self.renderers.len() <= self.prepare_layer { if self.renderers.len() <= self.prepare_layer {
self.renderers self.renderers
@ -165,23 +165,39 @@ impl Pipeline {
} }
}); });
renderer let result = renderer.prepare(
.prepare( device,
device, queue,
queue, &mut self.atlas,
&mut self.atlas, glyphon::Resolution {
glyphon::Resolution { width: target_size.width,
width: target_size.width, height: target_size.height,
height: target_size.height, },
}, text_areas,
text_areas, glyphon::Color::rgb(0, 0, 0),
glyphon::Color::rgb(0, 0, 0), &mut glyphon::SwashCache::new(fields.fonts),
&mut glyphon::SwashCache::new(fields.fonts), );
)
.expect("Prepare text sections");
self.prepare_layer += 1; match result {
}); Ok(()) => {
self.prepare_layer += 1;
true
}
Err(glyphon::PrepareError::AtlasFull(content_type)) => {
self.prepare_layer = 0;
if self.atlas.grow(device, content_type) {
false
} else {
// If the atlas cannot grow, then all bets are off.
// Instead of panicking, we will just pray that the result
// will be somewhat readable...
true
}
}
}
})
} }
pub fn render<'a>( pub fn render<'a>(
@ -205,6 +221,8 @@ impl Pipeline {
} }
pub fn end_frame(&mut self) { pub fn end_frame(&mut self) {
self.atlas.trim();
self.system self.system
.as_mut() .as_mut()
.unwrap() .unwrap()