Unbreak the final normalizers.
[movit] / effect_chain.h
1 #ifndef _EFFECT_CHAIN_H
2 #define _EFFECT_CHAIN_H 1
3
4 #include <set>
5 #include <vector>
6
7 #include "effect.h"
8 #include "effect_id.h"
9
10 enum PixelFormat { FORMAT_RGB, FORMAT_RGBA, FORMAT_BGR, FORMAT_BGRA };
11
12 enum ColorSpace {
13         COLORSPACE_sRGB = 0,
14         COLORSPACE_REC_709 = 0,  // Same as sRGB.
15         COLORSPACE_REC_601_525 = 1,
16         COLORSPACE_REC_601_625 = 2,
17 };
18
19 enum GammaCurve {
20         GAMMA_LINEAR = 0,
21         GAMMA_sRGB = 1,
22         GAMMA_REC_601 = 2,
23         GAMMA_REC_709 = 2,  // Same as Rec. 601.
24 };
25
26 struct ImageFormat {
27         PixelFormat pixel_format;
28         ColorSpace color_space;
29         GammaCurve gamma_curve;
30 };
31
32 class EffectChain {
33 public:
34         EffectChain(unsigned width, unsigned height);
35
36         // User API:
37         // input, effects, output, finalize need to come in that specific order.
38
39         void add_input(const ImageFormat &format);
40
41         // The returned pointer is owned by EffectChain.
42         Effect *add_effect(EffectId effect) {
43                 return add_effect(effect, last_added_effect());
44         }
45         Effect *add_effect(EffectId effect, Effect *input) {
46                 std::vector<Effect *> inputs;
47                 inputs.push_back(input);
48                 return add_effect(effect, inputs);
49         }
50         Effect *add_effect(EffectId effect, Effect *input1, Effect *input2) {
51                 std::vector<Effect *> inputs;
52                 inputs.push_back(input1);
53                 inputs.push_back(input2);
54                 return add_effect(effect, inputs);
55         }
56         Effect *add_effect(EffectId effect, const std::vector<Effect *> &inputs);
57
58         // Similar to add_effect, but:
59         //
60         //  * Does not insert any normalizing effects.
61         //  * Does not ask the effect to insert itself, so it won't work
62         //    with meta-effects.
63         //
64         // We should really separate out these two “sides” of Effect in the
65         // type system soon.
66         void add_effect_raw(Effect *effect, const std::vector<Effect *> &inputs);
67
68         void add_output(const ImageFormat &format);
69         void finalize();
70
71         //void render(unsigned char *src, unsigned char *dst);
72         void render_to_screen(unsigned char *src);
73
74         Effect *last_added_effect() {
75                 if (effects.empty()) {
76                         return NULL;
77                 } else {
78                         return effects.back();
79                 }       
80         }
81
82 private:
83         struct Phase {
84                 GLint glsl_program_num;
85                 bool input_needs_mipmaps;
86                 std::vector<Effect *> inputs;
87                 std::vector<Effect *> effects;  // In order.
88         };
89
90         Effect *normalize_to_linear_gamma(Effect *input);
91         Effect *normalize_to_srgb(Effect *input);
92
93         void draw_vertex(float x, float y, const std::vector<Effect *> &inputs);
94
95         // Create a GLSL program computing the given effects in order.
96         Phase compile_glsl_program(const std::vector<Effect *> &inputs, const std::vector<Effect *> &effects);
97
98         // Create all GLSL programs needed to compute the given effect, and all outputs
99         // that depends on it (whenever possible).
100         void construct_glsl_programs(Effect *start, std::set<Effect *> *completed_effects);
101
102         unsigned width, height;
103         ImageFormat input_format, output_format;
104         std::vector<Effect *> effects, unexpanded_effects;
105         std::map<Effect *, std::string> effect_ids;
106         std::map<Effect *, GLuint> effect_output_textures;
107         std::map<Effect *, std::vector<Effect *> > outgoing_links;
108         std::map<Effect *, std::vector<Effect *> > incoming_links;
109
110         GLuint source_image_num;
111         bool use_srgb_texture_format;
112
113         GLuint fbo;
114         std::vector<Phase> phases;
115
116         GLenum format, bytes_per_pixel;
117         bool finalized;
118
119         // Used during the building of the effect chain.
120         std::map<Effect *, ColorSpace> output_color_space;
121         std::map<Effect *, GammaCurve> output_gamma_curve;      
122 };
123
124
125 #endif // !defined(_EFFECT_CHAIN_H)