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 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 {
glyph_cache: GlyphCache<'static>,
glyph_cache_tex: Texture<UiPipeline>,
@ -17,13 +24,13 @@ pub struct Cache {
impl Cache {
pub fn new(renderer: &mut Renderer) -> Result<Self, Error> {
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 graphic_cache_dims = Vec2::new(w * 2, h * 2).map(|e| e.min(max_texture_size as u16));
let glyph_cache_dims = Vec2::new(w, h).map(|e| e.min(max_texture_size as u16));
let graphic_cache_dims =
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 {
glyph_cache: GlyphCache::builder()
@ -51,11 +58,28 @@ impl Cache {
pub fn add_graphic(&mut self, graphic: Graphic) -> GraphicId {
self.graphic_cache.add_graphic(graphic)
}
// new_window_size is in physical pixels
pub fn clear_graphic_cache(&mut self, renderer: &mut Renderer, new_window_size: Vec2<u16>) {
// Resizes and clears the GraphicCache
pub fn resize_graphic_cache(&mut self, renderer: &mut Renderer) -> Result<(), Error> {
let max_texture_size = renderer.max_texture_size();
let cache_size = new_window_size.map(|e| (e * 2).min(max_texture_size as u16));
self.graphic_cache.clear_cache(cache_size);
self.graphic_cache_tex = renderer.create_dynamic_texture(cache_size).unwrap();
let cache_dims = renderer
.get_resolution()
.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 fnv::{FnvHashMap, FnvHashSet};
use fnv::FnvHashMap;
use guillotiere::{size2, AllocId, Allocation, AtlasAllocator};
use image::{DynamicImage, RgbaImage};
use log::{error, warn};
use std::{
sync::{
mpsc::{channel, Receiver, Sender},
Arc,
},
thread,
};
use std::sync::Arc;
use vek::*;
#[derive(Clone)]

View File

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