Add glyph cache resizing, move when resize occurs

This commit is contained in:
Imbris 2019-07-02 22:31:20 -04:00
parent b5ed35fd27
commit cff79eadc9
3 changed files with 50 additions and 25 deletions

View File

@ -6,6 +6,13 @@ use crate::{
use conrod_core::text::GlyphCache; use conrod_core::text::GlyphCache;
use vek::*; use vek::*;
// Multiplied by current window size
const GLYPH_CACHE_SIZE: u16 = 1;
const GRAPHIC_CACHE_SIZE: u16 = 2;
// Glyph cache tolerances
const SCALE_TOLERANCE: f32 = 0.1;
const POSITION_TOLERANCE: f32 = 0.1;
pub struct Cache { pub struct Cache {
glyph_cache: GlyphCache<'static>, glyph_cache: GlyphCache<'static>,
glyph_cache_tex: Texture<UiPipeline>, glyph_cache_tex: Texture<UiPipeline>,
@ -17,13 +24,13 @@ pub struct Cache {
impl Cache { impl Cache {
pub fn new(renderer: &mut Renderer) -> Result<Self, Error> { pub fn new(renderer: &mut Renderer) -> Result<Self, Error> {
let (w, h) = renderer.get_resolution().into_tuple(); let (w, h) = renderer.get_resolution().into_tuple();
const SCALE_TOLERANCE: f32 = 0.1;
const POSITION_TOLERANCE: f32 = 0.1;
let max_texture_size = renderer.max_texture_size(); let max_texture_size = renderer.max_texture_size();
let graphic_cache_dims = Vec2::new(w * 2, h * 2).map(|e| e.min(max_texture_size as u16)); let graphic_cache_dims =
let glyph_cache_dims = Vec2::new(w, h).map(|e| e.min(max_texture_size as u16)); Vec2::new(w, h).map(|e| (e * GRAPHIC_CACHE_SIZE).min(max_texture_size as u16));
let glyph_cache_dims =
Vec2::new(w, h).map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size as u16));
Ok(Self { Ok(Self {
glyph_cache: GlyphCache::builder() glyph_cache: GlyphCache::builder()
@ -51,11 +58,28 @@ impl Cache {
pub fn add_graphic(&mut self, graphic: Graphic) -> GraphicId { pub fn add_graphic(&mut self, graphic: Graphic) -> GraphicId {
self.graphic_cache.add_graphic(graphic) self.graphic_cache.add_graphic(graphic)
} }
// new_window_size is in physical pixels // Resizes and clears the GraphicCache
pub fn clear_graphic_cache(&mut self, renderer: &mut Renderer, new_window_size: Vec2<u16>) { pub fn resize_graphic_cache(&mut self, renderer: &mut Renderer) -> Result<(), Error> {
let max_texture_size = renderer.max_texture_size(); let max_texture_size = renderer.max_texture_size();
let cache_size = new_window_size.map(|e| (e * 2).min(max_texture_size as u16)); let cache_dims = renderer
self.graphic_cache.clear_cache(cache_size); .get_resolution()
self.graphic_cache_tex = renderer.create_dynamic_texture(cache_size).unwrap(); .map(|e| (e * GRAPHIC_CACHE_SIZE).min(max_texture_size as u16));
self.graphic_cache.clear_cache(cache_dims);
self.graphic_cache_tex = renderer.create_dynamic_texture(cache_dims)?;
Ok(())
}
// Resizes and clears the GlyphCache
pub fn resize_glyph_cache(&mut self, renderer: &mut Renderer) -> Result<(), Error> {
let max_texture_size = renderer.max_texture_size();
let cache_dims = renderer
.get_resolution()
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size as u16));
self.glyph_cache = GlyphCache::builder()
.dimensions(cache_dims.x as u32, cache_dims.y as u32)
.scale_tolerance(SCALE_TOLERANCE)
.position_tolerance(POSITION_TOLERANCE)
.build();
self.glyph_cache_tex = renderer.create_dynamic_texture(cache_dims.map(|e| e as u16))?;
Ok(())
} }
} }

View File

@ -1,15 +1,9 @@
use dot_vox::DotVoxData; use dot_vox::DotVoxData;
use fnv::{FnvHashMap, FnvHashSet}; use fnv::FnvHashMap;
use guillotiere::{size2, AllocId, Allocation, AtlasAllocator}; use guillotiere::{size2, AllocId, Allocation, AtlasAllocator};
use image::{DynamicImage, RgbaImage}; use image::{DynamicImage, RgbaImage};
use log::{error, warn}; use log::{error, warn};
use std::{ use std::sync::Arc;
sync::{
mpsc::{channel, Receiver, Sender},
Arc,
},
thread,
};
use vek::*; use vek::*;
#[derive(Clone)] #[derive(Clone)]

View File

@ -101,6 +101,8 @@ pub struct Ui {
ingame_locals: Vec<Consts<UiLocals>>, ingame_locals: Vec<Consts<UiLocals>>,
// Window size for updating scaling // Window size for updating scaling
window_resized: Option<Vec2<f64>>, window_resized: Option<Vec2<f64>>,
// Used to delay cache resizing until after current frame is drawn
need_cache_resize: bool,
// Scaling of the ui // Scaling of the ui
scale: Scale, scale: Scale,
} }
@ -122,6 +124,7 @@ impl Ui {
default_globals: renderer.create_consts(&[Globals::default()])?, default_globals: renderer.create_consts(&[Globals::default()])?,
ingame_locals: Vec::new(), ingame_locals: Vec::new(),
window_resized: None, window_resized: None,
need_cache_resize: false,
scale, scale,
}) })
} }
@ -216,6 +219,15 @@ impl Ui {
None => return, None => return,
}; };
if self.need_cache_resize {
// Resize graphic cache
self.cache.resize_graphic_cache(renderer).unwrap();
// Resize glyph cache
self.cache.resize_glyph_cache(renderer).unwrap();
self.need_cache_resize = false;
}
self.draw_commands.clear(); self.draw_commands.clear();
let mut mesh = Mesh::new(); let mut mesh = Mesh::new();
@ -634,22 +646,17 @@ impl Ui {
}); });
// Handle window resizing. // Handle window resizing.
// TODO: avoid bluescreen
if let Some(new_dims) = self.window_resized.take() { if let Some(new_dims) = self.window_resized.take() {
let (old_w, old_h) = self.scale.scaled_window_size().into_tuple(); let (old_w, old_h) = self.scale.scaled_window_size().into_tuple();
self.scale.window_resized(new_dims, renderer); self.scale.window_resized(new_dims, renderer);
let (w, h) = self.scale.scaled_window_size().into_tuple(); let (w, h) = self.scale.scaled_window_size().into_tuple();
self.ui.handle_event(Input::Resize(w, h)); self.ui.handle_event(Input::Resize(w, h));
let res = renderer.get_resolution();
// Avoid panic in graphic cache when minimizing. // Avoid panic in graphic cache when minimizing.
// Avoid resetting cache if window size didn't change // Avoid resetting cache if window size didn't change
// Somewhat inefficient for elements that won't change size // Somewhat inefficient for elements that won't change size after a window resize
if res.x > 0 && res.y > 0 && !(old_w == w && old_h == h) { let res = renderer.get_resolution();
self.cache self.need_cache_resize = res.x > 0 && res.y > 0 && !(old_w == w && old_h == h);
.clear_graphic_cache(renderer, renderer.get_resolution());
}
// TODO: Probably need to resize glyph cache, see conrod's gfx backend for reference.
} }
} }