wgui: reuse WGfxPass on text & rect renderers

This commit is contained in:
galister
2025-06-18 04:18:07 +09:00
parent 1b7f9c8843
commit 9c1bd5b4f2
3 changed files with 66 additions and 31 deletions

View File

@@ -9,7 +9,7 @@ use vulkano::{
use crate::{ use crate::{
drawing::{Boundary, Rectangle}, drawing::{Boundary, Rectangle},
gfx::{BLEND_ALPHA, WGfx, cmd::GfxCommandBuffer, pipeline::WGfxPipeline}, gfx::{BLEND_ALPHA, WGfx, cmd::GfxCommandBuffer, pass::WGfxPass, pipeline::WGfxPipeline},
renderer_vk::model_buffer::ModelBuffer, renderer_vk::model_buffer::ModelBuffer,
}; };
@@ -59,12 +59,18 @@ impl RectPipeline {
} }
} }
struct CachedPass {
pass: WGfxPass<RectVertex>,
res: [u32; 2],
}
pub struct RectRenderer { pub struct RectRenderer {
pipeline: RectPipeline, pipeline: RectPipeline,
rect_vertices: Vec<RectVertex>, rect_vertices: Vec<RectVertex>,
vert_buffer: Subbuffer<[RectVertex]>, vert_buffer: Subbuffer<[RectVertex]>,
vert_buffer_size: usize, vert_buffer_size: usize,
model_buffer: ModelBuffer, model_buffer: ModelBuffer,
pass: Option<CachedPass>,
} }
impl RectRenderer { impl RectRenderer {
@@ -82,6 +88,7 @@ impl RectRenderer {
rect_vertices: vec![], rect_vertices: vec![],
vert_buffer, vert_buffer,
vert_buffer_size: BUFFER_SIZE, vert_buffer_size: BUFFER_SIZE,
pass: None,
}) })
} }
@@ -134,24 +141,31 @@ impl RectRenderer {
viewport: &mut Viewport, viewport: &mut Viewport,
cmd_buf: &mut GfxCommandBuffer, cmd_buf: &mut GfxCommandBuffer,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let vp = viewport.resolution(); let res = viewport.resolution();
self.model_buffer.upload(gfx)?; self.model_buffer.upload(gfx)?;
self.upload_verts()?; self.upload_verts()?;
let set0 = viewport.get_rect_descriptor(&self.pipeline); let cache = match self.pass.take() {
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline); Some(p) if p.res == res => p,
let pass = self.pipeline.color_rect.create_pass( _ => {
[vp[0] as _, vp[1] as _], let set0 = viewport.get_rect_descriptor(&self.pipeline);
self.vert_buffer.clone(), let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
0..4, let pass = self.pipeline.color_rect.create_pass(
0..self.rect_vertices.len() as _, [res[0] as _, res[1] as _],
vec![set0, set1], self.vert_buffer.clone(),
)?; 0..4,
0..self.rect_vertices.len() as _,
vec![set0, set1],
)?;
CachedPass { pass, res }
}
};
self.rect_vertices.clear(); self.rect_vertices.clear();
cmd_buf.run_ref(&cache.pass)?;
cmd_buf.run_ref(&pass) self.pass = Some(cache);
Ok(())
} }
} }

View File

@@ -1,5 +1,5 @@
use crate::{ use crate::{
gfx::cmd::GfxCommandBuffer, gfx::{cmd::GfxCommandBuffer, pass::WGfxPass},
renderer_vk::{model_buffer::ModelBuffer, viewport::Viewport}, renderer_vk::{model_buffer::ModelBuffer, viewport::Viewport},
}; };
@@ -15,6 +15,11 @@ use vulkano::{
command_buffer::CommandBufferUsage, command_buffer::CommandBufferUsage,
}; };
struct CachedPass {
pass: WGfxPass<GlyphVertex>,
res: [u32; 2],
}
/// A text renderer that uses cached glyphs to render text into an existing render pass. /// A text renderer that uses cached glyphs to render text into an existing render pass.
pub struct TextRenderer { pub struct TextRenderer {
pipeline: TextPipeline, pipeline: TextPipeline,
@@ -22,6 +27,7 @@ pub struct TextRenderer {
vertex_buffer_capacity: usize, vertex_buffer_capacity: usize,
glyph_vertices: Vec<GlyphVertex>, glyph_vertices: Vec<GlyphVertex>,
model_buffer: ModelBuffer, model_buffer: ModelBuffer,
pass: Option<CachedPass>,
} }
impl TextRenderer { impl TextRenderer {
@@ -41,6 +47,7 @@ impl TextRenderer {
vertex_buffer, vertex_buffer,
vertex_buffer_capacity: INITIAL_CAPACITY, vertex_buffer_capacity: INITIAL_CAPACITY,
glyph_vertices: Vec::new(), glyph_vertices: Vec::new(),
pass: None,
}) })
} }
@@ -250,26 +257,33 @@ impl TextRenderer {
return Ok(()); return Ok(());
} }
let res = viewport.resolution();
self.model_buffer.upload(&atlas.common.gfx)?; self.model_buffer.upload(&atlas.common.gfx)?;
let descriptor_sets = vec![ let cache = match self.pass.take() {
atlas.color_atlas.image_descriptor.clone(), Some(p) if p.res == res => p,
atlas.mask_atlas.image_descriptor.clone(), _ => {
viewport.get_text_descriptor(&self.pipeline), let descriptor_sets = vec![
self.model_buffer.get_text_descriptor(&self.pipeline), atlas.color_atlas.image_descriptor.clone(),
]; atlas.mask_atlas.image_descriptor.clone(),
viewport.get_text_descriptor(&self.pipeline),
self.model_buffer.get_text_descriptor(&self.pipeline),
];
let res = viewport.resolution(); let pass = self.pipeline.inner.create_pass(
[res[0] as _, res[1] as _],
self.vertex_buffer.clone(),
0..4,
0..self.glyph_vertices.len() as u32,
descriptor_sets,
)?;
CachedPass { pass, res }
}
};
let pass = self.pipeline.inner.create_pass( cmd_buf.run_ref(&cache.pass)?;
[res[0] as _, res[1] as _], self.pass = Some(cache);
self.vertex_buffer.clone(), Ok(())
0..4,
0..self.glyph_vertices.len() as u32,
descriptor_sets,
)?;
cmd_buf.run_ref(&pass)
} }
} }

View File

@@ -237,7 +237,14 @@ where
} else { } else {
let _ = panel.layout.add_child( let _ = panel.layout.add_child(
div, div,
Div::create().unwrap(), Rectangle::create(RectangleParams {
border_color: wgui::drawing::Color::new(0., 0., 0., 0.),
color: wgui::drawing::Color::new(0., 0., 0., 0.),
border: 2.0,
round: WLength::Units(4.0),
..Default::default()
})
.unwrap(),
taffy::Style { taffy::Style {
size: my_size, size: my_size,
min_size: my_size, min_size: my_size,