compositor: add support for OES_EGL_image_external
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>
This commit is contained in:
committed by
Kristian Høgsberg
parent
a91291c4d6
commit
e3b9591513
+37
-10
@@ -739,14 +739,14 @@ ensure_textures(struct weston_surface *es, int num_textures)
|
|||||||
|
|
||||||
for (i = es->num_textures; i < num_textures; i++) {
|
for (i = es->num_textures; i < num_textures; i++) {
|
||||||
glGenTextures(1, &es->textures[i]);
|
glGenTextures(1, &es->textures[i]);
|
||||||
glBindTexture(GL_TEXTURE_2D, es->textures[i]);
|
glBindTexture(es->target, es->textures[i]);
|
||||||
glTexParameteri(GL_TEXTURE_2D,
|
glTexParameteri(es->target,
|
||||||
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D,
|
glTexParameteri(es->target,
|
||||||
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
}
|
}
|
||||||
es->num_textures = num_textures;
|
es->num_textures = num_textures;
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(es->target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -791,6 +791,7 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
|
|||||||
if (wl_buffer_is_shm(buffer)) {
|
if (wl_buffer_is_shm(buffer)) {
|
||||||
es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
|
es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
|
||||||
es->shader = &ec->texture_shader_rgba;
|
es->shader = &ec->texture_shader_rgba;
|
||||||
|
es->target = GL_TEXTURE_2D;
|
||||||
|
|
||||||
ensure_textures(es, 1);
|
ensure_textures(es, 1);
|
||||||
glBindTexture(GL_TEXTURE_2D, es->textures[0]);
|
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++)
|
for (i = 0; i < es->num_images; i++)
|
||||||
ec->destroy_image(ec->egl_display, es->images[i]);
|
ec->destroy_image(ec->egl_display, es->images[i]);
|
||||||
es->num_images = 0;
|
es->num_images = 0;
|
||||||
|
es->target = GL_TEXTURE_2D;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case EGL_TEXTURE_RGB:
|
case EGL_TEXTURE_RGB:
|
||||||
case EGL_TEXTURE_RGBA:
|
case EGL_TEXTURE_RGBA:
|
||||||
@@ -814,6 +815,11 @@ weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
|
|||||||
num_planes = 1;
|
num_planes = 1;
|
||||||
es->shader = &ec->texture_shader_rgba;
|
es->shader = &ec->texture_shader_rgba;
|
||||||
break;
|
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:
|
case EGL_TEXTURE_Y_UV_WL:
|
||||||
num_planes = 2;
|
num_planes = 2;
|
||||||
es->shader = &ec->texture_shader_y_uv;
|
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++;
|
es->num_images++;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
glBindTexture(GL_TEXTURE_2D, es->textures[i]);
|
glBindTexture(es->target, es->textures[i]);
|
||||||
ec->image_target_texture_2d(GL_TEXTURE_2D,
|
ec->image_target_texture_2d(es->target,
|
||||||
es->images[i]);
|
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++) {
|
for (i = 0; i < es->num_textures; i++) {
|
||||||
glUniform1i(es->shader->tex_uniforms[i], i);
|
glUniform1i(es->shader->tex_uniforms[i], i);
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
glBindTexture(GL_TEXTURE_2D, es->textures[i]);
|
glBindTexture(es->target, es->textures[i]);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
glTexParameteri(es->target, GL_TEXTURE_MIN_FILTER, filter);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
glTexParameteri(es->target, GL_TEXTURE_MAG_FILTER, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
v = ec->vertices.data;
|
v = ec->vertices.data;
|
||||||
@@ -2848,6 +2854,19 @@ static const char texture_fragment_shader_rgba[] =
|
|||||||
FRAGMENT_SHADER_EXIT
|
FRAGMENT_SHADER_EXIT
|
||||||
"}\n";
|
"}\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[] =
|
static const char texture_fragment_shader_y_uv[] =
|
||||||
"precision mediump float;\n"
|
"precision mediump float;\n"
|
||||||
"uniform sampler2D tex;\n"
|
"uniform sampler2D tex;\n"
|
||||||
@@ -3287,6 +3306,7 @@ WL_EXPORT int
|
|||||||
weston_compositor_init_gl(struct weston_compositor *ec)
|
weston_compositor_init_gl(struct weston_compositor *ec)
|
||||||
{
|
{
|
||||||
const char *extensions;
|
const char *extensions;
|
||||||
|
int has_egl_image_external = 0;
|
||||||
|
|
||||||
log_egl_gl_info(ec->egl_display);
|
log_egl_gl_info(ec->egl_display);
|
||||||
|
|
||||||
@@ -3322,6 +3342,9 @@ weston_compositor_init_gl(struct weston_compositor *ec)
|
|||||||
if (strstr(extensions, "GL_EXT_unpack_subimage"))
|
if (strstr(extensions, "GL_EXT_unpack_subimage"))
|
||||||
ec->has_unpack_subimage = 1;
|
ec->has_unpack_subimage = 1;
|
||||||
|
|
||||||
|
if (strstr(extensions, "GL_OES_EGL_image_external"))
|
||||||
|
has_egl_image_external = 1;
|
||||||
|
|
||||||
extensions =
|
extensions =
|
||||||
(const char *) eglQueryString(ec->egl_display, EGL_EXTENSIONS);
|
(const char *) eglQueryString(ec->egl_display, EGL_EXTENSIONS);
|
||||||
if (!extensions) {
|
if (!extensions) {
|
||||||
@@ -3345,6 +3368,10 @@ weston_compositor_init_gl(struct weston_compositor *ec)
|
|||||||
if (weston_shader_init(&ec->texture_shader_rgba,
|
if (weston_shader_init(&ec->texture_shader_rgba,
|
||||||
vertex_shader, texture_fragment_shader_rgba) < 0)
|
vertex_shader, texture_fragment_shader_rgba) < 0)
|
||||||
return -1;
|
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,
|
if (weston_shader_init(&ec->texture_shader_y_uv,
|
||||||
vertex_shader, texture_fragment_shader_y_uv) < 0)
|
vertex_shader, texture_fragment_shader_y_uv) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ struct weston_compositor {
|
|||||||
EGLConfig egl_config;
|
EGLConfig egl_config;
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
struct weston_shader texture_shader_rgba;
|
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_uv;
|
||||||
struct weston_shader texture_shader_y_u_v;
|
struct weston_shader texture_shader_y_u_v;
|
||||||
struct weston_shader texture_shader_y_xuxv;
|
struct weston_shader texture_shader_y_xuxv;
|
||||||
@@ -448,6 +449,7 @@ struct weston_surface {
|
|||||||
struct wl_list frame_callback_list;
|
struct wl_list frame_callback_list;
|
||||||
|
|
||||||
EGLImageKHR images[3];
|
EGLImageKHR images[3];
|
||||||
|
GLenum target;
|
||||||
int num_images;
|
int num_images;
|
||||||
|
|
||||||
struct wl_buffer *buffer;
|
struct wl_buffer *buffer;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#define EGL_TEXTURE_Y_U_V_WL 0x31D7
|
#define EGL_TEXTURE_Y_U_V_WL 0x31D7
|
||||||
#define EGL_TEXTURE_Y_UV_WL 0x31D8
|
#define EGL_TEXTURE_Y_UV_WL 0x31D8
|
||||||
#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
|
#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
|
||||||
|
#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
|
||||||
|
|
||||||
struct wl_display;
|
struct wl_display;
|
||||||
struct wl_buffer;
|
struct wl_buffer;
|
||||||
@@ -53,4 +54,8 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, st
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EGL_TEXTURE_EXTERNAL_WL
|
||||||
|
#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user