node_map[effect] = node;
}
-void EffectChain::find_all_nonlinear_inputs(EffectChain::Node *node,
- std::vector<EffectChain::Node *> *nonlinear_inputs,
- std::vector<EffectChain::Node *> *intermediates)
+void EffectChain::find_all_nonlinear_inputs(Node *node,
+ std::vector<Node *> *nonlinear_inputs,
+ std::vector<Node *> *intermediates)
{
if (node->output_gamma_curve == GAMMA_LINEAR) {
return;
}
}
-EffectChain::Node *EffectChain::normalize_to_linear_gamma(EffectChain::Node *input)
+Node *EffectChain::normalize_to_linear_gamma(Node *input)
{
// Find out if all the inputs can be set to deliver sRGB inputs.
// If so, we can just ask them to do that instead of inserting a
return node;
}
-EffectChain::Node *EffectChain::normalize_to_srgb(EffectChain::Node *input)
+Node *EffectChain::normalize_to_srgb(Node *input)
{
assert(input->output_gamma_curve == GAMMA_LINEAR);
ColorSpaceConversionEffect *colorspace_conversion = new ColorSpaceConversionEffect();
return output;
}
-EffectChain::Phase *EffectChain::compile_glsl_program(
- const std::vector<EffectChain::Node *> &inputs,
- const std::vector<EffectChain::Node *> &effects)
+Phase *EffectChain::compile_glsl_program(
+ const std::vector<Node *> &inputs,
+ const std::vector<Node *> &effects)
{
assert(!effects.empty());
//
// We follow a quite simple depth-first search from the output, although
// without any explicit recursion.
-void EffectChain::construct_glsl_programs(EffectChain::Node *output)
+void EffectChain::construct_glsl_programs(Node *output)
{
// Which effects have already been completed in this phase?
// We need to keep track of it, as an effect with multiple outputs
std::reverse(phases.begin(), phases.end());
}
-void EffectChain::find_output_size(EffectChain::Phase *phase)
+void EffectChain::output_dot(const char *filename)
+{
+ FILE *fp = fopen(filename, "w");
+ if (fp == NULL) {
+ perror(filename);
+ exit(1);
+ }
+
+ fprintf(fp, "digraph G {\n");
+ for (unsigned i = 0; i < nodes.size(); ++i) {
+ fprintf(fp, " n%ld [label=\"%s\"];\n", (long)nodes[i], nodes[i]->effect->effect_type_id().c_str());
+ for (unsigned j = 0; j < nodes[i]->outgoing_links.size(); ++j) {
+ std::vector<std::string> labels;
+
+ if (nodes[i]->outgoing_links[j]->effect->needs_texture_bounce()) {
+ labels.push_back("needs_bounce");
+ }
+ if (nodes[i]->effect->changes_output_size()) {
+ labels.push_back("resize");
+ }
+
+ switch (nodes[i]->output_color_space) {
+ case COLORSPACE_REC_601_525:
+ labels.push_back("spc[rec601-525]");
+ break;
+ case COLORSPACE_REC_601_625:
+ labels.push_back("spc[rec601-625]");
+ break;
+ default:
+ break;
+ }
+
+ switch (nodes[i]->output_gamma_curve) {
+ case GAMMA_sRGB:
+ labels.push_back("gamma[sRGB]");
+ break;
+ case GAMMA_REC_601: // and GAMMA_REC_709
+ labels.push_back("gamma[rec601/709]");
+ break;
+ default:
+ break;
+ }
+
+ if (labels.empty()) {
+ fprintf(fp, " n%ld -> n%ld;\n", (long)nodes[i], (long)nodes[i]->outgoing_links[j]);
+ } else {
+ std::string label = labels[0];
+ for (unsigned k = 1; k < labels.size(); ++k) {
+ label += ", " + labels[k];
+ }
+ fprintf(fp, " n%ld -> n%ld [label=\"%s\"];\n", (long)nodes[i], (long)nodes[i]->outgoing_links[j], label.c_str());
+ }
+ }
+ }
+ fprintf(fp, "}\n");
+
+ fclose(fp);
+}
+
+void EffectChain::find_output_size(Phase *phase)
{
Node *output_node = phase->effects.back();
void EffectChain::finalize()
{
+ output_dot("final.dot");
+
// Find the output effect. This is, simply, one that has no outgoing links.
// If there are multiple ones, the graph is malformed (we do not support
// multiple outputs right now).