From patchwork Fri Aug 31 21:42:18 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 11136 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 8259923E52 for ; Fri, 31 Aug 2012 21:42:27 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id BEAB8A186A1 for ; Fri, 31 Aug 2012 21:41:47 +0000 (UTC) Received: by iafj25 with SMTP id j25so5288855iaf.11 for ; Fri, 31 Aug 2012 14:42:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :dkim-signature:sender:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=JzwhyobosOQylhrKeJKP7hLb2ok0oBa1ZJqBrJ+G5Hw=; b=EGOQMiWVqjITC1hC+pMZHTeIfl+0W2g9arAh7emJdbpPrpZKRIFgk1rzRF5EkjOil0 tKkVDY5dxu5Tcf5DB+s13tunT+0i4ygQfIQ8O5Cq0zqUJCpIOAl3tlLqONWW4YOmKrPX igIt0d9kOKO08oV37LdCJOhwN2r/boJxgEY2WcrJZp7GFoZjDSe/+7mFndvrfy0jf5Pc tPmQeRPOenH888p4ZJxdTADdW2AWik1on7opMLUOiQJPGnufDh8rWD31Nc67Q/z1xxmt L1tQZcbXUKMalgakJLEe0Q+IAWHGmqdkohcwhmKXBRwS+QaXGb1oQe5lg3wsOVHK2T4D t86g== Received: by 10.50.180.129 with SMTP id do1mr4505267igc.28.1346449346445; Fri, 31 Aug 2012 14:42:26 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp35662igc; Fri, 31 Aug 2012 14:42:25 -0700 (PDT) Received: by 10.68.201.198 with SMTP id kc6mr19684606pbc.122.1346449345337; Fri, 31 Aug 2012 14:42:25 -0700 (PDT) Received: from mail-pb0-f50.google.com (mail-pb0-f50.google.com [209.85.160.50]) by mx.google.com with ESMTPS id kt9si10701419pbc.140.2012.08.31.14.42.25 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 31 Aug 2012 14:42:25 -0700 (PDT) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.160.50 as permitted sender) client-ip=209.85.160.50; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.160.50 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass header.i=@gmail.com Received: by pbcmd12 with SMTP id md12so5927522pbc.37 for ; Fri, 31 Aug 2012 14:42:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer; bh=JzwhyobosOQylhrKeJKP7hLb2ok0oBa1ZJqBrJ+G5Hw=; b=ekah4T4eeUnxvHUg9VBLGNtCbEkvI/lO/yDbdCXpNWdaZBjqZq3s4MK5H2fB4DWIIZ 0wmwGcfli0+BYZ3/V5d34XCLmVuoawrYpw51ZDvWZVGj7kqUZBJ806P2U/YzIP9ZIt/W sd7XXpxHyxHTDaDW1t1d9x+S1KOr7IUzbH566nEbBQ3a/PMMiLHKQSiFEaYHaZrPkHEE QQ4RfrJxtV5bUUtSWhy/madgSAGLWa+FtZB2bVtmFC+7SqJkHAXKSqu/KzlqQPlRF4lt 0h2PZGOk8F/dLFJdb37szoufX0lbCW1Z6iA1opO8wbUC5KJeLSDTpQXWxW/bwRh5raps 5VAA== Received: by 10.68.227.165 with SMTP id sb5mr19770269pbc.82.1346449344802; Fri, 31 Aug 2012 14:42:24 -0700 (PDT) Received: from localhost ([38.96.16.75]) by mx.google.com with ESMTPS id vf8sm4205308pbc.27.2012.08.31.14.42.22 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 31 Aug 2012 14:42:22 -0700 (PDT) Sender: Rob Clark From: Rob Clark To: wayland-devel@lists.freedesktop.org Cc: patches@linaro.org, Rob Clark Subject: [PATCH 1/5 weston] compositor: add support for OES_EGL_image_external Date: Fri, 31 Aug 2012 16:42:18 -0500 Message-Id: <1346449338-20123-1-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.9.5 X-Gm-Message-State: ALoCoQnstQXT1NkG3lmL4YxOioPtlPkq2gdpjPzaNx0qYtLQtRe6Z9bUINv0aipXobeeEDZuASQq From: Rob Clark 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 --- src/compositor.c | 47 +++++++++++++++++++++++++++++++++++++---------- src/compositor.h | 2 ++ src/weston-egl-ext.h | 5 +++++ 3 files changed, 44 insertions(+), 10 deletions(-) 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