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. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
1600431e80
commit
4d5b2f3410
@ -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;
|
||||
@ -146,11 +146,18 @@ 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;
|
||||
/* Ensure premultiplied alpha, apply view alpha (opacity) */
|
||||
if (c_input_is_premult) {
|
||||
color *= alpha;
|
||||
} else {
|
||||
color.a *= alpha;
|
||||
color.rgb *= color.a;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user