Fix an issue where a (cached) shader program could be used from multiple
[movit] / ycbcr_conversion_effect.cpp
1 #include <epoxy/gl.h>
2 #include <assert.h>
3 #include <stdio.h>
4 #include <algorithm>
5 #include <Eigen/Core>
6 #include <Eigen/LU>
7
8 #include "ycbcr_conversion_effect.h"
9 #include "effect_util.h"
10 #include "util.h"
11 #include "ycbcr.h"
12
13 using namespace std;
14 using namespace Eigen;
15
16 namespace movit {
17
18 YCbCrConversionEffect::YCbCrConversionEffect(const YCbCrFormat &ycbcr_format)
19         : ycbcr_format(ycbcr_format)
20 {
21 }
22
23 string YCbCrConversionEffect::output_fragment_shader()
24 {
25         float offset[3];
26         Matrix3d ycbcr_to_rgb;
27         compute_ycbcr_matrix(ycbcr_format, offset, &ycbcr_to_rgb);
28
29         string frag_shader = output_glsl_mat3("PREFIX(ycbcr_matrix)", ycbcr_to_rgb.inverse());
30         frag_shader += output_glsl_vec3("PREFIX(offset)", offset[0], offset[1], offset[2]);
31
32         if (ycbcr_format.full_range) {
33                 // The card will clamp for us later.
34                 frag_shader += "#define YCBCR_CLAMP_RANGE 0\n";
35         } else {
36                 frag_shader += "#define YCBCR_CLAMP_RANGE 1\n";
37
38                 // These limits come from BT.601 page 8, or BT.701, page 5.
39                 // TODO: Use num_levels. Currently we support 8-bit levels only.
40                 frag_shader += output_glsl_vec3("PREFIX(ycbcr_min)", 16.0 / 255.0, 16.0 / 255.0, 16.0 / 255.0);
41                 frag_shader += output_glsl_vec3("PREFIX(ycbcr_max)", 235.0 / 255.0, 240.0 / 255.0, 240.0 / 255.0);
42         }
43
44         return frag_shader + read_file("ycbcr_conversion_effect.frag");
45 }
46
47 }  // namespace movit