]> git.sesse.net Git - movit/blobdiff - fft_input.h
Merge branch 'master' into epoxy
[movit] / fft_input.h
diff --git a/fft_input.h b/fft_input.h
new file mode 100644 (file)
index 0000000..b57723c
--- /dev/null
@@ -0,0 +1,81 @@
+#ifndef _MOVIT_FFT_INPUT_H
+#define _MOVIT_FFT_INPUT_H 1
+
+// FFTInput is used by FFTConvolutionEffect to send in the FFTed version of a
+// mostly static, one-channel data set, typically the convolution kernel
+// with some zero padding.
+//
+// Since the kernel is typically small and unlikely to change often,
+// it will be faster to FFT it once on the CPU (using the excellent FFTW3
+// library) and keep it in a texture, rather than FFT-ing it over and over on
+// the GPU. (We do not currently support caching Movit intermediates between
+// frames.) As an extra bonus, we can then do it in double precision and round
+// precisely to fp16 afterwards.
+//
+// This class is tested as part of by FFTConvolutionEffectTest.
+
+#include <epoxy/gl.h>
+#include <assert.h>
+#include <string>
+
+#include "effect.h"
+#include "effect_chain.h"
+#include "image_format.h"
+#include "input.h"
+
+namespace movit {
+
+class ResourcePool;
+
+class FFTInput : public Input {
+public:
+       FFTInput(unsigned width, unsigned height);
+       ~FFTInput();
+
+       virtual std::string effect_type_id() const { return "FFTInput"; }
+       std::string output_fragment_shader();
+
+       // FFTs the data and uploads the texture if it has changed since last time.
+       void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num);
+
+       unsigned get_width() const { return fft_width; }
+       unsigned get_height() const { return fft_height; }
+
+       // Strictly speaking, FFT data doesn't have any colorspace or gamma;
+       // these values are the Movit standards for “do nothing”.
+       Colorspace get_color_space() const { return COLORSPACE_sRGB; }
+       GammaCurve get_gamma_curve() const { return GAMMA_LINEAR; }
+       virtual AlphaHandling alpha_handling() const { return INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA; }
+       virtual bool is_single_texture() const { return true; }
+       virtual bool can_output_linear_gamma() const { return true; }
+
+       // Tells the input where to fetch the actual pixel data. Note that if you change
+       // this data, you must either call set_pixel_data() again (using the same pointer
+       // is fine), or invalidate_pixel_data(). Otherwise, the FFT won't be recalculated,
+       // and the texture won't be re-uploaded on subsequent frames.
+       void set_pixel_data(const float *pixel_data)
+       {
+               this->pixel_data = pixel_data;
+               invalidate_pixel_data();
+       }
+
+       void invalidate_pixel_data();
+
+       virtual void inform_added(EffectChain *chain)
+       {
+               resource_pool = chain->get_resource_pool();
+       }
+
+       virtual bool set_int(const std::string& key, int value);
+
+private:
+       GLuint texture_num;
+       int fft_width, fft_height;
+       unsigned convolve_width, convolve_height;
+       const float *pixel_data;
+       ResourcePool *resource_pool;
+};
+
+}  // namespace movit
+
+#endif // !defined(_MOVIT_FFT_INPUT_H)