From 7c794ada8801ed51a6efb4f53e694d02d254dff3 Mon Sep 17 00:00:00 2001 From: Joe Wilm Date: Sun, 1 Jan 2017 19:19:15 -0800 Subject: [PATCH] Improve error handling for shader initialization Shader initialization errors at startup should print a nice message now. --- src/display.rs | 16 +++++++++++++-- src/renderer/mod.rs | 50 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/display.rs b/src/display.rs index 2ddf1bdd..ab6cbc07 100644 --- a/src/display.rs +++ b/src/display.rs @@ -24,7 +24,7 @@ use cli; use config::Config; use font::{self, Rasterize}; use meter::Meter; -use renderer::{GlyphCache, QuadRenderer}; +use renderer::{self, GlyphCache, QuadRenderer}; use selection::Selection; use term::{Term, SizeInfo}; @@ -37,6 +37,9 @@ pub enum Error { /// Error dealing with fonts Font(font::Error), + + /// Error in renderer + Render(renderer::Error), } impl ::std::error::Error for Error { @@ -44,6 +47,7 @@ impl ::std::error::Error for Error { match *self { Error::Window(ref err) => Some(err), Error::Font(ref err) => Some(err), + Error::Render(ref err) => Some(err), } } @@ -51,6 +55,7 @@ impl ::std::error::Error for Error { match *self { Error::Window(ref err) => err.description(), Error::Font(ref err) => err.description(), + Error::Render(ref err) => err.description(), } } } @@ -60,6 +65,7 @@ impl ::std::fmt::Display for Error { match *self { Error::Window(ref err) => err.fmt(f), Error::Font(ref err) => err.fmt(f), + Error::Render(ref err) => err.fmt(f), } } } @@ -76,6 +82,12 @@ impl From for Error { } } +impl From for Error { + fn from(val: renderer::Error) -> Error { + Error::Render(val) + } +} + /// The display wraps a window, font rasterizer, and GPU renderer pub struct Display { window: Window, @@ -139,7 +151,7 @@ impl Display { let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr)?; // Create renderer - let mut renderer = QuadRenderer::new(config, size); + let mut renderer = QuadRenderer::new(config, size)?; // Initialize glyph cache let glyph_cache = { diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index cb8db636..d800a1b5 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -57,6 +57,42 @@ enum Msg { ShaderReload, } +#[derive(Debug)] +pub enum Error { + ShaderCreation(ShaderCreationError), +} + +impl ::std::error::Error for Error { + fn cause(&self) -> Option<&::std::error::Error> { + match *self { + Error::ShaderCreation(ref err) => Some(err), + } + } + + fn description(&self) -> &str { + match *self { + Error::ShaderCreation(ref err) => err.description(), + } + } +} + +impl ::std::fmt::Display for Error { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match *self { + Error::ShaderCreation(ref err) => { + write!(f, "There was an error initializing the shaders: {}", err) + } + } + } +} + +impl From for Error { + fn from(val: ShaderCreationError) -> Error { + Error::ShaderCreation(val) + } +} + + /// Text drawing program /// /// Uniforms are prefixed with "u", and vertex attributes are prefixed with "a". @@ -395,8 +431,8 @@ const ATLAS_SIZE: i32 = 1024; impl QuadRenderer { // TODO should probably hand this a transform instead of width/height - pub fn new(config: &Config, size: Size>) -> QuadRenderer { - let program = ShaderProgram::new(size).unwrap(); + pub fn new(config: &Config, size: Size>) -> Result { + let program = ShaderProgram::new(size)?; let mut vao: GLuint = 0; let mut vbo: GLuint = 0; @@ -503,7 +539,7 @@ impl QuadRenderer { if cfg!(feature = "live-shader-reload") { ::std::thread::spawn(move || { let (tx, rx) = ::std::sync::mpsc::channel(); - let mut watcher = Watcher::new(tx).unwrap(); + let mut watcher = Watcher::new(tx).expect("create file watcher"); watcher.watch(TEXT_SHADER_F_PATH).expect("watch fragment shader"); watcher.watch(TEXT_SHADER_V_PATH).expect("watch vertex shader"); @@ -547,7 +583,7 @@ impl QuadRenderer { let atlas = Atlas::new(ATLAS_SIZE); renderer.atlas.push(atlas); - renderer + Ok(renderer) } pub fn update_config(&mut self, config: &Config) { @@ -625,7 +661,7 @@ impl QuadRenderer { }, ShaderCreationError::Compile(path, log) => { err_println!("Error compiling shader at {:?}", path); - io::copy(&mut log.as_bytes(), &mut io::stdout()).unwrap(); + let _ = io::copy(&mut log.as_bytes(), &mut io::stdout()); } } @@ -1094,9 +1130,9 @@ impl ::std::error::Error for ShaderCreationError { impl ::std::fmt::Display for ShaderCreationError { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { match *self { - ShaderCreationError::Io(ref err) => write!(f, "Error creating shader: {}", err), + ShaderCreationError::Io(ref err) => write!(f, "couldn't read shader: {}", err), ShaderCreationError::Compile(ref _path, ref s) => { - write!(f, "Error compiling shader: {}", s) + write!(f, "failed compiling shader: {}", s) }, } }