Skip to content
Snippets Groups Projects
Commit 25a4bb53 authored by Pekka Paalanen's avatar Pekka Paalanen
Browse files

gl-renderer: add shader bit input_is_premult


Add a new shader requirements bit input_is_premult which says whether
the texture sampling results in premultiplied alpha or not. Currently
this can be deduced fully from the shader texture variant, but in the
future there might a protocol extension to explicitly control it. Hence
the need for a new bit.

yuva2rgba() is changed to produce straight alpha always. This makes
sample_input_texture() sometimes produce straight or premultiplied
alpha. The input_is_premult bit needs to match sample_input_texture()
behavior. Doing this should save three multiplications in the shader for
straight alpha formats.

pipeline_premult() function is added, because in the future another
pipeline working on straight alpha will be needed.

Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
parent 819054ce
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !637. Comments created here will be created in the context of that merge request.
......@@ -53,6 +53,7 @@ precision mediump float;
* snippet.
*/
compile_const int c_variant = DEF_VARIANT;
compile_const bool c_input_is_premult = DEF_INPUT_IS_PREMULT;
compile_const bool c_green_tint = DEF_GREEN_TINT;
vec4
......@@ -79,7 +80,6 @@ yuva2rgba(vec4 yuva)
color_out.g = Y - 0.39176229 * su - 0.81296764 * sv;
color_out.b = Y + 2.01723214 * su;
color_out.rgb *= yuva.w;
color_out.a = yuva.w;
return color_out;
......@@ -141,16 +141,31 @@ sample_input_texture()
return yuva2rgba(yuva);
}
vec4
pipeline_premult(vec4 color, compile_const bool input_is_premult)
{
/* Ensure premultiplied alpha, apply view alpha (opacity) */
if (input_is_premult) {
color *= alpha;
} else {
color.a *= alpha;
color.rgb *= color.a;
}
return color;
}
void
main()
{
vec4 color;
/* Electrical (non-linear) RGBA values, pre-multiplied */
/* Electrical (non-linear) RGBA values, may be premult or not */
color = sample_input_texture();
/* View alpha (opacity) */
color *= alpha;
color = pipeline_premult(color, c_input_is_premult);
/* color is guaranteed premult here */
if (c_green_tint)
color = vec4(0.0, 0.3, 0.0, 0.2) + color * 0.8;
......
......@@ -62,13 +62,14 @@ enum gl_shader_texture_variant {
struct gl_shader_requirements
{
unsigned variant:4; /* enum gl_shader_texture_variant */
bool input_is_premult:1;
bool green_tint:1;
/*
* The total size of all bitfields plus pad_bits_ must fill up exactly
* how many bytes the compiler allocates for them together.
*/
unsigned pad_bits_:27;
unsigned pad_bits_:26;
};
static_assert(sizeof(struct gl_shader_requirements) ==
4 /* total bitfield size in bytes */,
......@@ -202,6 +203,9 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec);
GLenum
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v);
bool
gl_shader_texture_variant_can_be_premult(enum gl_shader_texture_variant v);
void
gl_shader_destroy(struct gl_renderer *gr, struct gl_shader *shader);
......
......@@ -738,6 +738,7 @@ triangle_fan_debug(struct gl_renderer *gr,
alt = (struct gl_shader_config) {
.req = {
.variant = SHADER_VARIANT_SOLID,
.input_is_premult = true,
},
.projection = sconf->projection,
.view_alpha = 1.0f,
......@@ -925,6 +926,7 @@ maybe_censor_override(struct gl_shader_config *sconf,
const struct gl_shader_config alt = {
.req = {
.variant = SHADER_VARIANT_SOLID,
.input_is_premult = true,
},
.projection = sconf->projection,
.view_alpha = sconf->view_alpha,
......@@ -960,6 +962,8 @@ gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
int i;
sconf->req.variant = gs->shader_variant;
sconf->req.input_is_premult =
gl_shader_texture_variant_can_be_premult(gs->shader_variant);
for (i = 0; i < 4; i++)
sconf->unicolor[i] = gs->color[i];
......@@ -1264,6 +1268,7 @@ draw_output_borders(struct weston_output *output,
struct gl_shader_config sconf = {
.req = {
.variant = SHADER_VARIANT_RGBA,
.input_is_premult = true,
},
.view_alpha = 1.0f,
};
......@@ -1488,6 +1493,7 @@ blit_shadow_to_output(struct weston_output *output,
const struct gl_shader_config sconf = {
.req = {
.variant = SHADER_VARIANT_RGBA,
.input_is_premult = true,
},
.projection = {
.d = { /* transpose */
......
......@@ -147,8 +147,9 @@ create_shader_description_string(const struct gl_shader_requirements *req)
int size;
char *str;
size = asprintf(&str, "%s %cgreen",
size = asprintf(&str, "%s %cinput_is_premult %cgreen",
gl_shader_texture_variant_to_string(req->variant),
req->input_is_premult ? '+' : '-',
req->green_tint ? '+' : '-');
if (size < 0)
return NULL;
......@@ -163,8 +164,10 @@ create_shader_config_string(const struct gl_shader_requirements *req)
size = asprintf(&str,
"#define DEF_GREEN_TINT %s\n"
"#define DEF_INPUT_IS_PREMULT %s\n"
"#define DEF_VARIANT %s\n",
req->green_tint ? "true" : "false",
req->input_is_premult ? "true" : "false",
gl_shader_texture_variant_to_string(req->variant));
if (size < 0)
return NULL;
......@@ -349,6 +352,7 @@ gl_renderer_create_fallback_shader(struct gl_renderer *gr)
{
static const struct gl_shader_requirements fallback_requirements = {
.variant = SHADER_VARIANT_SOLID,
.input_is_premult = true,
};
struct gl_shader *shader;
......@@ -415,6 +419,25 @@ gl_renderer_garbage_collect_programs(struct gl_renderer *gr)
}
}
bool
gl_shader_texture_variant_can_be_premult(enum gl_shader_texture_variant v)
{
switch (v) {
case SHADER_VARIANT_SOLID:
case SHADER_VARIANT_RGBA:
case SHADER_VARIANT_EXTERNAL:
return true;
case SHADER_VARIANT_NONE:
case SHADER_VARIANT_RGBX:
case SHADER_VARIANT_Y_U_V:
case SHADER_VARIANT_Y_UV:
case SHADER_VARIANT_Y_XUXV:
case SHADER_VARIANT_XYUV:
return false;
}
return true;
}
GLenum
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment