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.
This commit is contained in:
parent
ea07f03ac9
commit
e503baf2e7
|
@ -3,7 +3,6 @@ name = "alacritty"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Joe Wilm <joe@jwilm.com>"]
|
authors = ["Joe Wilm <joe@jwilm.com>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
exclude = ["res/*"]
|
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -21,6 +20,11 @@ vte = "0.1.2"
|
||||||
mio = "0.6"
|
mio = "0.6"
|
||||||
copypasta = { path = "./copypasta" }
|
copypasta = { path = "./copypasta" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
# Enabling this feature makes shaders automatically reload when changed
|
||||||
|
live-shader-reload = []
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
gl_generator = "0.5"
|
gl_generator = "0.5"
|
||||||
|
|
||||||
|
|
|
@ -31,5 +31,4 @@ void main()
|
||||||
alphaMask = vec4(texture(mask, TexCoords).rgb, 1.0);
|
alphaMask = vec4(texture(mask, TexCoords).rgb, 1.0);
|
||||||
color = vec4(fg, 1.0);
|
color = vec4(fg, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
@ -33,9 +32,18 @@ use term::{self, cell, Cell};
|
||||||
|
|
||||||
use super::Rgb;
|
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_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");
|
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
|
/// LoadGlyph allows for copying a rasterized glyph into graphics memory
|
||||||
pub trait LoadGlyph {
|
pub trait LoadGlyph {
|
||||||
/// Load the rasterized glyph into GPU memory
|
/// Load the rasterized glyph into GPU memory
|
||||||
|
@ -448,34 +456,36 @@ impl QuadRenderer {
|
||||||
let should_reload = Arc::new(AtomicBool::new(false));
|
let should_reload = Arc::new(AtomicBool::new(false));
|
||||||
let should_reload2 = should_reload.clone();
|
let should_reload2 = should_reload.clone();
|
||||||
|
|
||||||
::std::thread::spawn(move || {
|
if cfg!(feature = "live-shader-reload") {
|
||||||
let (tx, rx) = ::std::sync::mpsc::channel();
|
::std::thread::spawn(move || {
|
||||||
let mut watcher = Watcher::new(tx).unwrap();
|
let (tx, rx) = ::std::sync::mpsc::channel();
|
||||||
watcher.watch(TEXT_SHADER_F_PATH).expect("watch fragment shader");
|
let mut watcher = Watcher::new(tx).unwrap();
|
||||||
watcher.watch(TEXT_SHADER_V_PATH).expect("watch vertex shader");
|
watcher.watch(TEXT_SHADER_F_PATH).expect("watch fragment shader");
|
||||||
|
watcher.watch(TEXT_SHADER_V_PATH).expect("watch vertex shader");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let event = rx.recv().expect("watcher event");
|
let event = rx.recv().expect("watcher event");
|
||||||
let ::notify::Event { path, op } = event;
|
let ::notify::Event { path, op } = event;
|
||||||
|
|
||||||
if let Ok(op) = op {
|
if let Ok(op) = op {
|
||||||
if op.contains(op::RENAME) {
|
if op.contains(op::RENAME) {
|
||||||
continue;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is last event we see after saving in vim
|
if op.contains(op::IGNORED) {
|
||||||
should_reload2.store(true, Ordering::Relaxed);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
let mut renderer = QuadRenderer {
|
let mut renderer = QuadRenderer {
|
||||||
program: program,
|
program: program,
|
||||||
|
@ -751,9 +761,26 @@ impl ShaderProgram {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(width: u32, height: u32) -> Result<ShaderProgram, ShaderCreationError> {
|
pub fn new(width: u32, height: u32) -> Result<ShaderProgram, ShaderCreationError> {
|
||||||
let vertex_shader = ShaderProgram::create_shader(TEXT_SHADER_V_PATH, gl::VERTEX_SHADER)?;
|
let vertex_source = if cfg!(feature = "live-shader-reload") {
|
||||||
let fragment_shader = ShaderProgram::create_shader(TEXT_SHADER_F_PATH,
|
None
|
||||||
gl::FRAGMENT_SHADER)?;
|
} 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);
|
let program = ShaderProgram::create_program(vertex_shader, fragment_shader);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -855,11 +882,24 @@ impl ShaderProgram {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn create_shader(path: &str, kind: GLenum) -> Result<GLuint, ShaderCreationError> {
|
fn create_shader(
|
||||||
let source = CString::new(read_file(path)?).unwrap();
|
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 = unsafe {
|
||||||
let shader = gl::CreateShader(kind);
|
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);
|
gl::CompileShader(shader);
|
||||||
shader
|
shader
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue