[PATCH weston 2/2] compositor: add support for OES_EGL_image_external
Rob Clark
rob.clark at linaro.org
Mon Aug 13 15:39:18 PDT 2012
From: Rob Clark <rob at ti.com>
In cases where the GPU can natively handle certain YUV formats,
eglQueryWaylandBufferWL() can return the value EGL_TEXTURE_EXTERNAL_OES
and the compositor will treat the buffer as a single egl-image-external.
See:
http://www.khronos.org/registry/gles/extensions/OES/OES_EGL_image_external.txt
Signed-off-by: Rob Clark <rob at ti.com>
---
src/compositor.c | 42 ++++++++++++++++++++++++++++++++----------
src/compositor.h | 2 ++
src/weston-egl-ext.h | 1 +
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c
index b2a3ae9..08e575a 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -719,14 +719,14 @@ ensure_textures(struct weston_surface *es, int num_textures)
for (i = es->num_textures; i < num_textures; i++) {
glGenTextures(1, &es->textures[i]);
- glBindTexture(GL_TEXTURE_2D, es->textures[i]);
- glTexParameteri(GL_TEXTURE_2D,
+ glBindTexture(es->target, es->textures[i]);
+ glTexParameteri(es->target,
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D,
+ glTexParameteri(es->target,
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
es->num_textures = num_textures;
- glBindTexture(GL_TEXTURE_2D, 0);
+ glBindTexture(es->target, 0);
}
static void
@@ -771,6 +771,7 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
if (wl_buffer_is_shm(buffer)) {
es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
es->shader = &ec->texture_shader_rgba;
+ es->target = GL_TEXTURE_2D;
ensure_textures(es, 1);
glBindTexture(GL_TEXTURE_2D, es->textures[0]);
@@ -786,7 +787,7 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
for (i = 0; i < es->num_images; i++)
ec->destroy_image(ec->egl_display, es->images[i]);
es->num_images = 0;
-
+ es->target = GL_TEXTURE_2D;
switch (format) {
case EGL_TEXTURE_RGB:
case EGL_TEXTURE_RGBA:
@@ -794,6 +795,11 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
num_planes = 1;
es->shader = &ec->texture_shader_rgba;
break;
+ case EGL_TEXTURE_EXTERNAL_OES:
+ num_planes = 1;
+ es->target = GL_TEXTURE_EXTERNAL_OES;
+ es->shader = &ec->texture_shader_egl_external;
+ break;
case EGL_TEXTURE_Y_UV_WL:
num_planes = 2;
es->shader = &ec->texture_shader_y_uv;
@@ -824,8 +830,8 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
es->num_images++;
glActiveTexture(GL_TEXTURE0 + i);
- glBindTexture(GL_TEXTURE_2D, es->textures[i]);
- ec->image_target_texture_2d(GL_TEXTURE_2D,
+ glBindTexture(es->target, es->textures[i]);
+ ec->image_target_texture_2d(es->target,
es->images[i]);
}
@@ -942,9 +948,9 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output,
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);
+ glBindTexture(es->target, es->textures[i]);
+ glTexParameteri(es->target, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(es->target, GL_TEXTURE_MAG_FILTER, filter);
}
v = ec->vertices.data;
@@ -2842,6 +2848,19 @@ static const char texture_fragment_shader_rgba[] =
FRAGMENT_SHADER_EXIT
"}\n";
+static const char texture_fragment_shader_egl_external[] =
+ "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "varying vec2 v_texcoord;\n"
+ "uniform samplerExternalOES tex;\n"
+ FRAGMENT_SHADER_UNIFORMS
+ "void main()\n"
+ "{\n"
+ FRAGMENT_SHADER_INIT
+ " gl_FragColor = texture2D(tex, v_texcoord)\n;"
+ FRAGMENT_SHADER_EXIT
+ "}\n";
+
static const char texture_fragment_shader_y_uv[] =
"precision mediump float;\n"
"uniform sampler2D tex;\n"
@@ -3251,6 +3270,9 @@ weston_compositor_init_gl(struct weston_compositor *ec)
if (weston_shader_init(&ec->texture_shader_rgba,
vertex_shader, texture_fragment_shader_rgba) < 0)
return -1;
+ if (weston_shader_init(&ec->texture_shader_egl_external,
+ vertex_shader, texture_fragment_shader_egl_external) < 0)
+ return -1;
if (weston_shader_init(&ec->texture_shader_y_uv,
vertex_shader, texture_fragment_shader_y_uv) < 0)
return -1;
diff --git a/src/compositor.h b/src/compositor.h
index 22c0174..be1c2d2 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -271,6 +271,7 @@ struct weston_compositor {
EGLConfig egl_config;
GLuint fbo;
struct weston_shader texture_shader_rgba;
+ struct weston_shader texture_shader_egl_external;
struct weston_shader texture_shader_y_uv;
struct weston_shader texture_shader_y_u_v;
struct weston_shader texture_shader_y_xuxv;
@@ -452,6 +453,7 @@ struct weston_surface {
struct wl_list frame_callback_list;
EGLImageKHR images[3];
+ GLenum target;
int num_images;
struct wl_buffer *buffer;
diff --git a/src/weston-egl-ext.h b/src/weston-egl-ext.h
index 8e132c0..5dae03e 100644
--- a/src/weston-egl-ext.h
+++ b/src/weston-egl-ext.h
@@ -39,6 +39,7 @@
#define EGL_TEXTURE_Y_U_V_WL 0x31D7
#define EGL_TEXTURE_Y_UV_WL 0x31D8
#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
+#define EGL_TEXTURE_EXTERNAL_OES 0x31DA
struct wl_display;
struct wl_buffer;
--
1.7.9.5
More information about the wayland-devel
mailing list