diff mbox

[1/5,weston] compositor: add support for OES_EGL_image_external

Message ID 1346449338-20123-1-git-send-email-rob.clark@linaro.org
State New
Headers show

Commit Message

Rob Clark Aug. 31, 2012, 9:42 p.m. UTC
From: Rob Clark <rob@ti.com>

In cases where the GPU can natively handle certain YUV formats,
eglQueryWaylandBufferWL() can return the value EGL_TEXTURE_EXTERNAL_WL
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

v1: original
v2: rename EGL_TEXTURE_EXTERNAL_OES -> EGL_TEXTURE_EXTERNAL_WL and query
    for the extension
v3: fix build without updated mesa headers, if EGL_TEXTURE_EXTERNAL_WL
    #define is missing from older mesa headers.
v4: resend without missing parts

Signed-off-by: Rob Clark <rob@ti.com>
---
 src/compositor.c     |   47 +++++++++++++++++++++++++++++++++++++----------
 src/compositor.h     |    2 ++
 src/weston-egl-ext.h |    5 +++++
 3 files changed, 44 insertions(+), 10 deletions(-)
diff mbox

Patch

diff --git a/src/compositor.c b/src/compositor.c
index 8803d4e..756859f 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -739,14 +739,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
@@ -791,6 +791,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]);
@@ -806,7 +807,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:
@@ -814,6 +815,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_WL:
+			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;
@@ -844,8 +850,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]);
 		}
 
@@ -965,9 +971,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;
@@ -2847,6 +2853,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"
@@ -3199,6 +3218,7 @@  WL_EXPORT int
 weston_compositor_init_gl(struct weston_compositor *ec)
 {
 	const char *extensions;
+	int has_egl_image_external = 0;
 
 	log_egl_gl_info(ec->egl_display);
 
@@ -3234,6 +3254,9 @@  weston_compositor_init_gl(struct weston_compositor *ec)
 	if (strstr(extensions, "GL_EXT_unpack_subimage"))
 		ec->has_unpack_subimage = 1;
 
+	if (strstr(extensions, "GL_OES_EGL_image_external"))
+		has_egl_image_external = 1;
+
 	extensions =
 		(const char *) eglQueryString(ec->egl_display, EGL_EXTENSIONS);
 	if (!extensions) {
@@ -3257,6 +3280,10 @@  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 (has_egl_image_external &&
+			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 b8e767d..f2ba4e1 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -276,6 +276,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;
@@ -447,6 +448,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..1d4b76b 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_WL         0x31DA
 
 struct wl_display;
 struct wl_buffer;
@@ -53,4 +54,8 @@  typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, st
 
 #endif
 
+#ifndef EGL_TEXTURE_EXTERNAL_WL
+#define EGL_TEXTURE_EXTERNAL_WL         0x31DA
+#endif
+
 #endif