summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-04-20 11:44:06 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2012-04-27 16:27:28 +0200
commit2aedd02f6f9ecfda274ba9a1cf8f9360e4074414 (patch)
tree1b94da1deb554caee06326bbbcab67861bf68ae0
parentaa16c8505a8b393f34a1026e78f02ab0b86acdab (diff)
compositor: handle YUV buffers.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r--src/compositor-wayland.c2
-rw-r--r--src/compositor.c80
-rw-r--r--src/compositor.h2
3 files changed, 66 insertions, 18 deletions
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 07ef427..78b8992 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -182,7 +182,7 @@ draw_border(struct wayland_output *output)
glUniformMatrix4fv(shader->proj_uniform,
1, GL_FALSE, output->base.matrix.d);
- glUniform1i(shader->tex_uniform, 0);
+ glUniform1i(shader->tex_uniforms[0], 0);
glUniform1f(shader->alpha_uniform, 1);
glUniform1f(shader->texwidth_uniform, 1);
diff --git a/src/compositor.c b/src/compositor.c
index 08e8d55..1642f63 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -722,6 +722,9 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
{
struct weston_surface *es = (struct weston_surface *) surface;
struct weston_compositor *ec = es->compositor;
+ struct wl_buffer_layout layout;
+ EGLint *attribs, attrib_list[2*4+1];
+ unsigned int i;
if (es->buffer) {
weston_buffer_post_release(es->buffer);
@@ -757,18 +760,57 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
es->pitch, es->buffer->height, 0,
GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
} else {
- destroy_image(ec, &es->images[0]);
- es->images[0] = ec->create_image(ec->display, NULL,
- EGL_WAYLAND_BUFFER_WL,
- buffer, NULL);
- es->num_images = 1;
-
- ensure_textures(es, 1);
- glBindTexture(GL_TEXTURE_2D, es->textures[0]);
- ec->image_target_texture_2d(GL_TEXTURE_2D, es->images[0]);
-
+ for (i = 0; i < es->num_images; i++)
+ destroy_image(ec, &es->images[i]);
+ es->num_images = 0;
+
+ wl_buffer_get_layout(buffer, &layout);
+ switch (layout.format) {
+ case WL_BUFFER_FORMAT_ARGB32:
+ case WL_BUFFER_FORMAT_XRGB32:
+ assert(layout.num_planes == 1);
+ es->shader = &ec->texture_shader_rgba;
+ break;
+ case WL_BUFFER_FORMAT_NV12:
+ assert(layout.num_planes == 2);
+ es->shader = &ec->texture_shader_nv12;
+ break;
+ case WL_BUFFER_FORMAT_YUV410:
+ case WL_BUFFER_FORMAT_YUV411:
+ case WL_BUFFER_FORMAT_YUV420:
+ case WL_BUFFER_FORMAT_YUV422:
+ case WL_BUFFER_FORMAT_YUV444:
+ assert(layout.num_planes == 3);
+ es->shader = &ec->texture_shader_yuv8;
+ break;
+ default:
+ layout.num_planes = 1;
+ es->shader = &ec->texture_shader_rgba;
+ break;
+ }
es->pitch = buffer->width;
- es->shader = &ec->texture_shader_rgba;
+
+ ensure_textures(es, layout.num_planes);
+ for (i = 0; i < layout.num_planes; i++) {
+ attribs = attrib_list;
+ *attribs++ = EGL_WAYLAND_BUFFER_PLANE_ID_WL;
+ *attribs++ = i;
+ *attribs++ = EGL_NONE;
+ es->images[i] = ec->create_image(
+ ec->display, NULL,
+ EGL_WAYLAND_BUFFER_WL,
+ buffer, attrib_list
+ );
+ if (!es->images[i])
+ continue;
+ es->num_images++;
+
+ glActiveTexture(GL_TEXTURE0 + i);
+ glBindTexture(GL_TEXTURE_2D, es->textures[i]);
+ ec->image_target_texture_2d(GL_TEXTURE_2D, es->images[i]);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+ glActiveTexture(GL_TEXTURE0);
}
}
@@ -836,6 +878,7 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output,
GLfloat *v;
pixman_region32_t repaint;
GLint filter;
+ unsigned int i;
int n;
pixman_region32_init(&repaint);
@@ -856,7 +899,6 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output,
glUniformMatrix4fv(es->shader->proj_uniform,
1, GL_FALSE, output->matrix.d);
- glUniform1i(es->shader->tex_uniform, 0);
glUniform4fv(es->shader->color_uniform, 1, es->color);
glUniform1f(es->shader->alpha_uniform, es->alpha / 255.0);
glUniform1f(es->shader->brightness_uniform, es->brightness / 255.0);
@@ -871,9 +913,13 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output,
n = texture_region(es, &repaint);
- glBindTexture(GL_TEXTURE_2D, es->textures[0]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ for (i = 0; i < es->num_textures; i++) {
+ glUniform1i(es->shader->tex_uniforms[i], i);
+ glActiveTexture(GL_TEXTURE0 + i);
+ glBindTexture(GL_TEXTURE_2D, es->textures[i]);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ }
v = ec->vertices.data;
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[0]);
@@ -2379,7 +2425,9 @@ weston_shader_init(struct weston_shader *shader,
}
shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
- shader->tex_uniform = glGetUniformLocation(shader->program, "tex");
+ shader->tex_uniforms[0] = glGetUniformLocation(shader->program, "tex");
+ shader->tex_uniforms[1] = glGetUniformLocation(shader->program, "tex1");
+ shader->tex_uniforms[2] = glGetUniformLocation(shader->program, "tex2");
shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
shader->brightness_uniform = glGetUniformLocation(shader->program, "bright");
shader->saturation_uniform = glGetUniformLocation(shader->program, "saturation");
diff --git a/src/compositor.h b/src/compositor.h
index ada5743..bd05e2f 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -156,7 +156,7 @@ struct weston_shader {
GLuint program;
GLuint vertex_shader, fragment_shader;
GLint proj_uniform;
- GLint tex_uniform;
+ GLint tex_uniforms[WL_BUFFER_MAX_PLANES];
GLint alpha_uniform;
GLint brightness_uniform;
GLint saturation_uniform;