Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compile in shaders to webrender instead of requiring a res directory #563

Merged
merged 3 commits into from Nov 17, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Build all shader source into a file, and use the compiled-in sources

  • Loading branch information
vvuk committed Nov 17, 2016
commit 45eae3fc949f31a44bc98bd8f6509f23c9c55f72
@@ -4,6 +4,7 @@ version = "0.9.0"
authors = ["Glenn Watson <gw@intuitionlibrary.com>"]
license = "MPL-2.0"
repository = "https://github.com/servo/webrender"
build = "build.rs"
workspace = ".."

[features]
@@ -0,0 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::env;
use std::path::{Path, PathBuf};
use std::io::prelude::*;
use std::fs::{canonicalize, read_dir, File};

fn write_shaders(glsl_files: Vec<PathBuf>, shader_file_path: &Path) {
let mut shader_file = File::create(shader_file_path).unwrap();

write!(shader_file, "/// AUTO GENERATED BY build.rs\n\n").unwrap();
write!(shader_file, "use std::collections::HashMap;\n").unwrap();
write!(shader_file, "lazy_static! {{\n").unwrap();
write!(shader_file, " pub static ref SHADERS: HashMap<&'static str, &'static str> = {{\n").unwrap();
write!(shader_file, " let mut h = HashMap::with_capacity({});\n", glsl_files.len()).unwrap();
for glsl in glsl_files {
let shader_name = glsl.file_name().unwrap().to_str().unwrap();
// strip .glsl
let shader_name = shader_name.replace(".glsl", "");
let full_path = canonicalize(&glsl).unwrap();
let full_name = full_path.as_os_str().to_str().unwrap();
// if someone is building on a network share, I'm sorry.
let full_name = full_name.replace("\\\\?\\", "");
let full_name = full_name.replace("\\", "/");
write!(shader_file, " h.insert(\"{}\", include_str!(\"{}\"));\n",
shader_name, full_name).unwrap();
}
write!(shader_file, " h\n").unwrap();
write!(shader_file, " }};\n").unwrap();
write!(shader_file, "}}\n").unwrap();
}

fn main() {
let out_dir = env::var("OUT_DIR").unwrap_or("out".to_owned());

let shaders_file = Path::new(&out_dir).join("shaders.rs");
let mut glsl_files = vec![];

let res_dir = Path::new("res");
for entry in read_dir(res_dir).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if entry.file_name().to_str().unwrap().ends_with(".glsl") {
glsl_files.push(path.to_owned());
}
}

write_shaders(glsl_files, &shaders_file);
}
@@ -9,11 +9,12 @@ use internal_types::{PackedVertex, PackedVertexForQuad};
use internal_types::{RenderTargetMode, TextureSampler};
use internal_types::{VertexAttribute, DebugFontVertex, DebugColorVertex, DEFAULT_TEXTURE};
//use notify::{self, Watcher};
use super::shader_source;
use std::collections::HashMap;
use std::fs::File;
use std::hash::BuildHasherDefault;
use std::io::Read;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::mem;
//use std::sync::mpsc::{channel, Sender};
//use std::thread;
@@ -37,7 +38,7 @@ const SHADER_VERSION: &'static str = "#version 150\n";
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
const SHADER_VERSION: &'static str = "#version 300 es\n";

static SHADER_PREAMBLE: &'static str = "shared.glsl";
static SHADER_PREAMBLE: &'static str = "shared";

pub type ViewportDimensions = [u32; 2];

@@ -67,6 +68,24 @@ pub enum VertexFormat {
DebugColor,
}

fn get_optional_shader_source(shader_name: &str, base_path: Option<&Path>) -> Option<String> {
if let Some(base) = base_path {
let shader_path = base.join(shader_name).with_extension("glsl");
if shader_path.exists() {
let mut source = String::new();
File::open(&shader_path).unwrap().read_to_string(&mut source).unwrap();
return Some(source);
}
}

shader_source::SHADERS.get(shader_name).and_then(|s| Some((*s).to_owned()))
}

fn get_shader_source(shader_name: &str, base_path: Option<&Path>) -> String {
get_optional_shader_source(shader_name, base_path)
.expect(&format!("Couldn't get required shader: {}", shader_name))
}

