Message ID | 1344897558-1976-3-git-send-email-rob.clark@linaro.org |
---|---|
State | New |
Headers | show |
On Mon, Aug 13, 2012 at 5:39 PM, Rob Clark <rob.clark@linaro.org> wrote: > 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_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@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: Kristian pointed out to me on IRC that this should be called something like EGL_TEXTURE_EXTERNAL_WL (or EGL_TEXTURE_EXTERNAL_OES_WL?), so I'll resubmit these patches.. > + 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) I wonder if some GL implementations would refuse to compile a shader with '#extension GL_OES_EGL_image_external : require'.. so maybe this shouldn't be treated as a failure case? BR, -R > + 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 >
On Mon, 13 Aug 2012 18:59:33 -0500 Rob Clark <rob@ti.com> wrote: > On Mon, Aug 13, 2012 at 5:39 PM, Rob Clark <rob.clark@linaro.org> wrote: > > 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_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@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: > > Kristian pointed out to me on IRC that this should be called something > like EGL_TEXTURE_EXTERNAL_WL (or EGL_TEXTURE_EXTERNAL_OES_WL?), so > I'll resubmit these patches.. > > > > + 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) > > I wonder if some GL implementations would refuse to compile a shader > with '#extension GL_OES_EGL_image_external : require'.. so maybe this > shouldn't be treated as a failure case? Why wouldn't they fail? They probably do not know what a samplerExternalOES is. Personally I would prefer to properly query the existence of the GL extension for image_external, and run this code only if it is supported. The existing checks are in weston_compositor_init_gl(). Thanks, pq
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;