aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2016-10-27 08:43:23 -0700
committerJoe Wilm <joe@jwilm.com>2016-10-27 08:43:23 -0700
commite503baf2e753a1cc8c287f10fb1460635d093168 (patch)
treebe8ee683c384186060a14c72ee44609dd1d529bc
parentea07f03ac901c366ed31da540711b84ca9e75602 (diff)
downloadalacritty-e503baf2e753a1cc8c287f10fb1460635d093168.tar.gz
alacritty-e503baf2e753a1cc8c287f10fb1460635d093168.zip
Live shader reloading is now a feature
Which means it can be disabled in release builds. No more working on a renderer feature and actually breaking the Alacritty your editor is running inside.
-rw-r--r--Cargo.toml6
-rw-r--r--res/text.f.glsl1
-rw-r--r--src/renderer/mod.rs96
3 files changed, 73 insertions, 30 deletions
diff --git a/Cargo.toml b/Cargo.toml
index f87a0cbe..d3132ddc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,7 +3,6 @@ name = "alacritty"
version = "0.1.0"
authors = ["Joe Wilm <joe@jwilm.com>"]
license = "Apache-2.0"
-exclude = ["res/*"]
build = "build.rs"
[dependencies]
@@ -21,6 +20,11 @@ vte = "0.1.2"
mio = "0.6"
copypasta = { path = "./copypasta" }
+[features]
+default = []
+# Enabling this feature makes shaders automatically reload when changed
+live-shader-reload = []
+
[build-dependencies]
gl_generator = "0.5"
diff --git a/res/text.f.glsl b/res/text.f.glsl
index 3bdcbe20..770c1a36 100644
--- a/res/text.f.glsl
+++ b/res/text.f.glsl
@@ -31,5 +31,4 @@ void main()
alphaMask = vec4(texture(mask, TexCoords).rgb, 1.0);
color = vec4(fg, 1.0);
}
-
}
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index 7ddf1d01..f1b30373 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::HashMap;
-use std::ffi::CString;
use std::fs::File;
use std::io::{self, Read};
use std::mem::size_of;
@@ -33,9 +32,18 @@ use term::{self, cell, Cell};
use super::Rgb;
+// Shader paths for live reload
static TEXT_SHADER_F_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.f.glsl");
static TEXT_SHADER_V_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.v.glsl");
+// Shader source which is used when live-shader-reload feature is disable
+static TEXT_SHADER_F: &'static str = include_str!(
+ concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.f.glsl")
+);
+static TEXT_SHADER_V: &'static str = include_str!(
+ concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.v.glsl")
+);
+
/// LoadGlyph allows for copying a rasterized glyph into graphics memory
pub trait LoadGlyph {
/// Load the rasterized glyph into GPU memory
@@ -448,34 +456,36 @@ impl QuadRenderer {
let should_reload = Arc::new(AtomicBool::new(false));
let should_reload2 = should_reload.clone();
- ::std::thread::spawn(move || {
- let (tx, rx) = ::std::sync::mpsc::channel();
- let mut watcher = Watcher::new(tx).unwrap();
- watcher.watch(TEXT_SHADER_F_PATH).expect("watch fragment shader");
- watcher.watch(TEXT_SHADER_V_PATH).expect("watch vertex shader");
+ if cfg!(feature = "live-shader-reload") {
+ ::std::thread::spawn(move || {
+ let (tx, rx) = ::std::sync::mpsc::channel();
+ let mut watcher = Watcher::new(tx).unwrap();
+ watcher.watch(TEXT_SHADER_F_PATH).expect("watch fragment shader");
+ watcher.watch(TEXT_SHADER_V_PATH).expect("watch vertex shader");
- loop {
- let event = rx.recv().expect("watcher event");
- let ::notify::Event { path, op } = event;
+ loop {
+ let event = rx.recv().expect("watcher event");
+ let ::notify::Event { path, op } = event;
- if let Ok(op) = op {
- if op.contains(op::RENAME) {
- continue;
- }
+ if let Ok(op) = op {
+ if op.contains(op::RENAME) {
+ continue;
+ }
- if op.contains(op::IGNORED) {
- if let Some(path) = path.as_ref() {
- if let Err(err) = watcher.watch(path) {
- println!("failed to establish watch on {:?}: {:?}", path, err);
+ if op.contains(op::IGNORED) {
+ if let Some(path) = path.as_ref() {
+ if let Err(err) = watcher.watch(path) {
+ println!("failed to establish watch on {:?}: {:?}", path, err);
+ }
}
- }
- // This is last event we see after saving in vim
- should_reload2.store(true, Ordering::Relaxed);
+ // This is last event we see after saving in vim
+ should_reload2.store(true, Ordering::Relaxed);
+ }
}
}
- }
- });
+ });
+ }
let mut renderer = QuadRenderer {
program: program,
@@ -751,9 +761,26 @@ impl ShaderProgram {
}
pub fn new(width: u32, height: u32) -> Result<ShaderProgram, ShaderCreationError> {
- let vertex_shader = ShaderProgram::create_shader(TEXT_SHADER_V_PATH, gl::VERTEX_SHADER)?;
- let fragment_shader = ShaderProgram::create_shader(TEXT_SHADER_F_PATH,
- gl::FRAGMENT_SHADER)?;
+ let vertex_source = if cfg!(feature = "live-shader-reload") {
+ None
+ } else {
+ Some(TEXT_SHADER_V)
+ };
+ let vertex_shader = ShaderProgram::create_shader(
+ TEXT_SHADER_V_PATH,
+ gl::VERTEX_SHADER,
+ vertex_source
+ )?;
+ let frag_source = if cfg!(feature = "live-shader-reload") {
+ None
+ } else {
+ Some(TEXT_SHADER_F)
+ };
+ let fragment_shader = ShaderProgram::create_shader(
+ TEXT_SHADER_F_PATH,
+ gl::FRAGMENT_SHADER,
+ frag_source
+ )?;
let program = ShaderProgram::create_program(vertex_shader, fragment_shader);
unsafe {
@@ -855,11 +882,24 @@ impl ShaderProgram {
}
- fn create_shader(path: &str, kind: GLenum) -> Result<GLuint, ShaderCreationError> {
- let source = CString::new(read_file(path)?).unwrap();
+ fn create_shader(
+ path: &str,
+ kind: GLenum,
+ source: Option<&'static str>
+ ) -> Result<GLuint, ShaderCreationError> {
+ let from_disk;
+ let source = if let Some(src) = source {
+ src
+ } else {
+ from_disk = read_file(path)?;
+ &from_disk[..]
+ };
+
+ let len: [GLint; 1] = [source.len() as GLint];
+
let shader = unsafe {
let shader = gl::CreateShader(kind);
- gl::ShaderSource(shader, 1, &source.as_ptr(), ptr::null());
+ gl::ShaderSource(shader, 1, &(source.as_ptr() as *const i8), len.as_ptr());
gl::CompileShader(shader);
shader
};