assert(ycbcr_format.chroma_subsampling_y == 1);
}
+void EffectChain::change_ycbcr_output_format(const YCbCrFormat &ycbcr_format)
+{
+ assert(output_color_ycbcr);
+ assert(output_ycbcr_format.chroma_subsampling_x == ycbcr_format.chroma_subsampling_x);
+ assert(output_ycbcr_format.chroma_subsampling_y == ycbcr_format.chroma_subsampling_y);
+ assert(fabs(output_ycbcr_format.cb_x_position - ycbcr_format.cb_x_position) < 1e-3);
+ assert(fabs(output_ycbcr_format.cb_y_position - ycbcr_format.cb_y_position) < 1e-3);
+ assert(fabs(output_ycbcr_format.cr_x_position - ycbcr_format.cr_x_position) < 1e-3);
+ assert(fabs(output_ycbcr_format.cr_y_position - ycbcr_format.cr_y_position) < 1e-3);
+
+ output_ycbcr_format = ycbcr_format;
+ if (finalized) {
+ // Find the YCbCrConversionEffect node. We don't store it to avoid
+ // an unneeded ABI break (this can be fixed on next break).
+ for (Node *node : nodes) {
+ if (node->effect->effect_type_id() == "YCbCrConversionEffect") {
+ YCbCrConversionEffect *effect = (YCbCrConversionEffect *)(node->effect);
+ effect->change_output_format(ycbcr_format);
+ }
+ }
+ }
+}
+
Node *EffectChain::add_node(Effect *effect)
{
for (unsigned i = 0; i < nodes.size(); ++i) {
if (alpha_handling == Effect::INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA ||
alpha_handling == Effect::INPUT_PREMULTIPLIED_ALPHA_KEEP_BLANK) {
// This combination (requiring premultiplied alpha, but _not_ requiring
- // linear light) is illegal, // since the combination
- // of premultiplied alpha and nonlinear inputs is
- // meaningless.
+ // linear light) is illegal, since the combination of premultiplied alpha
+ // and nonlinear inputs is meaningless.
assert(node->effect->needs_linear_light());
-
+
// If the effect has asked for premultiplied alpha, check that it has got it.
if (any_postmultiplied) {
node->output_alpha_type = ALPHA_INVALID;
output_textures->insert(make_pair(phase, tex_num));
}
- glUseProgram(phase->glsl_program_num);
- check_error();
-
// Set up RTT inputs for this phase.
for (unsigned sampler = 0; sampler < phase->inputs.size(); ++sampler) {
glActiveTexture(GL_TEXTURE0 + sampler);
glViewport(0, 0, phase->output_width, phase->output_height);
}
+ GLuint instance_program_num = resource_pool->use_glsl_program(phase->glsl_program_num);
+ check_error();
+
// Give the required parameters to all the effects.
unsigned sampler_num = phase->inputs.size();
for (unsigned i = 0; i < phase->effects.size(); ++i) {
Node *node = phase->effects[i];
unsigned old_sampler_num = sampler_num;
- node->effect->set_gl_state(phase->glsl_program_num, phase->effect_ids[node], &sampler_num);
+ node->effect->set_gl_state(instance_program_num, phase->effect_ids[node], &sampler_num);
check_error();
if (node->effect->is_single_texture()) {
node->effect->clear_gl_state();
}
+ resource_pool->unuse_glsl_program(instance_program_num);
+
if (!last_phase) {
resource_pool->release_fbo(fbo);
}