pub trait FileWatcherHandler : Send {
fn file_changed(&self, path: PathBuf);
}
@@ -325,8 +344,9 @@ impl Drop for Texture {
struct Program {
id: gl::GLuint,
u_transform: gl::GLint,
vs_path: PathBuf,
fs_path: PathBuf,
name: String,
vs_source: String,
fs_source: String,
prefix: Option<String>,
vs_id: Option<gl::GLuint>,
fs_id: Option<gl::GLuint>,
@@ -753,12 +773,8 @@ impl Device {
_file_changed_handler: Box<FileWatcherHandler>) -> Device {
//let file_watcher = FileWatcherThread::new(file_changed_handler);

let mut path = resource_path.clone();
path.push(SHADER_PREAMBLE);
let mut f = File::open(&path).unwrap();
let mut shader_preamble = String::new();
f.read_to_string(&mut shader_preamble).unwrap();
//file_watcher.add_watch(path);
let shader_preamble = get_shader_source(SHADER_PREAMBLE, Some(&resource_path));
//file_watcher.add_watch(resource_path);

Device {
resource_path: resource_path,
@@ -791,20 +807,20 @@ impl Device {
&self.capabilities
}

pub fn compile_shader(path: &PathBuf,
pub fn compile_shader(name: &str,
source_str: &str,
shader_type: gl::GLenum,
shader_preamble: &[String],
panic_on_fail: bool)
-> Option<gl::GLuint> {
debug!("compile {:?}", path);
debug!("compile {:?}", name);

let mut f = File::open(&path).unwrap();
let mut s = String::new();
s.push_str(SHADER_VERSION);
for prefix in shader_preamble {
s.push_str(&prefix);
}
f.read_to_string(&mut s).unwrap();
s.push_str(source_str);

let id = gl::create_shader(shader_type);
let mut source = Vec::new();
@@ -813,15 +829,15 @@ impl Device {
gl::compile_shader(id);
let log = gl::get_shader_info_log(id);
if gl::get_shader_iv(id, gl::COMPILE_STATUS) == (0 as gl::GLint) {
println!("Failed to compile shader: {:?}\n{}", path, log);
println!("Failed to compile shader: {:?}\n{}", name, log);
if panic_on_fail {
panic!("-- Shader compile failed - exiting --");
}

None
} else {
if !log.is_empty() {
println!("Warnings detected on shader: {:?}\n{}", path, log);
println!("Warnings detected on shader: {:?}\n{}", name, log);
}
Some(id)
}
@@ -1191,30 +1207,28 @@ impl Device {
debug_assert!(self.inside_frame);

let pid = gl::create_program();
let base_path = self.resource_path.join(base_filename);

let vs_path = base_path.with_extension("vs.glsl");
//self.file_watcher.add_watch(vs_path.clone());

let fs_path = base_path.with_extension("fs.glsl");
//self.file_watcher.add_watch(fs_path.clone());
let mut vs_name = String::from(base_filename);
vs_name.push_str(".vs");
let mut fs_name = String::from(base_filename);
fs_name.push_str(".fs");

let mut include = format!("// Base shader: {}\n", base_filename);
for inc_filename in include_filenames {
let include_path = self.resource_path.join(inc_filename).with_extension("glsl");
File::open(&include_path).unwrap().read_to_string(&mut include).unwrap();
let src = get_shader_source(inc_filename, Some(&self.resource_path));
include.push_str(&src);
}

let shared_path = base_path.with_extension("glsl");
if let Ok(mut f) = File::open(&shared_path) {
f.read_to_string(&mut include).unwrap();
}
if let Some(shared_src) = get_optional_shader_source(base_filename, Some(&self.resource_path)) {
include.push_str(&shared_src);
}

let program = Program {
name: base_filename.to_owned(),
id: pid,
u_transform: -1,
vs_path: vs_path,
fs_path: fs_path,
vs_source: get_shader_source(&vs_name, Some(&self.resource_path)),
fs_source: get_shader_source(&fs_name, Some(&self.resource_path)),
prefix: prefix,
vs_id: None,
fs_id: None,
@@ -1256,11 +1270,13 @@ impl Device {
fs_preamble.push(include);

// todo(gw): store shader ids so they can be freed!
let vs_id = Device::compile_shader(&program.vs_path,
let vs_id = Device::compile_shader(&program.name,
&program.vs_source,
gl::VERTEX_SHADER,
&vs_preamble,
panic_on_fail);
let fs_id = Device::compile_shader(&program.fs_path,
let fs_id = Device::compile_shader(&program.name,
&program.fs_source,
gl::FRAGMENT_SHADER,
&fs_preamble,
panic_on_fail);
@@ -72,6 +72,10 @@ mod texture_cache;
mod tiling;
mod util;

mod shader_source {
include!(concat!(env!("OUT_DIR"), "/shaders.rs"));
}

mod platform {
#[cfg(target_os="macos")]
pub use platform::macos::font;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.