Prepare for a more DAG-like effect graph. Does not actually do anything differently...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 4 Oct 2012 20:27:08 +0000 (22:27 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 4 Oct 2012 20:27:08 +0000 (22:27 +0200)
blur_effect.cpp
blur_effect.h
effect.cpp
effect.h
effect_chain.cpp
effect_chain.h

index f2d5d03..8ffd6dd 100644 (file)
@@ -18,9 +18,9 @@ BlurEffect::BlurEffect() {
        vpass->set_int("direction", SingleBlurPassEffect::VERTICAL);
 }
 
-void BlurEffect::add_self_to_effect_chain(std::vector<Effect *> *chain) {
-       hpass->add_self_to_effect_chain(chain);
-       vpass->add_self_to_effect_chain(chain);
+void BlurEffect::add_self_to_effect_chain(EffectChain *chain, Effect *input) {
+       hpass->add_self_to_effect_chain(chain, input);
+       vpass->add_self_to_effect_chain(chain, hpass);
 }
 
 bool BlurEffect::set_float(const std::string &key, float value) {
index 3f86e17..b47d89b 100644 (file)
@@ -26,7 +26,7 @@ public:
 
        virtual bool needs_texture_bounce() const { return true; }
        virtual bool needs_mipmaps() const { return true; }
-       virtual void add_self_to_effect_chain(std::vector<Effect *> *chain);
+       virtual void add_self_to_effect_chain(EffectChain *chain, Effect *input);
        virtual bool set_float(const std::string &key, float value);
        
 private:
index 4f2bfd6..7f8dda2 100644 (file)
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <assert.h>
 #include "effect.h"
+#include "effect_chain.h"
 #include "util.h"
 
 #include <GL/gl.h>
@@ -169,6 +170,11 @@ void Effect::invalidate_1d_texture(const std::string &key)
        params_tex_1d[key].needs_update = true;
 }
 
+void Effect::add_self_to_effect_chain(EffectChain *chain, Effect *input)
+{
+       chain->add_effect_raw(this, input);
+}
+
 // Output convenience uniforms for each parameter.
 // These will be filled in per-frame.
 std::string Effect::output_convenience_uniforms() const
index 4191d4d..397d364 100644 (file)
--- a/effect.h
+++ b/effect.h
@@ -16,6 +16,8 @@
 
 #include <GL/gl.h>
 
+class EffectChain;
+
 // Can alias on a float[2].
 struct Point2D {
        Point2D(float x, float y)
@@ -96,9 +98,7 @@ public:
        // For most effects, the default will be fine, but for effects that
        // consist of multiple passes, it is often useful to replace this
        // with something that adds completely different things to the chain.
-       virtual void add_self_to_effect_chain(std::vector<Effect *> *chain) {
-               chain->push_back(this);
-       }
+       virtual void add_self_to_effect_chain(EffectChain *graph, Effect *input);
 
        // Outputs one GLSL uniform declaration for each registered parameter
        // (see below), with the right prefix prepended to each uniform name.
index 6362a09..a0e4b5a 100644 (file)
 #include "blur_effect.h"
 
 EffectChain::EffectChain(unsigned width, unsigned height)
-       : width(width), height(height), use_srgb_texture_format(false), finalized(false) {}
+       : width(width),
+         height(height),
+         last_added_effect(NULL),
+         use_srgb_texture_format(false),
+         finalized(false) {}
 
 void EffectChain::add_input(const ImageFormat &format)
 {
@@ -33,7 +37,15 @@ void EffectChain::add_output(const ImageFormat &format)
 {
        output_format = format;
 }
-       
+
+void EffectChain::add_effect_raw(Effect *effect, Effect *input)
+{
+       effects.push_back(effect);
+       outgoing_links.insert(std::make_pair(input, effect));
+       incoming_links.insert(std::make_pair(effect, input));
+       last_added_effect = effect;
+}
+
 Effect *instantiate_effect(EffectId effect)
 {
        switch (effect) {
@@ -59,42 +71,46 @@ Effect *instantiate_effect(EffectId effect)
        assert(false);
 }
 
-void EffectChain::normalize_to_linear_gamma()
+Effect *EffectChain::normalize_to_linear_gamma(Effect *input)
 {
        if (current_gamma_curve == GAMMA_sRGB) {
                // TODO: check if the extension exists
                use_srgb_texture_format = true;
+               current_gamma_curve = GAMMA_LINEAR;
+               return input;
        } else {
                GammaExpansionEffect *gamma_conversion = new GammaExpansionEffect();
                gamma_conversion->set_int("source_curve", current_gamma_curve);
-               gamma_conversion->add_self_to_effect_chain(&effects);
+               gamma_conversion->add_self_to_effect_chain(this, input);
+               current_gamma_curve = GAMMA_LINEAR;
+               return gamma_conversion;
        }
-       current_gamma_curve = GAMMA_LINEAR;
 }
 
-void EffectChain::normalize_to_srgb()
+Effect *EffectChain::normalize_to_srgb(Effect *input)
 {
        assert(current_gamma_curve == GAMMA_LINEAR);
        ColorSpaceConversionEffect *colorspace_conversion = new ColorSpaceConversionEffect();
        colorspace_conversion->set_int("source_space", current_color_space);
        colorspace_conversion->set_int("destination_space", COLORSPACE_sRGB);
-       colorspace_conversion->add_self_to_effect_chain(&effects);
+       colorspace_conversion->add_self_to_effect_chain(this, input);
        current_color_space = COLORSPACE_sRGB;
+       return colorspace_conversion;
 }
 
-Effect *EffectChain::add_effect(EffectId effect_id)
+Effect *EffectChain::add_effect(EffectId effect_id, Effect *input)
 {
        Effect *effect = instantiate_effect(effect_id);
 
        if (effect->needs_linear_light() && current_gamma_curve != GAMMA_LINEAR) {
-               normalize_to_linear_gamma();
+               input = normalize_to_linear_gamma(input);
        }
 
        if (effect->needs_srgb_primaries() && current_color_space != COLORSPACE_sRGB) {
-               normalize_to_srgb();
+               input = normalize_to_srgb(input);
        }
 
-       effect->add_self_to_effect_chain(&effects);
+       effect->add_self_to_effect_chain(this, input);
        return effect;
 }
 
@@ -193,7 +209,7 @@ void EffectChain::finalize()
        }
        if (current_gamma_curve != output_format.gamma_curve) {
                if (current_gamma_curve != GAMMA_LINEAR) {
-                       normalize_to_linear_gamma();
+                       normalize_to_linear_gamma(last_added_effect);  // FIXME
                }
                assert(current_gamma_curve == GAMMA_LINEAR);
                GammaCompressionEffect *gamma_conversion = new GammaCompressionEffect();
index 4abfb97..a22e96a 100644 (file)
@@ -32,12 +32,26 @@ class EffectChain {
 public:
        EffectChain(unsigned width, unsigned height);
 
+       // User API:
        // input, effects, output, finalize need to come in that specific order.
 
        void add_input(const ImageFormat &format);
 
        // The returned pointer is owned by EffectChain.
-       Effect *add_effect(EffectId effect);
+       Effect *add_effect(EffectId effect) {
+               return add_effect(effect, get_last_added_effect());
+       }
+       Effect *add_effect(EffectId effect, Effect *input);
+
+       // Similar to add_effect, but:
+       //
+       //  * Does not insert any normalizing effects.
+       //  * Does not ask the effect to insert itself, so it won't work
+       //    with meta-effects.
+       //
+       // We should really separate out these two “sides” of Effect in the
+       // type system soon.
+       void add_effect_raw(Effect *effect, Effect *input);
 
        void add_output(const ImageFormat &format);
        void finalize();
@@ -45,6 +59,10 @@ public:
        //void render(unsigned char *src, unsigned char *dst);
        void render_to_screen(unsigned char *src);
 
+       Effect *get_last_added_effect() { 
+               return last_added_effect;
+       }
+
 private:
        struct Phase {
                GLint glsl_program_num;
@@ -52,8 +70,8 @@ private:
                unsigned start, end;
        };
 
-       void normalize_to_linear_gamma();
-       void normalize_to_srgb();
+       Effect *normalize_to_linear_gamma(Effect *input);
+       Effect *normalize_to_srgb(Effect *input);
 
        // Create a GLSL program computing effects [start, end>.
        Phase compile_glsl_program(unsigned start_index, unsigned end_index);
@@ -61,6 +79,9 @@ private:
        unsigned width, height;
        ImageFormat input_format, output_format;
        std::vector<Effect *> effects;
+       std::multimap<Effect *, Effect *> outgoing_links;
+       std::multimap<Effect *, Effect *> incoming_links;
+       Effect *last_added_effect;
 
        GLuint source_image_num;
        bool use_srgb_texture_format;