// 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)
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
// 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.
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