From cff79eadc9ecb9633d8b377d76f8bae46f8bba68 Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 2 Jul 2019 22:31:20 -0400 Subject: [PATCH] Add glyph cache resizing, move when resize occurs --- voxygen/src/ui/cache.rs | 42 ++++++++++++++++++++++++------- voxygen/src/ui/graphic/graphic.rs | 10 ++------ voxygen/src/ui/mod.rs | 23 +++++++++++------ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/voxygen/src/ui/cache.rs b/voxygen/src/ui/cache.rs index 7a45ff4268..ae88334fd3 100644 --- a/voxygen/src/ui/cache.rs +++ b/voxygen/src/ui/cache.rs @@ -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, @@ -17,13 +24,13 @@ pub struct Cache { impl Cache { pub fn new(renderer: &mut Renderer) -> Result { 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) { + // 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(()) } } diff --git a/voxygen/src/ui/graphic/graphic.rs b/voxygen/src/ui/graphic/graphic.rs index 45b7527652..7a6bc224fe 100644 --- a/voxygen/src/ui/graphic/graphic.rs +++ b/voxygen/src/ui/graphic/graphic.rs @@ -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)] diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index c004504e96..3d60f21d6e 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -101,6 +101,8 @@ pub struct Ui { ingame_locals: Vec>, // Window size for updating scaling window_resized: Option>, + // 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); } }