diff options
author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-04-20 11:44:06 +0200 |
---|---|---|
committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-04-27 16:27:28 +0200 |
commit | 2aedd02f6f9ecfda274ba9a1cf8f9360e4074414 (patch) | |
tree | 1b94da1deb554caee06326bbbcab67861bf68ae0 | |
parent | aa16c8505a8b393f34a1026e78f02ab0b86acdab (diff) |
compositor: handle YUV buffers.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
-rw-r--r-- | src/compositor-wayland.c | 2 | ||||
-rw-r--r-- | src/compositor.c | 80 | ||||
-rw-r--r-- | src/compositor.h | 2 |
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; |