X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=fft_input.h;fp=fft_input.h;h=681876baa2476429b2fae0b6adbe65ddb2cfa4d1;hb=3ccf5fb197c9a72545affc0b7286349d5603b72e;hp=0000000000000000000000000000000000000000;hpb=74ac64b2e402247edf61271a4862e657da7fe135;p=movit diff --git a/fft_input.h b/fft_input.h new file mode 100644 index 0000000..681876b --- /dev/null +++ b/fft_input.h @@ -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 +#include +#include + +#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)