]> git.sesse.net Git - nageru/blobdiff - flow.h
Allow symlinked frame files. Useful for testing.
[nageru] / flow.h
diff --git a/flow.h b/flow.h
index 0a6ea203c31517b9624cb8bb732e7a81136ac93f..08b25904356ab61265835e46cf219105c5ae88d2 100644 (file)
--- a/flow.h
+++ b/flow.h
@@ -5,12 +5,13 @@
 // in-between frames. The main user interface is the DISComputeFlow and Interpolate
 // classes (also GrayscaleConversion can be useful).
 
-#include <stdint.h>
-#include <epoxy/gl.h>
 #include <array>
+#include <epoxy/gl.h>
 #include <map>
-#include <vector>
+#include <mutex>
+#include <stdint.h>
 #include <utility>
+#include <vector>
 
 class ScopedTimer;
 
@@ -18,10 +19,10 @@ class ScopedTimer;
 struct OperatingPoint {
        unsigned coarsest_level;  // TODO: Adjust dynamically based on the resolution?
        unsigned finest_level;
-       unsigned search_iterations;  // TODO: Not implemented yet! Halved from the paper.
-       unsigned patch_size_pixels;  // TODO: Not implemented in the shader yet!
+       unsigned search_iterations;  // Halved from the paper.
+       unsigned patch_size_pixels;
        float patch_overlap_ratio;
-       bool variational_refinement;  // TODO: Actually disabling this is not implemented yet!
+       bool variational_refinement;
 
        // Not part of the original paper; used for interpolation.
        // NOTE: Values much larger than 1.0 seems to trigger Haswell's “PMA stall”;
@@ -78,6 +79,8 @@ static constexpr OperatingPoint operating_point4 = {
        8.0f    // Splat size (pixels).
 };
 
+int find_num_levels(int width, int height);
+
 // A class that caches FBOs that render to a given set of textures.
 // It never frees anything, so it is only suitable for rendering to
 // the same (small) set of textures over and over again.
@@ -108,7 +111,6 @@ private:
        std::map<std::array<GLuint, num_elements>, GLuint> fbos;
 };
 
-
 // Same, but with a depth texture.
 template<size_t num_elements>
 class PersistentFBOSetWithDepth {
@@ -178,10 +180,11 @@ private:
 // Motion search to find the initial flow. See motion_search.frag for documentation.
 class MotionSearch {
 public:
-       MotionSearch();
+       MotionSearch(const OperatingPoint &op);
        void exec(GLuint tex_view, GLuint grad_tex, GLuint flow_tex, GLuint flow_out_tex, int level_width, int level_height, int prev_level_width, int prev_level_height, int width_patches, int height_patches, int num_layers);
 
 private:
+       const OperatingPoint op;
        PersistentFBOSet<1> fbos;
 
        GLuint motion_vs_obj;
@@ -190,6 +193,7 @@ private:
 
        GLuint uniform_inv_image_size, uniform_inv_prev_level_size, uniform_out_flow_size;
        GLuint uniform_image_tex, uniform_grad_tex, uniform_flow_tex;
+       GLuint uniform_patch_size, uniform_num_iterations;
 };
 
 // Do “densification”, ie., upsampling of the flow patches to the flow field
@@ -379,6 +383,7 @@ private:
        GLuint uniform_scale_factor;
 };
 
+// All operations, except construction and destruction, are thread-safe.
 class TexturePool {
 public:
        GLuint get_texture(GLenum format, GLuint width, GLuint height, GLuint num_layers = 0);
@@ -394,7 +399,8 @@ private:
                bool in_use = false;
                bool is_renderbuffer = false;
        };
-       std::vector<Texture> textures;
+       std::mutex mu;
+       std::vector<Texture> textures;  // Under mu.
 };
 
 class DISComputeFlow {
@@ -415,7 +421,8 @@ public:
        // after use.
        GLuint exec(GLuint tex, FlowDirection flow_direction, ResizeStrategy resize_strategy);
 
-       void release_texture(GLuint tex) {
+       void release_texture(GLuint tex)
+       {
                pool.release_texture(tex);
        }
 
@@ -446,7 +453,7 @@ public:
        Splat(const OperatingPoint &op);
 
        // alpha is the time of the interpolated frame (0..1).
-       void exec(GLuint image_tex, GLuint bidirectional_flow_tex, GLuint flow_tex, GLuint depth_rb, int width, int height, float alpha);
+       void exec(GLuint gray_tex, GLuint bidirectional_flow_tex, GLuint flow_tex, GLuint depth_rb, int width, int height, float alpha);
 
 private:
        const OperatingPoint op;
@@ -457,7 +464,7 @@ private:
        GLuint splat_program;
 
        GLuint uniform_splat_size, uniform_alpha;
-       GLuint uniform_image_tex, uniform_flow_tex;
+       GLuint uniform_gray_tex, uniform_flow_tex;
        GLuint uniform_inv_flow_size;
 };
 
@@ -515,11 +522,15 @@ private:
 
 class Blend {
 public:
-       Blend();
-       void exec(GLuint image_tex, GLuint flow_tex, GLuint output_tex, int width, int height, float alpha);
+       Blend(bool split_ycbcr_output);
+
+       // output2_tex is only used if split_ycbcr_output was true.
+       void exec(GLuint image_tex, GLuint flow_tex, GLuint output_tex, GLuint output2_tex, int width, int height, float alpha);
 
 private:
+       bool split_ycbcr_output;
        PersistentFBOSet<1> fbos;
+       PersistentFBOSet<2> fbos_split;
        GLuint blend_vs_obj;
        GLuint blend_fs_obj;
        GLuint blend_program;
@@ -530,22 +541,23 @@ private:
 
 class Interpolate {
 public:
-       Interpolate(int width, int height, const OperatingPoint &op);
+       Interpolate(const OperatingPoint &op, bool split_ycbcr_output);
 
-       // Returns a texture that must be released with release_texture()
-       // after use. image_tex must be a two-layer RGBA8 texture with mipmaps
-       // (unless flow_level == 0).
-       GLuint exec(GLuint image_tex, GLuint bidirectional_flow_tex, GLuint width, GLuint height, float alpha);
+       // Returns a texture (or two, if split_ycbcr_output is true) that must
+       // be released with release_texture() after use. image_tex must be a
+       // two-layer RGBA8 texture with mipmaps (unless flow_level == 0).
+       std::pair<GLuint, GLuint> exec(GLuint image_tex, GLuint gray_tex, GLuint bidirectional_flow_tex, GLuint width, GLuint height, float alpha);
 
-       void release_texture(GLuint tex) {
+       void release_texture(GLuint tex)
+       {
                pool.release_texture(tex);
        }
 
 private:
-       int width, height, flow_level;
+       int flow_level;
        GLuint vertex_vbo, vao;
        TexturePool pool;
-       const OperatingPoint op;
+       const bool split_ycbcr_output;
 
        Splat splat;
        HoleFill hole_fill;