Message ID | 1345156101-28827-2-git-send-email-rob.clark@linaro.org |
---|---|
State | New |
Headers | show |
On Thu, 16 Aug 2012 17:28:20 -0500 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_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 > > Signed-off-by: Rob Clark <rob@ti.com> Looks good to me now. The only thing I could still say is that maybe it would be nice to log a warning, if the extension is not detected, but querySurface still returns EGL_TEXTURE_EXTERNAL_WL. Hmm, that reminds me, I don't think we have any EGL or GL error reporting in Weston... but that's a whole different story. Thanks, pq > --- > src/compositor.c | 47 +++++++++++++++++++++++++++++++++++++---------- > src/compositor.h | 2 ++ > src/weston-egl-ext.h | 1 + > 3 files changed, 40 insertions(+), 10 deletions(-) > > diff --git a/src/compositor.c b/src/compositor.c > index b2a3ae9..5c6782e 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_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; > @@ -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" > @@ -3193,6 +3212,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); > > @@ -3228,6 +3248,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) { > @@ -3251,6 +3274,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 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..5369f02 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;
On Fri, Aug 17, 2012 at 1:09 AM, Pekka Paalanen <ppaalanen@gmail.com> wrote: > On Thu, 16 Aug 2012 17:28:20 -0500 > 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_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 >> >> Signed-off-by: Rob Clark <rob@ti.com> > > Looks good to me now. The only thing I could still say is that maybe it > would be nice to log a warning, if the extension is not detected, but > querySurface still returns EGL_TEXTURE_EXTERNAL_WL. I was debating about putting an assert in there to make it more explicit that query_surface should never return EGL_TEXTURE_EXTERNAL_WL if the gl driver doesn't support OES_EGL_image_external. I guess it could be a warning too, although there is nothing really sane that weston could do as a fallback BR, -R > Hmm, that reminds me, I don't think we have any EGL or GL error > reporting in Weston... but that's a whole different story. > > > Thanks, > pq > > >> --- >> src/compositor.c | 47 +++++++++++++++++++++++++++++++++++++---------- >> src/compositor.h | 2 ++ >> src/weston-egl-ext.h | 1 + >> 3 files changed, 40 insertions(+), 10 deletions(-) >> >> diff --git a/src/compositor.c b/src/compositor.c >> index b2a3ae9..5c6782e 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_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; >> @@ -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" >> @@ -3193,6 +3212,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); >> >> @@ -3228,6 +3248,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) { >> @@ -3251,6 +3274,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 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..5369f02 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; > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
diff --git a/src/compositor.c b/src/compositor.c index b2a3ae9..5c6782e 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_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; @@ -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" @@ -3193,6 +3212,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); @@ -3228,6 +3248,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) { @@ -3251,6 +3274,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 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..5369f02 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;