From 8baa85998b90377f5ed0162e11fd94fd2d9c9d05 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 28 Sep 2024 10:49:01 +0200 Subject: [PATCH] Squashed commit of the following: commit 79098b2523f6009824d3992dc98c24944d49c784 Author: griffi-gh Date: Sat Sep 28 10:46:00 2024 +0200 Revert "wip integrate hui-painter instead of `hui::draw`" This reverts commit 3d01377eb29b15f170de977e10ad3eeceb5abe79. commit 3d01377eb29b15f170de977e10ad3eeceb5abe79 Author: griffi-gh Date: Fri Sep 27 21:42:58 2024 +0200 wip integrate hui-painter instead of `hui::draw` --- hui-painter/src/lib.rs | 6 ++- hui-painter/src/paint/command.rs | 26 +++++++++++-- hui-painter/src/paint/command/list.rs | 45 ++++++++++++++++++++++ hui-painter/src/paint/command/rectangle.rs | 4 +- hui-painter/src/paint/command/text.rs | 14 +++---- hui-painter/src/paint/command/transform.rs | 22 +++++------ hui-painter/src/text.rs | 4 +- hui-painter/src/texture/atlas.rs | 15 ++++++++ hui-painter/src/util.rs | 0 9 files changed, 106 insertions(+), 30 deletions(-) create mode 100644 hui-painter/src/paint/command/list.rs create mode 100644 hui-painter/src/util.rs diff --git a/hui-painter/src/lib.rs b/hui-painter/src/lib.rs index cb339e0..1983e57 100644 --- a/hui-painter/src/lib.rs +++ b/hui-painter/src/lib.rs @@ -1,17 +1,19 @@ pub mod paint; pub mod texture; pub mod text; +pub mod util; use text::FontManager; use texture::TextureAtlas; +/// Painter instance, stores textures and fonts needed for rendering #[derive(Default)] -pub struct Painter { +pub struct PainterInstance { pub atlas: TextureAtlas, pub fonts: FontManager, } -impl Painter { +impl PainterInstance { pub fn new() -> Self { Self::default() } diff --git a/hui-painter/src/paint/command.rs b/hui-painter/src/paint/command.rs index 106222e..f09c174 100644 --- a/hui-painter/src/paint/command.rs +++ b/hui-painter/src/paint/command.rs @@ -1,9 +1,12 @@ use glam::Vec2; -use crate::{paint::buffer::PaintBuffer, Painter}; +use crate::{paint::buffer::PaintBuffer, PainterInstance}; // mod root; // pub use root::RootCommand; +mod list; +pub use list::PaintList; + mod transform; pub use transform::PaintTransform; @@ -19,15 +22,30 @@ pub trait PaintCommand { /// /// Make sure to propagate this call to children! #[allow(unused_variables)] - fn pre_paint(&self, ctx: &mut Painter) {} + fn pre_paint(&self, ctx: &mut PainterInstance) {} /// Paint the command into the buffer /// /// Do not allocate new textures or cache glyphs here, use `pre_paint` instead!\ /// (Doing this WILL lead to atlas corruption flicker for a single frame if it's forced to resize!) - fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer); + fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer); } pub trait Measurable: PaintCommand { - fn size(&self, ctx: &Painter) -> Vec2; + fn size(&self, ctx: &PainterInstance) -> Vec2; } + +// TODO move paint_root to PaintCommand instead of separate trait? + +pub trait PaintRoot: PaintCommand { + /// Paint the root command, calling `pre_paint` before painting + /// + /// This is a convenience method for painting the root command + /// Do not use this inside the `paint` method of a command! + fn paint_root(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) { + self.pre_paint(ctx); + self.paint(ctx, into); + } +} + +impl PaintRoot for T {} diff --git a/hui-painter/src/paint/command/list.rs b/hui-painter/src/paint/command/list.rs new file mode 100644 index 0000000..e5eea89 --- /dev/null +++ b/hui-painter/src/paint/command/list.rs @@ -0,0 +1,45 @@ +use crate::PainterInstance; + +use super::PaintCommand; + +pub struct PaintList { + pub commands: Vec>, +} + +impl PaintList { + pub fn new(commands: Vec>) -> Self { + Self { + commands + } + } + + pub fn new_empty() -> Self { + Self { + commands: Vec::new(), + } + } + + pub fn add(&mut self, command: impl PaintCommand + 'static) { + self.commands.push(Box::new(command)); + } +} + +impl Default for PaintList { + fn default() -> Self { + Self::new_empty() + } +} + +impl PaintCommand for PaintList { + fn pre_paint(&self, ctx: &mut PainterInstance) { + for command in &self.commands { + command.pre_paint(ctx); + } + } + + fn paint(&self, ctx: &mut crate::PainterInstance, into: &mut crate::paint::buffer::PaintBuffer) { + for command in &self.commands { + command.paint(ctx, into); + } + } +} \ No newline at end of file diff --git a/hui-painter/src/paint/command/rectangle.rs b/hui-painter/src/paint/command/rectangle.rs index f18d64c..189ef47 100644 --- a/hui-painter/src/paint/command/rectangle.rs +++ b/hui-painter/src/paint/command/rectangle.rs @@ -7,7 +7,7 @@ use crate::{ command::PaintCommand, }, texture::TextureHandle, - Painter + PainterInstance }; /// Calculate the number of points based on the maximum corner radius @@ -92,7 +92,7 @@ impl PaintRectangle { } impl PaintCommand for PaintRectangle { - fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer) { + fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) { // If texture is set: // - Get texture UV // - Map local UVs to texture UV coords diff --git a/hui-painter/src/paint/command/text.rs b/hui-painter/src/paint/command/text.rs index ebdd7f7..6a09765 100644 --- a/hui-painter/src/paint/command/text.rs +++ b/hui-painter/src/paint/command/text.rs @@ -1,11 +1,11 @@ -use std::{borrow::Cow, sync::Arc}; -use fontdue::layout::{self, CoordinateSystem, GlyphRasterConfig, Layout}; +use std::borrow::Cow; +use fontdue::layout::{CoordinateSystem, Layout}; use glam::{vec2, Vec2}; use crate::{ paint::{ buffer::PaintBuffer, command::PaintCommand, - }, text::FontHandle, Painter + }, text::FontHandle, PainterInstance }; use super::Measurable; @@ -34,7 +34,7 @@ impl PaintText { } } - fn build_font_array<'a>(&self, ctx: &'a Painter) -> Vec<&'a fontdue::Font> { + fn build_font_array<'a>(&self, ctx: &'a PainterInstance) -> Vec<&'a fontdue::Font> { let font = ctx.fonts.get_fontdue_font(self.text.font) .expect("FontHandle is invalid"); vec![&font] @@ -55,7 +55,7 @@ impl PaintText { } impl PaintCommand for PaintText { - fn pre_paint(&self, ctx: &mut Painter) { + fn pre_paint(&self, ctx: &mut PainterInstance) { let font_array = self.build_font_array(ctx); let layout = self.build_layout(&font_array); @@ -64,7 +64,7 @@ impl PaintCommand for PaintText { } } - fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer) { + fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) { // let font_array = self.build_font_array(ctx); // let layout = self.build_layout(&font_array); @@ -80,7 +80,7 @@ impl PaintCommand for PaintText { } impl Measurable for PaintText { - fn size(&self, ctx: &Painter) -> Vec2 { + fn size(&self, ctx: &PainterInstance) -> Vec2 { let font_array = self.build_font_array(ctx); let layout = self.build_layout(&font_array); diff --git a/hui-painter/src/paint/command/transform.rs b/hui-painter/src/paint/command/transform.rs index 314709e..d390d4a 100644 --- a/hui-painter/src/paint/command/transform.rs +++ b/hui-painter/src/paint/command/transform.rs @@ -1,31 +1,27 @@ use crate::{ - Painter, + PainterInstance, paint::{ buffer::PaintBuffer, command::PaintCommand, }, }; -pub struct PaintTransform { +pub struct PaintTransform { pub transform: glam::Affine2, - pub children: Vec>, + pub child: T, } -impl PaintCommand for PaintTransform { - fn pre_paint(&self, ctx: &mut Painter) { - for child in &self.children { - child.pre_paint(ctx); - } +impl PaintCommand for PaintTransform { + fn pre_paint(&self, ctx: &mut PainterInstance) { + self.child.pre_paint(ctx); } - fn paint(&self, ctx: &mut Painter, into: &mut PaintBuffer) { + fn paint(&self, ctx: &mut PainterInstance, into: &mut PaintBuffer) { // remember the starting index let starting_index = into.vertices.len(); - // paint children nodes - for child in &self.children { - child.paint(ctx, into); - } + // paint children node + self.child.paint(ctx, into); let mut min_point = glam::Vec2::splat(f32::MAX); let mut max_point = glam::Vec2::splat(f32::MIN); diff --git a/hui-painter/src/text.rs b/hui-painter/src/text.rs index 9b8897b..03c51b7 100644 --- a/hui-painter/src/text.rs +++ b/hui-painter/src/text.rs @@ -23,7 +23,7 @@ impl FontManager { /// /// Panics: /// - If the font data is invalid. - pub fn add_font(&mut self, data: &[u8]) -> FontHandle { + pub fn add(&mut self, data: &[u8]) -> FontHandle { let font = self.fonts.add_font(data); self.ftm.init_font(font); font @@ -33,7 +33,7 @@ impl FontManager { /// /// Panics: /// - If the font handle is invalid. - pub fn remove_font(&mut self, font: FontHandle, atlas: &mut TextureAtlas) { + pub fn remove(&mut self, font: FontHandle, atlas: &mut TextureAtlas) { self.ftm.drop_font(font, atlas); self.fonts.remove_font(font); } diff --git a/hui-painter/src/texture/atlas.rs b/hui-painter/src/texture/atlas.rs index 1a2e1d1..de06fc1 100644 --- a/hui-painter/src/texture/atlas.rs +++ b/hui-painter/src/texture/atlas.rs @@ -141,6 +141,9 @@ pub struct TextureAtlas { /// Deallocated allocations that can be reused, sorted by size //TODO: use binary heap or btreeset for reuse_allocations instead, but this works for now reuse_allocations: Vec, + + /// Version of the texture atlas, incremented every time the atlas is modified + version: u64, } impl TextureAtlas { @@ -158,9 +161,19 @@ impl TextureAtlas { next_id: 0, allocations: HashMap::default(), reuse_allocations: Vec::new(), + version: 0, } } + pub fn version(&self) -> u64 { + self.version + } + + fn mark_modified(&mut self) { + // XXX: wrapping_add? will this *ever* overflow? + self.version = self.version.wrapping_add(1); + } + /// Get the next handle /// /// Does not allocate a texture associated with it @@ -303,6 +316,8 @@ impl TextureAtlas { } } } + + self.mark_modified(); } /// Allocate a texture in the atlas, returning a handle to it.\ diff --git a/hui-painter/src/util.rs b/hui-painter/src/util.rs new file mode 100644 index 0000000..e69de29