]> git.sesse.net Git - movit/blob - fft_input.h
Release Movit 1.6.0.
[movit] / fft_input.h
1 #ifndef _MOVIT_FFT_INPUT_H
2 #define _MOVIT_FFT_INPUT_H 1
3
4 // FFTInput is used by FFTConvolutionEffect to send in the FFTed version of a
5 // mostly static, one-channel data set, typically the convolution kernel
6 // with some zero padding.
7 //
8 // Since the kernel is typically small and unlikely to change often,
9 // it will be faster to FFT it once on the CPU (using the excellent FFTW3
10 // library) and keep it in a texture, rather than FFT-ing it over and over on
11 // the GPU. (We do not currently support caching Movit intermediates between
12 // frames.) As an extra bonus, we can then do it in double precision and round
13 // precisely to fp16 afterwards.
14 //
15 // This class is tested as part of by FFTConvolutionEffectTest.
16
17 #include <epoxy/gl.h>
18 #include <assert.h>
19 #include <string>
20
21 #include "effect.h"
22 #include "effect_chain.h"
23 #include "image_format.h"
24 #include "input.h"
25
26 namespace movit {
27
28 class ResourcePool;
29
30 class FFTInput : public Input {
31 public:
32         FFTInput(unsigned width, unsigned height);
33         ~FFTInput();
34
35         std::string effect_type_id() const override { return "FFTInput"; }
36         std::string output_fragment_shader() override;
37
38         // FFTs the data and uploads the texture if it has changed since last time.
39         void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num) override;
40
41         unsigned get_width() const override { return fft_width; }
42         unsigned get_height() const override { return fft_height; }
43
44         // Strictly speaking, FFT data doesn't have any colorspace or gamma;
45         // these values are the Movit standards for “do nothing”.
46         Colorspace get_color_space() const override { return COLORSPACE_sRGB; }
47         GammaCurve get_gamma_curve() const override { return GAMMA_LINEAR; }
48         AlphaHandling alpha_handling() const override { return INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA; }
49         bool is_single_texture() const override { return true; }
50         bool can_output_linear_gamma() const override { return true; }
51         bool can_supply_mipmaps() const override { return false; }
52
53         // Tells the input where to fetch the actual pixel data. Note that if you change
54         // this data, you must either call set_pixel_data() again (using the same pointer
55         // is fine), or invalidate_pixel_data(). Otherwise, the FFT won't be recalculated,
56         // and the texture won't be re-uploaded on subsequent frames.
57         void set_pixel_data(const float *pixel_data)
58         {
59                 this->pixel_data = pixel_data;
60                 invalidate_pixel_data();
61         }
62
63         void invalidate_pixel_data();
64
65         void inform_added(EffectChain *chain) override
66         {
67                 resource_pool = chain->get_resource_pool();
68         }
69
70         bool set_int(const std::string& key, int value) override;
71
72 private:
73         GLuint texture_num;
74         int fft_width, fft_height;
75         unsigned convolve_width, convolve_height;
76         const float *pixel_data;
77         ResourcePool *resource_pool;
78         GLint uniform_tex;
79 };
80
81 }  // namespace movit
82
83 #endif // !defined(_MOVIT_FFT_INPUT_H)