+// Where (0,0) is taken to be in the output. If you want to render to an
+// OpenGL screen, you should keep the default of bottom-left, as that is
+// OpenGL's natural coordinate system. However, there are cases, such as if you
+// render to an FBO and read the pixels back into some other system, where
+// you'd want a top-left origin; if so, an additional flip step will be added
+// at the very end (but done in a vertex shader, so it will have zero extra
+// cost).
+//
+// Note that Movit's coordinate system in general consistently puts (0,0) in
+// the top left for _input_, no matter what you set as output origin.
+enum OutputOrigin {
+ OUTPUT_ORIGIN_BOTTOM_LEFT,
+ OUTPUT_ORIGIN_TOP_LEFT,
+};
+
+// Transformation to apply (if any) to pixel data in temporary buffers.
+// See set_intermediate_format() below for more information.
+enum FramebufferTransformation {
+ // The default; just store the value. This is what you usually want.
+ NO_FRAMEBUFFER_TRANSFORMATION,
+
+ // If the values are in linear light, store sqrt(x) to the framebuffer
+ // instead of x itself, of course undoing it with x² on read. Useful as
+ // a rough approximation to the sRGB curve. (If the values are not in
+ // linear light, just store them as-is.)
+ SQUARE_ROOT_FRAMEBUFFER_TRANSFORMATION,
+};
+
+// A node in the graph; basically an effect and some associated information.
+class Node {
+public:
+ Effect *effect;
+ bool disabled;
+
+ // Edges in the graph (forward and backward).
+ std::vector<Node *> outgoing_links;
+ std::vector<Node *> incoming_links;
+
+ // For unit tests only. Do not use from other code.
+ // Will contain an arbitrary choice if the node is in multiple phases.
+ Phase *containing_phase;
+
+private:
+ // Logical size of the output of this effect, ie. the resolution
+ // you would get if you sampled it as a texture. If it is undefined
+ // (since the inputs differ in resolution), it will be 0x0.
+ // If both this and output_texture_{width,height} are set,
+ // they will be equal.
+ unsigned output_width, output_height;
+
+ // If the effect has is_single_texture(), or if the output went to RTT
+ // and that texture has been bound to a sampler, the sampler number
+ // will be stored here.
+ //
+ // TODO: Can an RTT texture be used as inputs to multiple effects
+ // within the same phase? If so, we have a problem with modifying
+ // sampler state here.
+ int bound_sampler_num;
+
+ // Used during the building of the effect chain.
+ Colorspace output_color_space;
+ GammaCurve output_gamma_curve;
+ AlphaType output_alpha_type;
+ bool needs_mipmaps; // Directly or indirectly.
+
+ // Set if this effect, and all effects consuming output from this node
+ // (in the same phase) have one_to_one_sampling() set.
+ bool one_to_one_sampling;
+
+ friend class EffectChain;
+};
+
+// A rendering phase; a single GLSL program rendering a single quad.
+struct Phase {
+ Node *output_node;
+
+ GLuint glsl_program_num; // Owned by the resource_pool.
+
+ // Position and texcoord attribute indexes, although it doesn't matter
+ // which is which, because they contain the same data.
+ std::set<GLint> attribute_indexes;
+
+ bool input_needs_mipmaps;
+
+ // Inputs are only inputs from other phases (ie., those that come from RTT);
+ // input textures are counted as part of <effects>.
+ std::vector<Phase *> inputs;
+ // Bound sampler numbers for each input. Redundant in a sense
+ // (it always corresponds to the index), but we need somewhere
+ // to hold the value for the uniform.
+ std::vector<int> input_samplers;
+ std::vector<Node *> effects; // In order.
+ unsigned output_width, output_height, virtual_output_width, virtual_output_height;
+
+ // Identifier used to create unique variables in GLSL.
+ // Unique per-phase to increase cacheability of compiled shaders.
+ std::map<Node *, std::string> effect_ids;
+
+ // Uniforms for this phase; combined from all the effects.
+ std::vector<Uniform<int> > uniforms_sampler2d;
+ std::vector<Uniform<bool> > uniforms_bool;
+ std::vector<Uniform<int> > uniforms_int;
+ std::vector<Uniform<float> > uniforms_float;
+ std::vector<Uniform<float> > uniforms_vec2;
+ std::vector<Uniform<float> > uniforms_vec3;
+ std::vector<Uniform<float> > uniforms_vec4;
+ std::vector<Uniform<Eigen::Matrix3d> > uniforms_mat3;
+
+ // For measurement of GPU time used.
+ std::list<GLuint> timer_query_objects_running;
+ std::list<GLuint> timer_query_objects_free;
+ uint64_t time_elapsed_ns;
+ uint64_t num_measured_iterations;