mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-08 10:08:00 +02:00
gl-renderer: Add OpenGL ES 2 support to texture swizzles
Fallback to shader based swizzling when OpenGL ES 3 isn't available. Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
parent
a990e8ceda
commit
be5c662bae
3 changed files with 113 additions and 17 deletions
|
|
@ -131,6 +131,9 @@ uniform sampler2D tex_wireframe;
|
|||
uniform float view_alpha;
|
||||
uniform vec4 unicolor;
|
||||
uniform vec4 tint;
|
||||
uniform ivec4 swizzle_idx[3];
|
||||
uniform vec4 swizzle_mask[3];
|
||||
uniform vec4 swizzle_sub[3];
|
||||
|
||||
#define MAX_CURVE_PARAMS 10
|
||||
#define MAX_CURVESET_PARAMS (MAX_CURVE_PARAMS * 3)
|
||||
|
|
@ -151,6 +154,39 @@ uniform HIGHPRECISION vec2 color_mapping_lut_scale_offset;
|
|||
#endif
|
||||
uniform HIGHPRECISION mat3 color_mapping_matrix;
|
||||
|
||||
/*
|
||||
* 2D texture sampler abstracting away the lack of swizzles on OpenGL ES 2. This
|
||||
* should only be used by code relying on swizzling. 'unit' is the texture unit
|
||||
* used to index the swizzling uniforms, which must appropriately be set prior
|
||||
* to draw call.
|
||||
*/
|
||||
vec4
|
||||
texture2D_swizzle(sampler2D sampler, int unit, vec2 coord)
|
||||
{
|
||||
#if GLES_API_MAJOR_VERSION == 3
|
||||
return texture2D(sampler, coord);
|
||||
#else
|
||||
vec4 color = texture2D(sampler, coord);
|
||||
|
||||
/* Swizzle components. */
|
||||
color = vec4(color[swizzle_idx[unit].x],
|
||||
color[swizzle_idx[unit].y],
|
||||
color[swizzle_idx[unit].z],
|
||||
color[swizzle_idx[unit].w]);
|
||||
|
||||
/* Substitute with 0 or 1. */
|
||||
return color * swizzle_mask[unit] + swizzle_sub[unit];
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEF_VARIANT == SHADER_VARIANT_EXTERNAL
|
||||
vec4
|
||||
texture2D_swizzle(samplerExternalOES sampler, int unit, vec2 coord)
|
||||
{
|
||||
return texture2D(sampler, coord);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4
|
||||
sample_input_texture()
|
||||
{
|
||||
|
|
@ -162,11 +198,11 @@ sample_input_texture()
|
|||
return unicolor;
|
||||
|
||||
if (c_variant == SHADER_VARIANT_EXTERNAL)
|
||||
return texture2D(tex, v_texcoord);
|
||||
return texture2D_swizzle(tex, 0, v_texcoord);
|
||||
|
||||
if (c_variant == SHADER_VARIANT_RGBA ||
|
||||
c_variant == SHADER_VARIANT_RGBX) {
|
||||
vec4 color = texture2D(tex, v_texcoord);
|
||||
vec4 color = texture2D_swizzle(tex, 0, v_texcoord);
|
||||
|
||||
if (c_variant == SHADER_VARIANT_RGBX)
|
||||
color.a = 1.0;
|
||||
|
|
@ -177,20 +213,20 @@ sample_input_texture()
|
|||
/* Requires conversion to RGBA */
|
||||
|
||||
if (c_variant == SHADER_VARIANT_Y_U_V) {
|
||||
yuva.x = texture2D(tex, v_texcoord).x;
|
||||
yuva.y = texture2D(tex1, v_texcoord).x;
|
||||
yuva.z = texture2D(tex2, v_texcoord).x;
|
||||
yuva.x = texture2D_swizzle(tex, 0, v_texcoord).x;
|
||||
yuva.y = texture2D_swizzle(tex1, 1, v_texcoord).x;
|
||||
yuva.z = texture2D_swizzle(tex2, 2, v_texcoord).x;
|
||||
|
||||
} else if (c_variant == SHADER_VARIANT_Y_UV) {
|
||||
yuva.x = texture2D(tex, v_texcoord).x;
|
||||
yuva.yz = texture2D(tex1, v_texcoord).rg;
|
||||
yuva.x = texture2D_swizzle(tex, 0, v_texcoord).x;
|
||||
yuva.yz = texture2D_swizzle(tex1, 1, v_texcoord).rg;
|
||||
|
||||
} else if (c_variant == SHADER_VARIANT_Y_XUXV) {
|
||||
yuva.x = texture2D(tex, v_texcoord).x;
|
||||
yuva.yz = texture2D(tex1, v_texcoord).ga;
|
||||
yuva.x = texture2D_swizzle(tex, 0, v_texcoord).x;
|
||||
yuva.yz = texture2D_swizzle(tex1, 1, v_texcoord).ga;
|
||||
|
||||
} else if (c_variant == SHADER_VARIANT_XYUV) {
|
||||
yuva.xyz = texture2D(tex, v_texcoord).bgr;
|
||||
yuva.xyz = texture2D_swizzle(tex, 0, v_texcoord).bgr;
|
||||
|
||||
} else {
|
||||
/* Never reached, bad variant value. */
|
||||
|
|
|
|||
|
|
@ -2262,6 +2262,7 @@ blit_shadow_to_output(struct weston_output *output,
|
|||
pixman_region32_t *output_damage)
|
||||
{
|
||||
struct gl_output_state *go = get_output_state(output);
|
||||
struct gl_renderer *gr = get_renderer(output->compositor);
|
||||
struct gl_shader_config sconf = {
|
||||
.req = {
|
||||
.variant = SHADER_VARIANT_RGBA,
|
||||
|
|
@ -2282,7 +2283,6 @@ blit_shadow_to_output(struct weston_output *output,
|
|||
.input_param = &go->shadow_param,
|
||||
.input_num = 1,
|
||||
};
|
||||
struct gl_renderer *gr = get_renderer(output->compositor);
|
||||
double width = go->area.width;
|
||||
double height = go->area.height;
|
||||
struct weston_color_transform *ctransf;
|
||||
|
|
@ -2805,14 +2805,24 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
|
||||
num_planes = yuv->output_planes;
|
||||
for (out = 0; out < num_planes; out++) {
|
||||
const GLint swizzles_rg[] = {
|
||||
GL_RED, GL_ALPHA, GL_ZERO, GL_ONE
|
||||
};
|
||||
const struct pixel_format_info *info;
|
||||
|
||||
info = pixel_format_get_info(yuv->plane[out].format);
|
||||
assert(info);
|
||||
texture_format[out] = info->gl;
|
||||
|
||||
assert(yuv->plane[out].plane_index < (int) shm_plane_count);
|
||||
/* Emulate red-green texture behaviour when
|
||||
* gl_texture_2d_init() implicitly falls back to a
|
||||
* luminance-alpha texture format. */
|
||||
if (!gl_features_has(gr, FEATURE_TEXTURE_RG) &&
|
||||
texture_format[out].internal == GL_RG8)
|
||||
ARRAY_COPY(texture_format[out].swizzles.array,
|
||||
swizzles_rg);
|
||||
|
||||
assert(yuv->plane[out].plane_index < (int) shm_plane_count);
|
||||
offset[out] = shm_offset[yuv->plane[out].plane_index];
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ struct gl_shader {
|
|||
GLint proj_uniform;
|
||||
GLint surface_to_buffer_uniform;
|
||||
GLint tex_uniforms[3];
|
||||
GLint swizzle_idx[3];
|
||||
GLint swizzle_mask[3];
|
||||
GLint swizzle_sub[3];
|
||||
GLint tex_uniform_wireframe;
|
||||
GLint view_alpha_uniform;
|
||||
GLint color_uniform;
|
||||
|
|
@ -282,7 +285,7 @@ gl_shader_create(struct gl_renderer *gr,
|
|||
{
|
||||
bool verbose = weston_log_scope_is_enabled(gr->shader_scope);
|
||||
struct gl_shader *shader = NULL;
|
||||
char msg[512];
|
||||
char buffer[512];
|
||||
GLint status;
|
||||
const char *sources[3];
|
||||
char *conf = NULL;
|
||||
|
|
@ -321,7 +324,12 @@ gl_shader_create(struct gl_renderer *gr,
|
|||
if (!conf)
|
||||
goto error_fragment;
|
||||
|
||||
sources[0] = "#version 100\n";
|
||||
sprintf(buffer,
|
||||
"#version 100\n"
|
||||
"#define GLES_API_MAJOR_VERSION %d\n",
|
||||
gr->gl_version >= gl_version(3, 0) ? 3 : 2);
|
||||
|
||||
sources[0] = buffer;
|
||||
sources[1] = conf;
|
||||
sources[2] = fragment_shader;
|
||||
shader->fragment_shader = compile_shader(GL_FRAGMENT_SHADER,
|
||||
|
|
@ -346,8 +354,9 @@ gl_shader_create(struct gl_renderer *gr,
|
|||
glLinkProgram(shader->program);
|
||||
glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
|
||||
if (!status) {
|
||||
glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
|
||||
weston_log("link info: %s\n", msg);
|
||||
glGetProgramInfoLog(shader->program, sizeof buffer, NULL,
|
||||
buffer);
|
||||
weston_log("link info: %s\n", buffer);
|
||||
goto error_link;
|
||||
}
|
||||
|
||||
|
|
@ -363,6 +372,17 @@ gl_shader_create(struct gl_renderer *gr,
|
|||
if (requirements->wireframe)
|
||||
shader->tex_uniform_wireframe =
|
||||
glGetUniformLocation(shader->program, "tex_wireframe");
|
||||
if (gr->gl_version < gl_version(3, 0)) {
|
||||
shader->swizzle_idx[0] = glGetUniformLocation(shader->program, "swizzle_idx[0]");
|
||||
shader->swizzle_idx[1] = glGetUniformLocation(shader->program, "swizzle_idx[1]");
|
||||
shader->swizzle_idx[2] = glGetUniformLocation(shader->program, "swizzle_idx[2]");
|
||||
shader->swizzle_mask[0] = glGetUniformLocation(shader->program, "swizzle_mask[0]");
|
||||
shader->swizzle_mask[1] = glGetUniformLocation(shader->program, "swizzle_mask[1]");
|
||||
shader->swizzle_mask[2] = glGetUniformLocation(shader->program, "swizzle_mask[2]");
|
||||
shader->swizzle_sub[0] = glGetUniformLocation(shader->program, "swizzle_sub[0]");
|
||||
shader->swizzle_sub[1] = glGetUniformLocation(shader->program, "swizzle_sub[1]");
|
||||
shader->swizzle_sub[2] = glGetUniformLocation(shader->program, "swizzle_sub[2]");
|
||||
}
|
||||
shader->view_alpha_uniform = glGetUniformLocation(shader->program, "view_alpha");
|
||||
if (requirements->variant == SHADER_VARIANT_SOLID) {
|
||||
shader->color_uniform = glGetUniformLocation(shader->program,
|
||||
|
|
@ -639,8 +659,12 @@ gl_shader_load_config(struct gl_renderer *gr,
|
|||
struct gl_shader *shader,
|
||||
const struct gl_shader_config *sconf)
|
||||
{
|
||||
GLint *swizzles;
|
||||
int swizzle_idx[4];
|
||||
float swizzle_mask[4];
|
||||
float swizzle_sub[4];
|
||||
GLsizei n_params;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
glUniformMatrix4fv(shader->proj_uniform,
|
||||
1, GL_FALSE, sconf->projection.d);
|
||||
|
|
@ -659,6 +683,32 @@ gl_shader_load_config(struct gl_renderer *gr,
|
|||
assert(sconf->input_num <= SHADER_INPUT_TEX_MAX);
|
||||
for (i = 0; i < sconf->input_num; i++) {
|
||||
assert(shader->tex_uniforms[i] != -1);
|
||||
|
||||
/* If the OpenGL ES implementation lacks swizzles as texture
|
||||
* parameters (OpenGL ES 2), the fragment shader loads swizzling
|
||||
* info from uniforms. */
|
||||
if (gr->gl_version < gl_version(3, 0)) {
|
||||
swizzles = sconf->input_param[i].swizzles.array;
|
||||
for (j = 0; j < 4; j++) {
|
||||
swizzle_idx[j] = swizzles[j] - GL_RED;
|
||||
if (swizzle_idx[j] >= 0) {
|
||||
/* Swizzle is GL_RED, GL_GREEN, GL_BLUE
|
||||
* or GL_ALPHA. */
|
||||
swizzle_mask[j] = 1.0f;
|
||||
swizzle_sub[j] = 0.0f;
|
||||
} else {
|
||||
/* Swizzle is GL_ZERO (0) or GL_ONE
|
||||
* (1). */
|
||||
swizzle_idx[j] = 0;
|
||||
swizzle_mask[j] = 0.0f;
|
||||
swizzle_sub[j] = (float) swizzles[j];
|
||||
}
|
||||
}
|
||||
glUniform4iv(shader->swizzle_idx[i], 1, swizzle_idx);
|
||||
glUniform4fv(shader->swizzle_mask[i], 1, swizzle_mask);
|
||||
glUniform4fv(shader->swizzle_sub[i], 1, swizzle_sub);
|
||||
}
|
||||
|
||||
glUniform1i(shader->tex_uniforms[i], TEX_UNIT_IMAGES + i);
|
||||
glActiveTexture(GL_TEXTURE0 + TEX_UNIT_IMAGES + i);
|
||||
glBindTexture(sconf->input_param[i].target,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue