+ // Make sure the output rectangle is at least large enough to hold
+ // the given input rectangle in both dimensions, and is of the
+ // current aspect ratio (aspect_nom/aspect_denom).
+ void size_rectangle_to_fit(unsigned width, unsigned height, unsigned *output_width, unsigned *output_height);
+
+ // Compute the input sizes for all inputs for all effects in a given phase,
+ // and inform the effects about the results.
+ void inform_input_sizes(Phase *phase);
+
+ // Determine the preferred output size of a given phase.
+ // Requires that all input phases (if any) already have output sizes set.
+ void find_output_size(Phase *phase);
+
+ // Find all inputs eventually feeding into this effect that have
+ // output gamma different from GAMMA_LINEAR.
+ void find_all_nonlinear_inputs(Node *effect, std::vector<Node *> *nonlinear_inputs);
+
+ // Create a GLSL program computing the effects for this phase in order.
+ void compile_glsl_program(Phase *phase);
+
+ // Create all GLSL programs needed to compute the given effect, and all outputs
+ // that depend on it (whenever possible). Returns the phase that has <output>
+ // as the last effect. Also pushes all phases in order onto <phases>.
+ Phase *construct_phase(Node *output, std::map<Node *, Phase *> *completed_effects);
+
+ // Execute one phase, ie. set up all inputs, effects and outputs, and render the quad.
+ void execute_phase(Phase *phase, bool last_phase, std::map<Phase *, GLuint> *output_textures, std::set<Phase *> *generated_mipmaps);
+
+ // Set up uniforms for one phase. The program must already be bound.
+ void setup_uniforms(Phase *phase);
+
+ // Set up the given sampler number for sampling from an RTT texture.
+ void setup_rtt_sampler(int sampler_num, bool use_mipmaps);
+
+ // Output the current graph to the given file in a Graphviz-compatible format;
+ // only useful for debugging.
+ void output_dot(const char *filename);
+ std::vector<std::string> get_labels_for_edge(const Node *from, const Node *to);
+ void output_dot_edge(FILE *fp,
+ const std::string &from_node_id,
+ const std::string &to_node_id,
+ const std::vector<std::string> &labels);
+
+ // Some of the graph algorithms assume that the nodes array is sorted
+ // topologically (inputs are always before outputs), but some operations
+ // (like graph rewriting) can change that. This function restores that order.
+ void sort_all_nodes_topologically();
+
+ // Do the actual topological sort. <nodes> must be a connected, acyclic subgraph;
+ // links that go to nodes not in the set will be ignored.
+ std::vector<Node *> topological_sort(const std::vector<Node *> &nodes);
+
+ // Utility function used by topological_sort() to do a depth-first search.
+ // The reason why we store nodes left to visit instead of a more conventional
+ // list of nodes to visit is that we want to be able to limit ourselves to
+ // a subgraph instead of all nodes. The set thus serves a dual purpose.
+ void topological_sort_visit_node(Node *node, std::set<Node *> *nodes_left_to_visit, std::vector<Node *> *sorted_list);
+
+ // Used during finalize().
+ void find_color_spaces_for_inputs();
+ void propagate_alpha();
+ void propagate_gamma_and_color_space();
+ Node *find_output_node();
+
+ bool node_needs_colorspace_fix(Node *node);
+ void fix_internal_color_spaces();
+ void fix_output_color_space();
+
+ bool node_needs_alpha_fix(Node *node);
+ void fix_internal_alpha(unsigned step);
+ void fix_output_alpha();
+
+ bool node_needs_gamma_fix(Node *node);
+ void fix_internal_gamma_by_asking_inputs(unsigned step);
+ void fix_internal_gamma_by_inserting_nodes(unsigned step);
+ void fix_output_gamma();
+ void add_ycbcr_conversion_if_needed();
+ void add_dither_if_needed();
+
+ float aspect_nom, aspect_denom;
+ ImageFormat output_format;
+ OutputAlphaFormat output_alpha_format;
+
+ enum OutputColorType { OUTPUT_COLOR_RGB, OUTPUT_COLOR_YCBCR };
+ OutputColorType output_color_type;
+ YCbCrFormat output_ycbcr_format; // If output_color_type == OUTPUT_COLOR_YCBCR.
+ YCbCrOutputSplitting output_ycbcr_splitting; // If output_color_type == OUTPUT_COLOR_YCBCR.
+
+ std::vector<Node *> nodes;
+ std::map<Effect *, Node *> node_map;
+ Effect *dither_effect;
+
+ std::vector<Input *> inputs; // Also contained in nodes.
+ std::vector<Phase *> phases;
+
+ unsigned num_dither_bits;
+ OutputOrigin output_origin;
+ bool finalized;
+
+ ResourcePool *resource_pool;
+ bool owns_resource_pool;