From 879854382e1f6db14812cd6bd5390ca01f4b1d5a Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 4 Oct 2012 22:27:08 +0200 Subject: [PATCH] Prepare for a more DAG-like effect graph. Does not actually do anything differently yet. --- blur_effect.cpp | 6 +++--- blur_effect.h | 2 +- effect.cpp | 6 ++++++ effect.h | 6 +++--- effect_chain.cpp | 40 ++++++++++++++++++++++++++++------------ effect_chain.h | 27 ++++++++++++++++++++++++--- 6 files changed, 65 insertions(+), 22 deletions(-) diff --git a/blur_effect.cpp b/blur_effect.cpp index f2d5d03..8ffd6dd 100644 --- a/blur_effect.cpp +++ b/blur_effect.cpp @@ -18,9 +18,9 @@ BlurEffect::BlurEffect() { vpass->set_int("direction", SingleBlurPassEffect::VERTICAL); } -void BlurEffect::add_self_to_effect_chain(std::vector *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) { diff --git a/blur_effect.h b/blur_effect.h index 3f86e17..b47d89b 100644 --- a/blur_effect.h +++ b/blur_effect.h @@ -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 *chain); + virtual void add_self_to_effect_chain(EffectChain *chain, Effect *input); virtual bool set_float(const std::string &key, float value); private: diff --git a/effect.cpp b/effect.cpp index 4f2bfd6..7f8dda2 100644 --- a/effect.cpp +++ b/effect.cpp @@ -4,6 +4,7 @@ #include #include #include "effect.h" +#include "effect_chain.h" #include "util.h" #include @@ -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 diff --git a/effect.h b/effect.h index 4191d4d..397d364 100644 --- a/effect.h +++ b/effect.h @@ -16,6 +16,8 @@ #include +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 *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. diff --git a/effect_chain.cpp b/effect_chain.cpp index 6362a09..a0e4b5a 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -20,7 +20,11 @@ #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(); diff --git a/effect_chain.h b/effect_chain.h index 4abfb97..a22e96a 100644 --- a/effect_chain.h +++ b/effect_chain.h @@ -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 effects; + std::multimap outgoing_links; + std::multimap incoming_links; + Effect *last_added_effect; GLuint source_image_num; bool use_srgb_texture_format; -- 2.39.2