4 #include "effect_util.h"
5 #include "padding_effect.h"
12 PaddingEffect::PaddingEffect()
13 : border_color(0.0f, 0.0f, 0.0f, 0.0f),
18 border_offset_top(0.0f),
19 border_offset_left(0.0f),
20 border_offset_bottom(0.0f),
21 border_offset_right(0.0f)
23 register_vec4("border_color", (float *)&border_color);
24 register_int("width", &output_width);
25 register_int("height", &output_height);
26 register_float("top", &top);
27 register_float("left", &left);
28 register_float("border_offset_top", &border_offset_top);
29 register_float("border_offset_left", &border_offset_left);
30 register_float("border_offset_bottom", &border_offset_bottom);
31 register_float("border_offset_right", &border_offset_right);
34 string PaddingEffect::output_fragment_shader()
36 return read_file("padding_effect.frag");
39 void PaddingEffect::set_gl_state(GLuint glsl_program_num, const string &prefix, unsigned *sampler_num)
41 Effect::set_gl_state(glsl_program_num, prefix, sampler_num);
45 (output_height - input_height - top) / output_height
47 set_uniform_vec2(glsl_program_num, prefix, "offset", offset);
50 float(output_width) / input_width,
51 float(output_height) / input_height
53 set_uniform_vec2(glsl_program_num, prefix, "scale", scale);
55 float normalized_coords_to_texels[2] = {
56 float(input_width), float(input_height)
58 set_uniform_vec2(glsl_program_num, prefix, "normalized_coords_to_texels", normalized_coords_to_texels);
60 // Texels -0.5..0.5 should map to light level 0..1 (and then we
62 float offset_bottomleft[2] = {
63 0.5f - border_offset_left, 0.5f + border_offset_bottom,
66 // Texels size-0.5..size+0.5 should map to light level 1..0 (and then clamp).
67 float offset_topright[2] = {
68 input_width + 0.5f + border_offset_right, input_height + 0.5f - border_offset_top,
71 set_uniform_vec2(glsl_program_num, prefix, "offset_bottomleft", offset_bottomleft);
72 set_uniform_vec2(glsl_program_num, prefix, "offset_topright", offset_topright);
75 // We don't change the pixels of the image itself, so the only thing that
76 // can make us less flexible is if the border color can be interpreted
77 // differently in different modes.
79 // 0.0 and 1.0 are interpreted the same, no matter the gamma ramp.
80 // Alpha is not affected by gamma per se, but the combination of
81 // premultiplied alpha and non-linear gamma curve does not make sense,
82 // so if could possibly be converting blank alpha to non-blank
83 // (ie., premultiplied), we need our output to be in linear light.
84 bool PaddingEffect::needs_linear_light() const
86 if ((border_color.r == 0.0 || border_color.r == 1.0) &&
87 (border_color.g == 0.0 || border_color.g == 1.0) &&
88 (border_color.b == 0.0 || border_color.b == 1.0) &&
89 border_color.a == 1.0) {
95 // The white point is the same (D65) in all the color spaces we currently support,
96 // so any gray would be okay, but we don't really have a guarantee for that.
97 // Stay safe and say that only pure black and pure white is okay.
98 // Alpha is not affected by color space.
99 bool PaddingEffect::needs_srgb_primaries() const
101 if (border_color.r == 0.0 && border_color.g == 0.0 && border_color.b == 0.0) {
104 if (border_color.r == 1.0 && border_color.g == 1.0 && border_color.b == 1.0) {
110 Effect::AlphaHandling PaddingEffect::alpha_handling() const
112 // If the border color is black, it doesn't matter if we're pre- or postmultiplied.
113 // Note that for non-solid black (i.e. alpha < 1.0), we're equally fine with
114 // pre- and postmultiplied, but later effects might change this status
115 // (consider e.g. blur), so setting DONT_CARE_ALPHA_TYPE is inappropriate,
116 // as it propagate blank alpha through this effect.
117 if (border_color.r == 0.0 && border_color.g == 0.0 && border_color.b == 0.0 && border_color.a == 1.0) {
118 return DONT_CARE_ALPHA_TYPE;
121 // If the border color is solid, we preserve blank alpha, as we never output any
122 // new non-solid pixels.
123 if (border_color.a == 1.0) {
124 return INPUT_PREMULTIPLIED_ALPHA_KEEP_BLANK;
127 // Otherwise, we're going to output our border color in premultiplied alpha,
128 // so the other pixels better be premultiplied as well.
129 return INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA;
132 void PaddingEffect::get_output_size(unsigned *width, unsigned *height, unsigned *virtual_width, unsigned *virtual_height) const
134 *virtual_width = *width = output_width;
135 *virtual_height = *height = output_height;
138 void PaddingEffect::inform_input_size(unsigned input_num, unsigned width, unsigned height)
140 assert(input_num == 0);
142 input_height = height;
145 IntegralPaddingEffect::IntegralPaddingEffect() {}
147 bool IntegralPaddingEffect::set_int(const std::string &key, int value)
149 if (key == "top" || key == "left") {
150 return PaddingEffect::set_float(key, value);
152 return PaddingEffect::set_int(key, value);
156 bool IntegralPaddingEffect::set_float(const std::string &key, float value)
158 if (key == "top" || key == "left") {
159 // These are removed as float parameters from this version.
162 return PaddingEffect::set_float(key, value);