summaryrefslogtreecommitdiffstats
path: root/gfx/wr/swgl/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/wr/swgl/build.rs')
-rw-r--r--gfx/wr/swgl/build.rs148
1 files changed, 148 insertions, 0 deletions
diff --git a/gfx/wr/swgl/build.rs b/gfx/wr/swgl/build.rs
new file mode 100644
index 0000000000..b20dacd593
--- /dev/null
+++ b/gfx/wr/swgl/build.rs
@@ -0,0 +1,148 @@
+/* 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/. */
+
+extern crate cc;
+extern crate glsl_to_cxx;
+extern crate webrender_build;
+
+use std::collections::HashSet;
+use std::fmt::Write;
+use webrender_build::shader::{ShaderFeatureFlags, get_shader_features};
+
+// Shader key is in "name feature,feature" format.
+// File name needs to be formatted as "name_feature_feature".
+fn shader_file(shader_key: &str) -> String {
+ shader_key.replace(' ', "_").replace(',', "_")
+}
+
+fn write_load_shader(shader_keys: &[String]) {
+ let mut load_shader = String::new();
+ for s in shader_keys {
+ let _ = write!(load_shader, "#include \"{}.h\"\n", shader_file(s));
+ }
+ load_shader.push_str("ProgramLoader load_shader(const char* name) {\n");
+ for s in shader_keys {
+ let _ = write!(load_shader, " if (!strcmp(name, \"{}\")) {{ return {}_program::loader; }}\n",
+ s, shader_file(s));
+ }
+ load_shader.push_str(" return nullptr;\n}\n");
+ std::fs::write(std::env::var("OUT_DIR").unwrap() + "/load_shader.h", load_shader).unwrap();
+}
+
+fn process_imports(shader_dir: &str, shader: &str, included: &mut HashSet<String>, output: &mut String) {
+ if !included.insert(shader.into()) {
+ return;
+ }
+ println!("cargo:rerun-if-changed={}/{}.glsl", shader_dir, shader);
+ let source = std::fs::read_to_string(format!("{}/{}.glsl", shader_dir, shader)).unwrap();
+ for line in source.lines() {
+ if line.starts_with("#include ") {
+ let imports = line["#include ".len() ..].split(',');
+ for import in imports {
+ process_imports(shader_dir, import, included, output);
+ }
+ } else if line.starts_with("#version ") || line.starts_with("#extension ") {
+ // ignore
+ } else {
+ output.push_str(line);
+ output.push('\n');
+ }
+ }
+}
+
+fn translate_shader(shader_key: &str, shader_dir: &str) {
+ let mut imported = String::from("#define SWGL 1\n");
+ let _ = write!(imported, "#define WR_MAX_VERTEX_TEXTURE_WIDTH {}U\n",
+ webrender_build::MAX_VERTEX_TEXTURE_WIDTH);
+
+ let (basename, features) =
+ shader_key.split_at(shader_key.find(' ').unwrap_or(shader_key.len()));
+ if !features.is_empty() {
+ for feature in features.trim().split(',') {
+ let _ = write!(imported, "#define WR_FEATURE_{}\n", feature);
+ }
+ }
+
+ process_imports(shader_dir, basename, &mut HashSet::new(), &mut imported);
+
+ let shader = shader_file(shader_key);
+
+ let out_dir = std::env::var("OUT_DIR").unwrap();
+ let imp_name = format!("{}/{}.c", out_dir, shader);
+ std::fs::write(&imp_name, imported).unwrap();
+
+ let mut build = cc::Build::new();
+ if build.get_compiler().is_like_msvc() {
+ build.flag("/EP");
+ } else {
+ build.flag("-xc").flag("-P");
+ }
+ build.file(&imp_name);
+ let vs = build.clone()
+ .define("WR_VERTEX_SHADER", Some("1"))
+ .expand();
+ let fs = build.clone()
+ .define("WR_FRAGMENT_SHADER", Some("1"))
+ .expand();
+ let vs_name = format!("{}/{}.vert", out_dir, shader);
+ let fs_name = format!("{}/{}.frag", out_dir, shader);
+ std::fs::write(&vs_name, vs).unwrap();
+ std::fs::write(&fs_name, fs).unwrap();
+
+ let args = vec![
+ "glsl_to_cxx".to_string(),
+ vs_name,
+ fs_name,
+ ];
+ let result = glsl_to_cxx::translate(&mut args.into_iter());
+ std::fs::write(format!("{}/{}.h", out_dir, shader), result).unwrap();
+}
+
+fn main() {
+ let shader_dir = match std::env::var("MOZ_SRC") {
+ Ok(dir) => dir + "/gfx/wr/webrender/res",
+ Err(_) => std::env::var("CARGO_MANIFEST_DIR").unwrap() + "/../webrender/res",
+ };
+
+ let shader_flags =
+ ShaderFeatureFlags::GL |
+ ShaderFeatureFlags::DUAL_SOURCE_BLENDING |
+ ShaderFeatureFlags::DEBUG;
+ let mut shaders: Vec<String> = Vec::new();
+ for (name, features) in get_shader_features(shader_flags) {
+ shaders.extend(features.iter().map(|f| {
+ if f.is_empty() { name.to_owned() } else { format!("{} {}", name, f) }
+ }));
+ }
+
+ shaders.sort();
+
+ for shader in &shaders {
+ translate_shader(shader, &shader_dir);
+ }
+
+ write_load_shader(&shaders);
+
+ println!("cargo:rerun-if-changed=src/composite.h");
+ println!("cargo:rerun-if-changed=src/gl_defs.h");
+ println!("cargo:rerun-if-changed=src/glsl.h");
+ println!("cargo:rerun-if-changed=src/program.h");
+ println!("cargo:rerun-if-changed=src/swgl_ext.h");
+ println!("cargo:rerun-if-changed=src/texture.h");
+ println!("cargo:rerun-if-changed=src/vector_type.h");
+ println!("cargo:rerun-if-changed=src/gl.cc");
+ cc::Build::new()
+ .cpp(true)
+ .file("src/gl.cc")
+ .flag("-std=c++14")
+ .flag("-UMOZILLA_CONFIG_H")
+ .flag("-fno-exceptions")
+ .flag("-fno-rtti")
+ .flag("-fno-math-errno")
+ .define("_GLIBCXX_USE_CXX11_ABI", Some("0"))
+ .include(shader_dir)
+ .include("src")
+ .include(std::env::var("OUT_DIR").unwrap())
+ .compile("gl_cc");
+}