Squashed commit of the following:

commit 79098b2523f6009824d3992dc98c24944d49c784
Author: griffi-gh <prasol258@gmail.com>
Date:   Sat Sep 28 10:46:00 2024 +0200

    Revert "wip integrate hui-painter instead of `hui::draw`"

    This reverts commit 3d01377eb2.

commit 3d01377eb2
Author: griffi-gh <prasol258@gmail.com>
Date:   Fri Sep 27 21:42:58 2024 +0200

    wip integrate hui-painter instead of `hui::draw`
This commit is contained in:
griffi-gh 2024-09-28 10:49:01 +02:00
parent 108deeab34
commit 8baa85998b
9 changed files with 106 additions and 30 deletions

View file

@ -1,17 +1,19 @@
pub mod paint; pub mod paint;
pub mod texture; pub mod texture;
pub mod text; pub mod text;
pub mod util;
use text::FontManager; use text::FontManager;
use texture::TextureAtlas; use texture::TextureAtlas;
/// Painter instance, stores textures and fonts needed for rendering
#[derive(Default)] #[derive(Default)]
pub struct Painter { pub struct PainterInstance {
pub atlas: TextureAtlas, pub atlas: TextureAtlas,
pub fonts: FontManager, pub fonts: FontManager,
} }
impl Painter { impl PainterInstance {
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
} }

View file

@ -1,9 +1,12 @@
use glam::Vec2; use glam::Vec2;
use crate::{paint::buffer::PaintBuffer, Painter}; use crate::{paint::buffer::PaintBuffer, PainterInstance};
// mod root; // mod root;
// pub use root::RootCommand; // pub use root::RootCommand;
mod list;
pub use list::PaintList;
mod transform; mod transform;
pub use transform::PaintTransform; pub use transform::PaintTransform;
@ -19,15 +22,30 @@ pub trait PaintCommand {
/// ///
/// Make sure to propagate this call to children! /// Make sure to propagate this call to children!
#[allow(unused_variables)] #[allow(unused_variables)]
fn pre_paint(&self, ctx: &mut Painter) {} fn pre_paint(&self, ctx: &mut PainterInstance) {}
/// Paint the command into the buffer /// Paint the command into the buffer
/// ///
/// Do not allocate new textures or cache glyphs here, use `pre_paint` instead!\ /// 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!) /// (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 { 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<T: PaintCommand> PaintRoot for T {}

View file

@ -0,0 +1,45 @@
use crate::PainterInstance;
use super::PaintCommand;
pub struct PaintList {
pub commands: Vec<Box<dyn PaintCommand>>,
}
impl PaintList {
pub fn new(commands: Vec<Box<dyn PaintCommand>>) -> 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);
}
}
}

View file

@ -7,7 +7,7 @@ use crate::{
command::PaintCommand, command::PaintCommand,
}, },
texture::TextureHandle, texture::TextureHandle,
Painter PainterInstance
}; };
/// Calculate the number of points based on the maximum corner radius /// Calculate the number of points based on the maximum corner radius
@ -92,7 +92,7 @@ impl PaintRectangle {
} }
impl PaintCommand for 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: // If texture is set:
// - Get texture UV // - Get texture UV
// - Map local UVs to texture UV coords // - Map local UVs to texture UV coords

View file

@ -1,11 +1,11 @@
use std::{borrow::Cow, sync::Arc}; use std::borrow::Cow;
use fontdue::layout::{self, CoordinateSystem, GlyphRasterConfig, Layout}; use fontdue::layout::{CoordinateSystem, Layout};
use glam::{vec2, Vec2}; use glam::{vec2, Vec2};
use crate::{ use crate::{
paint::{ paint::{
buffer::PaintBuffer, buffer::PaintBuffer,
command::PaintCommand, command::PaintCommand,
}, text::FontHandle, Painter }, text::FontHandle, PainterInstance
}; };
use super::Measurable; 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) let font = ctx.fonts.get_fontdue_font(self.text.font)
.expect("FontHandle is invalid"); .expect("FontHandle is invalid");
vec![&font] vec![&font]
@ -55,7 +55,7 @@ impl PaintText {
} }
impl PaintCommand for 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 font_array = self.build_font_array(ctx);
let layout = self.build_layout(&font_array); 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 font_array = self.build_font_array(ctx);
// let layout = self.build_layout(&font_array); // let layout = self.build_layout(&font_array);
@ -80,7 +80,7 @@ impl PaintCommand for PaintText {
} }
impl Measurable 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 font_array = self.build_font_array(ctx);
let layout = self.build_layout(&font_array); let layout = self.build_layout(&font_array);

View file

@ -1,31 +1,27 @@
use crate::{ use crate::{
Painter, PainterInstance,
paint::{ paint::{
buffer::PaintBuffer, buffer::PaintBuffer,
command::PaintCommand, command::PaintCommand,
}, },
}; };
pub struct PaintTransform { pub struct PaintTransform<T: PaintCommand + 'static> {
pub transform: glam::Affine2, pub transform: glam::Affine2,
pub children: Vec<Box<dyn PaintCommand>>, pub child: T,
} }
impl PaintCommand for PaintTransform { impl<T: PaintCommand + 'static> PaintCommand for PaintTransform<T> {
fn pre_paint(&self, ctx: &mut Painter) { fn pre_paint(&self, ctx: &mut PainterInstance) {
for child in &self.children { self.child.pre_paint(ctx);
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 // remember the starting index
let starting_index = into.vertices.len(); let starting_index = into.vertices.len();
// paint children nodes // paint children node
for child in &self.children { self.child.paint(ctx, into);
child.paint(ctx, into);
}
let mut min_point = glam::Vec2::splat(f32::MAX); let mut min_point = glam::Vec2::splat(f32::MAX);
let mut max_point = glam::Vec2::splat(f32::MIN); let mut max_point = glam::Vec2::splat(f32::MIN);

View file

@ -23,7 +23,7 @@ impl FontManager {
/// ///
/// Panics: /// Panics:
/// - If the font data is invalid. /// - 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); let font = self.fonts.add_font(data);
self.ftm.init_font(font); self.ftm.init_font(font);
font font
@ -33,7 +33,7 @@ impl FontManager {
/// ///
/// Panics: /// Panics:
/// - If the font handle is invalid. /// - 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.ftm.drop_font(font, atlas);
self.fonts.remove_font(font); self.fonts.remove_font(font);
} }

View file

@ -141,6 +141,9 @@ pub struct TextureAtlas {
/// Deallocated allocations that can be reused, sorted by size /// Deallocated allocations that can be reused, sorted by size
//TODO: use binary heap or btreeset for reuse_allocations instead, but this works for now //TODO: use binary heap or btreeset for reuse_allocations instead, but this works for now
reuse_allocations: Vec<TextureAllocation>, reuse_allocations: Vec<TextureAllocation>,
/// Version of the texture atlas, incremented every time the atlas is modified
version: u64,
} }
impl TextureAtlas { impl TextureAtlas {
@ -158,9 +161,19 @@ impl TextureAtlas {
next_id: 0, next_id: 0,
allocations: HashMap::default(), allocations: HashMap::default(),
reuse_allocations: Vec::new(), 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 /// Get the next handle
/// ///
/// Does not allocate a texture associated with it /// 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.\ /// Allocate a texture in the atlas, returning a handle to it.\

0
hui-painter/src/util.rs Normal file
View file