From 849e2cd0910a468c1aa7b11cd855c685421781ae Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 10 Mar 2014 22:09:18 +0100 Subject: [PATCH] Handle texture non-bounce a bit better. This allows us to ignore the texture bounce flag when reading from a FlatInput, and also handles better the case where an YCbCrInput is read from multiple times (it's now bounced, which should be better for speed, I think). The main motivation, however, is to be able to control sampler state a bit less hackish in the future. --- effect.h | 9 +++++++++ effect_chain.cpp | 8 +++++--- flat_input.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/effect.h b/effect.h index ce07df4..14cbe30 100644 --- a/effect.h +++ b/effect.h @@ -167,6 +167,15 @@ public: // next effect set needs_texture_bounce()). virtual bool changes_output_size() const { return false; } + // Whether this effect is effectively sampling from a a single texture. + // If so, it will override needs_texture_bounce(); however, there are also + // two demands it needs to fulfill: + // + // 1. It needs to be an Input, ie. num_inputs() == 0. + // 2. It needs to allocate exactly one sampler in set_gl_state(), + // and allow dependent effects to change that sampler state. + virtual bool is_single_texture() const { return false; } + // If changes_output_size() is true, you must implement this to tell // the framework what output size you want. Also, you can set a // virtual width/height, which is the size the next effect (if any) diff --git a/effect_chain.cpp b/effect_chain.cpp index 7d19ac3..22ba189 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -359,13 +359,13 @@ void EffectChain::construct_glsl_programs(Node *output) for (unsigned i = 0; i < deps.size(); ++i) { bool start_new_phase = false; - // FIXME: If we sample directly from a texture, we won't need this. - if (node->effect->needs_texture_bounce()) { + if (node->effect->needs_texture_bounce() && + !deps[i]->effect->is_single_texture()) { start_new_phase = true; } if (deps[i]->outgoing_links.size() > 1) { - if (deps[i]->effect->num_inputs() > 0) { + if (!deps[i]->effect->is_single_texture()) { // More than one effect uses this as the input, // and it is not a texture itself. // The easiest thing to do (and probably also the safest @@ -373,6 +373,8 @@ void EffectChain::construct_glsl_programs(Node *output) // and then let the next passes read from that. start_new_phase = true; } else { + assert(deps[i]->effect->num_inputs() == 0); + // For textures, we try to be slightly more clever; // if none of our outputs need a bounce, we don't bounce // but instead simply use the effect many times. diff --git a/flat_input.h b/flat_input.h index 12a94d9..2f636f0 100644 --- a/flat_input.h +++ b/flat_input.h @@ -58,6 +58,7 @@ public: unsigned get_height() const { return height; } Colorspace get_color_space() const { return image_format.color_space; } GammaCurve get_gamma_curve() const { return image_format.gamma_curve; } + virtual bool is_single_texture() 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 -- 2.39.2