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:
committed by
Pekka Paalanen
parent
1600431e80
commit
4d5b2f3410
@@ -53,6 +53,7 @@ precision mediump float;
|
|||||||
* snippet.
|
* snippet.
|
||||||
*/
|
*/
|
||||||
compile_const int c_variant = DEF_VARIANT;
|
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;
|
compile_const bool c_green_tint = DEF_GREEN_TINT;
|
||||||
|
|
||||||
vec4
|
vec4
|
||||||
@@ -79,7 +80,6 @@ yuva2rgba(vec4 yuva)
|
|||||||
color_out.g = Y - 0.39176229 * su - 0.81296764 * sv;
|
color_out.g = Y - 0.39176229 * su - 0.81296764 * sv;
|
||||||
color_out.b = Y + 2.01723214 * su;
|
color_out.b = Y + 2.01723214 * su;
|
||||||
|
|
||||||
color_out.rgb *= yuva.w;
|
|
||||||
color_out.a = yuva.w;
|
color_out.a = yuva.w;
|
||||||
|
|
||||||
return color_out;
|
return color_out;
|
||||||
@@ -146,11 +146,18 @@ main()
|
|||||||
{
|
{
|
||||||
vec4 color;
|
vec4 color;
|
||||||
|
|
||||||
/* Electrical (non-linear) RGBA values, pre-multiplied */
|
/* Electrical (non-linear) RGBA values, may be premult or not */
|
||||||
color = sample_input_texture();
|
color = sample_input_texture();
|
||||||
|
|
||||||
/* View alpha (opacity) */
|
/* Ensure premultiplied alpha, apply view alpha (opacity) */
|
||||||
color *= alpha;
|
if (c_input_is_premult) {
|
||||||
|
color *= alpha;
|
||||||
|
} else {
|
||||||
|
color.a *= alpha;
|
||||||
|
color.rgb *= color.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* color is guaranteed premult here */
|
||||||
|
|
||||||
if (c_green_tint)
|
if (c_green_tint)
|
||||||
color = vec4(0.0, 0.3, 0.0, 0.2) + color * 0.8;
|
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
|
struct gl_shader_requirements
|
||||||
{
|
{
|
||||||
unsigned variant:4; /* enum gl_shader_texture_variant */
|
unsigned variant:4; /* enum gl_shader_texture_variant */
|
||||||
|
bool input_is_premult:1;
|
||||||
bool green_tint:1;
|
bool green_tint:1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The total size of all bitfields plus pad_bits_ must fill up exactly
|
* The total size of all bitfields plus pad_bits_ must fill up exactly
|
||||||
* how many bytes the compiler allocates for them together.
|
* how many bytes the compiler allocates for them together.
|
||||||
*/
|
*/
|
||||||
unsigned pad_bits_:27;
|
unsigned pad_bits_:26;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(struct gl_shader_requirements) ==
|
static_assert(sizeof(struct gl_shader_requirements) ==
|
||||||
4 /* total bitfield size in bytes */,
|
4 /* total bitfield size in bytes */,
|
||||||
@@ -202,6 +203,9 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec);
|
|||||||
GLenum
|
GLenum
|
||||||
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v);
|
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
|
void
|
||||||
gl_shader_destroy(struct gl_renderer *gr, struct gl_shader *shader);
|
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) {
|
alt = (struct gl_shader_config) {
|
||||||
.req = {
|
.req = {
|
||||||
.variant = SHADER_VARIANT_SOLID,
|
.variant = SHADER_VARIANT_SOLID,
|
||||||
|
.input_is_premult = true,
|
||||||
},
|
},
|
||||||
.projection = sconf->projection,
|
.projection = sconf->projection,
|
||||||
.view_alpha = 1.0f,
|
.view_alpha = 1.0f,
|
||||||
@@ -925,6 +926,7 @@ maybe_censor_override(struct gl_shader_config *sconf,
|
|||||||
const struct gl_shader_config alt = {
|
const struct gl_shader_config alt = {
|
||||||
.req = {
|
.req = {
|
||||||
.variant = SHADER_VARIANT_SOLID,
|
.variant = SHADER_VARIANT_SOLID,
|
||||||
|
.input_is_premult = true,
|
||||||
},
|
},
|
||||||
.projection = sconf->projection,
|
.projection = sconf->projection,
|
||||||
.view_alpha = sconf->view_alpha,
|
.view_alpha = sconf->view_alpha,
|
||||||
@@ -960,6 +962,8 @@ gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
sconf->req.variant = gs->shader_variant;
|
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++)
|
for (i = 0; i < 4; i++)
|
||||||
sconf->unicolor[i] = gs->color[i];
|
sconf->unicolor[i] = gs->color[i];
|
||||||
@@ -1264,6 +1268,7 @@ draw_output_borders(struct weston_output *output,
|
|||||||
struct gl_shader_config sconf = {
|
struct gl_shader_config sconf = {
|
||||||
.req = {
|
.req = {
|
||||||
.variant = SHADER_VARIANT_RGBA,
|
.variant = SHADER_VARIANT_RGBA,
|
||||||
|
.input_is_premult = true,
|
||||||
},
|
},
|
||||||
.view_alpha = 1.0f,
|
.view_alpha = 1.0f,
|
||||||
};
|
};
|
||||||
@@ -1488,6 +1493,7 @@ blit_shadow_to_output(struct weston_output *output,
|
|||||||
const struct gl_shader_config sconf = {
|
const struct gl_shader_config sconf = {
|
||||||
.req = {
|
.req = {
|
||||||
.variant = SHADER_VARIANT_RGBA,
|
.variant = SHADER_VARIANT_RGBA,
|
||||||
|
.input_is_premult = true,
|
||||||
},
|
},
|
||||||
.projection = {
|
.projection = {
|
||||||
.d = { /* transpose */
|
.d = { /* transpose */
|
||||||
|
|||||||
@@ -147,8 +147,9 @@ create_shader_description_string(const struct gl_shader_requirements *req)
|
|||||||
int size;
|
int size;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
size = asprintf(&str, "%s %cgreen",
|
size = asprintf(&str, "%s %cinput_is_premult %cgreen",
|
||||||
gl_shader_texture_variant_to_string(req->variant),
|
gl_shader_texture_variant_to_string(req->variant),
|
||||||
|
req->input_is_premult ? '+' : '-',
|
||||||
req->green_tint ? '+' : '-');
|
req->green_tint ? '+' : '-');
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -163,8 +164,10 @@ create_shader_config_string(const struct gl_shader_requirements *req)
|
|||||||
|
|
||||||
size = asprintf(&str,
|
size = asprintf(&str,
|
||||||
"#define DEF_GREEN_TINT %s\n"
|
"#define DEF_GREEN_TINT %s\n"
|
||||||
|
"#define DEF_INPUT_IS_PREMULT %s\n"
|
||||||
"#define DEF_VARIANT %s\n",
|
"#define DEF_VARIANT %s\n",
|
||||||
req->green_tint ? "true" : "false",
|
req->green_tint ? "true" : "false",
|
||||||
|
req->input_is_premult ? "true" : "false",
|
||||||
gl_shader_texture_variant_to_string(req->variant));
|
gl_shader_texture_variant_to_string(req->variant));
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -349,6 +352,7 @@ gl_renderer_create_fallback_shader(struct gl_renderer *gr)
|
|||||||
{
|
{
|
||||||
static const struct gl_shader_requirements fallback_requirements = {
|
static const struct gl_shader_requirements fallback_requirements = {
|
||||||
.variant = SHADER_VARIANT_SOLID,
|
.variant = SHADER_VARIANT_SOLID,
|
||||||
|
.input_is_premult = true,
|
||||||
};
|
};
|
||||||
struct gl_shader *shader;
|
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
|
GLenum
|
||||||
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v)
|
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user