--- /dev/null
+#ifndef _EMBEDDED_FILES_H
+#define _EMBEDDED_FILES_H 1
+
+// Files that are embedded into the binary as part of the build process.
+// They are used as a backup if the files are not available on disk
+// (which is typically the case if the program is installed, as opposed to
+// being run during development).
+
+#include <stddef.h>
+
+extern const unsigned char *_binary_add_base_flow_frag_data;
+extern const size_t _binary_add_base_flow_frag_size;
+extern const unsigned char *_binary_blend_frag_data;
+extern const size_t _binary_blend_frag_size;
+extern const unsigned char *_binary_chroma_subsample_frag_data;
+extern const size_t _binary_chroma_subsample_frag_size;
+extern const unsigned char *_binary_chroma_subsample_vert_data;
+extern const size_t _binary_chroma_subsample_vert_size;
+extern const unsigned char *_binary_densify_frag_data;
+extern const size_t _binary_densify_frag_size;
+extern const unsigned char *_binary_densify_vert_data;
+extern const size_t _binary_densify_vert_size;
+extern const unsigned char *_binary_derivatives_frag_data;
+extern const size_t _binary_derivatives_frag_size;
+extern const unsigned char *_binary_diffusivity_frag_data;
+extern const size_t _binary_diffusivity_frag_size;
+extern const unsigned char *_binary_equations_frag_data;
+extern const size_t _binary_equations_frag_size;
+extern const unsigned char *_binary_equations_vert_data;
+extern const size_t _binary_equations_vert_size;
+extern const unsigned char *_binary_gray_frag_data;
+extern const size_t _binary_gray_frag_size;
+extern const unsigned char *_binary_hole_blend_frag_data;
+extern const size_t _binary_hole_blend_frag_size;
+extern const unsigned char *_binary_hole_fill_frag_data;
+extern const size_t _binary_hole_fill_frag_size;
+extern const unsigned char *_binary_hole_fill_vert_data;
+extern const size_t _binary_hole_fill_vert_size;
+extern const unsigned char *_binary_motion_search_frag_data;
+extern const size_t _binary_motion_search_frag_size;
+extern const unsigned char *_binary_motion_search_vert_data;
+extern const size_t _binary_motion_search_vert_size;
+extern const unsigned char *_binary_prewarp_frag_data;
+extern const size_t _binary_prewarp_frag_size;
+extern const unsigned char *_binary_resize_flow_frag_data;
+extern const size_t _binary_resize_flow_frag_size;
+extern const unsigned char *_binary_sobel_frag_data;
+extern const size_t _binary_sobel_frag_size;
+extern const unsigned char *_binary_sor_frag_data;
+extern const size_t _binary_sor_frag_size;
+extern const unsigned char *_binary_sor_vert_data;
+extern const size_t _binary_sor_vert_size;
+extern const unsigned char *_binary_splat_frag_data;
+extern const size_t _binary_splat_frag_size;
+extern const unsigned char *_binary_splat_vert_data;
+extern const size_t _binary_splat_vert_size;
+extern const unsigned char *_binary_vs_vert_data;
+extern const size_t _binary_vs_vert_size;
+
+#endif // !defined(_EMBEDDED_FILES_H)
#include "flow.h"
+#include "embedded_files.h"
#include "gpu_timers.h"
#include "util.h"
#include <algorithm>
#include <assert.h>
#include <deque>
+#include <dlfcn.h>
#include <epoxy/gl.h>
#include <map>
#include <memory>
return levels;
}
-string read_file(const string &filename)
+string read_file(const string &filename, const unsigned char *start = nullptr, const size_t size = 0)
{
FILE *fp = fopen(filename.c_str(), "r");
if (fp == nullptr) {
+ // Fall back to the version we compiled in. (We prefer disk if we can,
+ // since that makes it possible to work on shaders without recompiling
+ // all the time.)
+ if (start != nullptr) {
+ return string(reinterpret_cast<const char *>(start),
+ reinterpret_cast<const char *>(start) + size);
+ }
+
perror(filename.c_str());
exit(1);
}
exit(1);
}
- int size = ftell(fp);
+ int disk_size = ftell(fp);
ret = fseek(fp, 0, SEEK_SET);
if (ret == -1) {
}
string str;
- str.resize(size);
- ret = fread(&str[0], size, 1, fp);
+ str.resize(disk_size);
+ ret = fread(&str[0], disk_size, 1, fp);
if (ret == -1) {
perror("fread");
exit(1);
}
if (ret == 0) {
fprintf(stderr, "Short read when trying to read %d bytes from %s\n",
- size, filename.c_str());
+ disk_size, filename.c_str());
exit(1);
}
fclose(fp);
GrayscaleConversion::GrayscaleConversion()
{
- gray_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
- gray_fs_obj = compile_shader(read_file("gray.frag"), GL_FRAGMENT_SHADER);
+ gray_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
+ gray_fs_obj = compile_shader(read_file("gray.frag", _binary_gray_frag_data, _binary_gray_frag_size), GL_FRAGMENT_SHADER);
gray_program = link_program(gray_vs_obj, gray_fs_obj);
// Set up the VAO containing all the required position/texcoord data.
Sobel::Sobel()
{
- sobel_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
- sobel_fs_obj = compile_shader(read_file("sobel.frag"), GL_FRAGMENT_SHADER);
+ sobel_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
+ sobel_fs_obj = compile_shader(read_file("sobel.frag", _binary_sobel_frag_data, _binary_sobel_frag_size), GL_FRAGMENT_SHADER);
sobel_program = link_program(sobel_vs_obj, sobel_fs_obj);
uniform_tex = glGetUniformLocation(sobel_program, "tex");
MotionSearch::MotionSearch(const OperatingPoint &op)
: op(op)
{
- motion_vs_obj = compile_shader(read_file("motion_search.vert"), GL_VERTEX_SHADER);
- motion_fs_obj = compile_shader(read_file("motion_search.frag"), GL_FRAGMENT_SHADER);
+ motion_vs_obj = compile_shader(read_file("motion_search.vert", _binary_motion_search_vert_data, _binary_motion_search_vert_size), GL_VERTEX_SHADER);
+ motion_fs_obj = compile_shader(read_file("motion_search.frag", _binary_motion_search_frag_data, _binary_motion_search_frag_size), GL_FRAGMENT_SHADER);
motion_search_program = link_program(motion_vs_obj, motion_fs_obj);
uniform_inv_image_size = glGetUniformLocation(motion_search_program, "inv_image_size");
Densify::Densify(const OperatingPoint &op)
: op(op)
{
- densify_vs_obj = compile_shader(read_file("densify.vert"), GL_VERTEX_SHADER);
- densify_fs_obj = compile_shader(read_file("densify.frag"), GL_FRAGMENT_SHADER);
+ densify_vs_obj = compile_shader(read_file("densify.vert", _binary_densify_vert_data, _binary_densify_vert_size), GL_VERTEX_SHADER);
+ densify_fs_obj = compile_shader(read_file("densify.frag", _binary_densify_frag_data, _binary_densify_frag_size), GL_FRAGMENT_SHADER);
densify_program = link_program(densify_vs_obj, densify_fs_obj);
uniform_patch_size = glGetUniformLocation(densify_program, "patch_size");
Prewarp::Prewarp()
{
- prewarp_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
- prewarp_fs_obj = compile_shader(read_file("prewarp.frag"), GL_FRAGMENT_SHADER);
+ prewarp_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
+ prewarp_fs_obj = compile_shader(read_file("prewarp.frag", _binary_prewarp_frag_data, _binary_prewarp_frag_size), GL_FRAGMENT_SHADER);
prewarp_program = link_program(prewarp_vs_obj, prewarp_fs_obj);
uniform_image_tex = glGetUniformLocation(prewarp_program, "image_tex");
Derivatives::Derivatives()
{
- derivatives_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
- derivatives_fs_obj = compile_shader(read_file("derivatives.frag"), GL_FRAGMENT_SHADER);
+ derivatives_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
+ derivatives_fs_obj = compile_shader(read_file("derivatives.frag", _binary_derivatives_frag_data, _binary_derivatives_frag_size), GL_FRAGMENT_SHADER);
derivatives_program = link_program(derivatives_vs_obj, derivatives_fs_obj);
uniform_tex = glGetUniformLocation(derivatives_program, "tex");
ComputeDiffusivity::ComputeDiffusivity()
{
- diffusivity_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
- diffusivity_fs_obj = compile_shader(read_file("diffusivity.frag"), GL_FRAGMENT_SHADER);
+ diffusivity_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
+ diffusivity_fs_obj = compile_shader(read_file("diffusivity.frag", _binary_diffusivity_frag_data, _binary_diffusivity_frag_size), GL_FRAGMENT_SHADER);
diffusivity_program = link_program(diffusivity_vs_obj, diffusivity_fs_obj);
uniform_flow_tex = glGetUniformLocation(diffusivity_program, "flow_tex");
SetupEquations::SetupEquations()
{
- equations_vs_obj = compile_shader(read_file("equations.vert"), GL_VERTEX_SHADER);
- equations_fs_obj = compile_shader(read_file("equations.frag"), GL_FRAGMENT_SHADER);
+ equations_vs_obj = compile_shader(read_file("equations.vert", _binary_equations_vert_data, _binary_equations_vert_size), GL_VERTEX_SHADER);
+ equations_fs_obj = compile_shader(read_file("equations.frag", _binary_equations_frag_data, _binary_equations_frag_size), GL_FRAGMENT_SHADER);
equations_program = link_program(equations_vs_obj, equations_fs_obj);
uniform_I_x_y_tex = glGetUniformLocation(equations_program, "I_x_y_tex");
SOR::SOR()
{
- sor_vs_obj = compile_shader(read_file("sor.vert"), GL_VERTEX_SHADER);
- sor_fs_obj = compile_shader(read_file("sor.frag"), GL_FRAGMENT_SHADER);
+ sor_vs_obj = compile_shader(read_file("sor.vert", _binary_sor_vert_data, _binary_sor_vert_size), GL_VERTEX_SHADER);
+ sor_fs_obj = compile_shader(read_file("sor.frag", _binary_sor_frag_data, _binary_sor_frag_size), GL_FRAGMENT_SHADER);
sor_program = link_program(sor_vs_obj, sor_fs_obj);
uniform_diff_flow_tex = glGetUniformLocation(sor_program, "diff_flow_tex");
AddBaseFlow::AddBaseFlow()
{
- add_flow_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
- add_flow_fs_obj = compile_shader(read_file("add_base_flow.frag"), GL_FRAGMENT_SHADER);
+ add_flow_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
+ add_flow_fs_obj = compile_shader(read_file("add_base_flow.frag", _binary_add_base_flow_frag_data, _binary_add_base_flow_frag_size), GL_FRAGMENT_SHADER);
add_flow_program = link_program(add_flow_vs_obj, add_flow_fs_obj);
uniform_diff_flow_tex = glGetUniformLocation(add_flow_program, "diff_flow_tex");
ResizeFlow::ResizeFlow()
{
- resize_flow_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
- resize_flow_fs_obj = compile_shader(read_file("resize_flow.frag"), GL_FRAGMENT_SHADER);
+ resize_flow_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
+ resize_flow_fs_obj = compile_shader(read_file("resize_flow.frag", _binary_resize_flow_frag_data, _binary_resize_flow_frag_size), GL_FRAGMENT_SHADER);
resize_flow_program = link_program(resize_flow_vs_obj, resize_flow_fs_obj);
uniform_flow_tex = glGetUniformLocation(resize_flow_program, "flow_tex");
Splat::Splat(const OperatingPoint &op)
: op(op)
{
- splat_vs_obj = compile_shader(read_file("splat.vert"), GL_VERTEX_SHADER);
- splat_fs_obj = compile_shader(read_file("splat.frag"), GL_FRAGMENT_SHADER);
+ splat_vs_obj = compile_shader(read_file("splat.vert", _binary_splat_vert_data, _binary_splat_vert_size), GL_VERTEX_SHADER);
+ splat_fs_obj = compile_shader(read_file("splat.frag", _binary_splat_frag_data, _binary_splat_frag_size), GL_FRAGMENT_SHADER);
splat_program = link_program(splat_vs_obj, splat_fs_obj);
uniform_splat_size = glGetUniformLocation(splat_program, "splat_size");
HoleFill::HoleFill()
{
- fill_vs_obj = compile_shader(read_file("hole_fill.vert"), GL_VERTEX_SHADER);
- fill_fs_obj = compile_shader(read_file("hole_fill.frag"), GL_FRAGMENT_SHADER);
+ fill_vs_obj = compile_shader(read_file("hole_fill.vert", _binary_hole_fill_vert_data, _binary_hole_fill_vert_size), GL_VERTEX_SHADER);
+ fill_fs_obj = compile_shader(read_file("hole_fill.frag", _binary_hole_fill_frag_data, _binary_hole_fill_frag_size), GL_FRAGMENT_SHADER);
fill_program = link_program(fill_vs_obj, fill_fs_obj);
uniform_tex = glGetUniformLocation(fill_program, "tex");
HoleBlend::HoleBlend()
{
- blend_vs_obj = compile_shader(read_file("hole_fill.vert"), GL_VERTEX_SHADER); // Reuse the vertex shader from the fill.
- blend_fs_obj = compile_shader(read_file("hole_blend.frag"), GL_FRAGMENT_SHADER);
+ blend_vs_obj = compile_shader(read_file("hole_fill.vert", _binary_hole_fill_vert_data, _binary_hole_fill_vert_size), GL_VERTEX_SHADER); // Reuse the vertex shader from the fill.
+ blend_fs_obj = compile_shader(read_file("hole_blend.frag", _binary_hole_blend_frag_data, _binary_hole_blend_frag_size), GL_FRAGMENT_SHADER);
blend_program = link_program(blend_vs_obj, blend_fs_obj);
uniform_left_tex = glGetUniformLocation(blend_program, "left_tex");
Blend::Blend(bool split_ycbcr_output)
: split_ycbcr_output(split_ycbcr_output)
{
- string frag_shader = read_file("blend.frag");
+ string frag_shader = read_file("blend.frag", _binary_blend_frag_data, _binary_blend_frag_size);
if (split_ycbcr_output) {
// Insert after the first #version line.
size_t offset = frag_shader.find('\n');
frag_shader = frag_shader.substr(0, offset + 1) + "#define SPLIT_YCBCR_OUTPUT 1\n" + frag_shader.substr(offset + 1);
}
- blend_vs_obj = compile_shader(read_file("vs.vert"), GL_VERTEX_SHADER);
+ blend_vs_obj = compile_shader(read_file("vs.vert", _binary_vs_vert_data, _binary_vs_vert_size), GL_VERTEX_SHADER);
blend_fs_obj = compile_shader(frag_shader, GL_FRAGMENT_SHADER);
blend_program = link_program(blend_vs_obj, blend_fs_obj);
srcs += moc_files
srcs += proto_generated
+# Shaders needed at runtime.
+shaders = ['chroma_subsample.vert', 'densify.vert', 'equations.vert', 'hole_fill.vert', 'motion_search.vert', 'sor.vert', 'splat.vert', 'vs.vert']
+shaders += ['add_base_flow.frag', 'blend.frag', 'chroma_subsample.frag', 'densify.frag', 'derivatives.frag', 'diffusivity.frag',
+ 'equations.frag', 'gray.frag', 'hole_blend.frag', 'hole_fill.frag', 'motion_search.frag', 'prewarp.frag', 'resize_flow.frag',
+ 'sobel.frag', 'sor.frag', 'splat.frag']
+
+foreach shader : shaders
+ run_command('ln', '-s', join_paths(meson.current_source_dir(), shader), meson.current_build_dir())
+endforeach
+
+bin2h = executable('bin2h', 'bin2h.cpp')
+bin2h_gen = generator(bin2h, \
+ output : ['@PLAINNAME@.cpp'],
+ arguments : ['@INPUT@', '@PLAINNAME@', '@OUTPUT@'])
+shader_srcs = bin2h_gen.process(shaders)
+srcs += shader_srcs
+
executable('futatabi', srcs, dependencies: [qt5deps, libjpegdep, movitdep, libmicrohttpddep, protobufdep, sqlite3dep, vax11dep, vadrmdep, x11dep, libavformatdep, libavcodecdep, libavutildep, libswscaledep])
-executable('flow', 'flow_main.cpp', 'flow.cpp', 'gpu_timers.cpp', dependencies: [epoxydep, sdl2dep, sdl2_imagedep])
+executable('flow', 'flow_main.cpp', 'flow.cpp', 'gpu_timers.cpp', shader_srcs, dependencies: [epoxydep, sdl2dep, sdl2_imagedep])
executable('eval', 'eval.cpp', 'util.cpp')
executable('vis', 'vis.cpp', 'util.cpp')