summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO22
-rw-r--r--0001-gl-renderer-Renaming-of-things-and-minor-improvement.patch212
-rw-r--r--0002-gl-renderer-Refactor-gl_renderer_output_window_creat.patch169
-rw-r--r--0003-gl-renderer-Implement-use-check_extension.patch167
-rw-r--r--0004-gl-renderer-Add-support-for-EGLDevice-EGLOutput.patch820
-rw-r--r--0005-compositor-drm-Gracefully-handle-vblank-and-flip-inv.patch82
-rw-r--r--0006-compositor-drm-Renaming-of-gbm-fields.patch228
-rw-r--r--0007-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch552
-rw-r--r--PKGBUILD44
9 files changed, 2285 insertions, 11 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 802ae7fd95c3..0badd42231a1 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,5 +1,5 @@
-pkgbase = weston
- pkgdesc = Reference implementation of a Wayland compositor
+pkgbase = weston-eglstream
+ pkgdesc = Reference implementation of a Wayland compositor with EGLStream support
pkgver = 1.10.0
pkgrel = 1
url = http://wayland.freedesktop.org
@@ -17,8 +17,24 @@ pkgbase = weston
depends = glu
depends = pango
depends = colord
+ provides = weston
+ conflicts = weston
source = http://wayland.freedesktop.org/releases/weston-1.10.0.tar.xz
+ source = 0001-gl-renderer-Renaming-of-things-and-minor-improvement.patch
+ source = 0002-gl-renderer-Refactor-gl_renderer_output_window_creat.patch
+ source = 0003-gl-renderer-Implement-use-check_extension.patch
+ source = 0004-gl-renderer-Add-support-for-EGLDevice-EGLOutput.patch
+ source = 0005-compositor-drm-Gracefully-handle-vblank-and-flip-inv.patch
+ source = 0006-compositor-drm-Renaming-of-gbm-fields.patch
+ source = 0007-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch
sha1sums = c9c2c8e2e798b25e7bf6b31bf0c4ef08724a7ebb
+ sha1sums = c623cdf628a20a4bde5a98cc40867c32a8300e79
+ sha1sums = 3441d0a7da0ae64835a5b29545caab4bc7977417
+ sha1sums = f6742fadb973ec6c2b55e5500127309e70579312
+ sha1sums = 31e3a447a1209712d604d739d0ac7e5b1925e940
+ sha1sums = b483f21b3f880d3978cc678bf5f97802f7ddddaf
+ sha1sums = 13d217d76a0811f5eb8d7180d31ec7a69fbbaabd
+ sha1sums = 6bab10ac02a7e69b1bb1bf1982b5804e87870e0e
-pkgname = weston
+pkgname = weston-eglstream
diff --git a/0001-gl-renderer-Renaming-of-things-and-minor-improvement.patch b/0001-gl-renderer-Renaming-of-things-and-minor-improvement.patch
new file mode 100644
index 000000000000..ae7acd6ca073
--- /dev/null
+++ b/0001-gl-renderer-Renaming-of-things-and-minor-improvement.patch
@@ -0,0 +1,212 @@
+From 50b2478345ae978143364abde179080a36479e94 Mon Sep 17 00:00:00 2001
+From: "Miguel A. Vico" <mvicomoya@nvidia.com>
+Date: Mon, 21 Mar 2016 17:37:31 +0100
+Subject: [PATCH 1/7] gl-renderer: Renaming of things and minor improvements
+X-NVConfidentiality: public
+
+In preparation for follow-on changes to support frame presentation
+through EGLDevice+EGLOutput, this change includes the following:
+ -Rename gl_renderer_output_create to gl_renderer_output_window_create
+ -Add <platform_attribs> argument to gl_renderer_create
+ -Rename <attribs> argument for gl_renderer_create() and
+ gl_renderer_output_window_create() to <config_attribs>
+ -Accept non-NULL empty <visual_id> arrays (n_ids == 0) both in
+ gl_renderer_create() and gl_renderer_output_window_create()
+
+Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
+Reviewed-by: Andy Ritger <aritger@nvidia.com>
+---
+ src/compositor-drm.c | 3 ++-
+ src/compositor-fbdev.c | 3 ++-
+ src/compositor-wayland.c | 3 ++-
+ src/compositor-x11.c | 4 ++--
+ src/gl-renderer.c | 18 +++++++++---------
+ src/gl-renderer.h | 7 ++++---
+ 6 files changed, 21 insertions(+), 17 deletions(-)
+
+diff --git a/src/compositor-drm.c b/src/compositor-drm.c
+index 538e56eb58ba..ded15f83c3e6 100644
+--- a/src/compositor-drm.c
++++ b/src/compositor-drm.c
+@@ -1588,6 +1588,7 @@ drm_backend_create_gl_renderer(struct drm_backend *b)
+ if (gl_renderer->create(b->compositor,
+ EGL_PLATFORM_GBM_KHR,
+ (void *)b->gbm,
++ NULL,
+ gl_renderer->opaque_attribs,
+ format,
+ n_formats) < 0) {
+@@ -1852,7 +1853,7 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
+
+ if (format[1])
+ n_formats = 2;
+- if (gl_renderer->output_create(&output->base,
++ if (gl_renderer->output_window_create(&output->base,
+ (EGLNativeWindowType)output->surface,
+ output->surface,
+ gl_renderer->opaque_attribs,
+diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
+index 36d7ae0ae500..84435b7f2fbd 100644
+--- a/src/compositor-fbdev.c
++++ b/src/compositor-fbdev.c
+@@ -526,7 +526,7 @@ fbdev_output_create(struct fbdev_backend *backend,
+ goto out_hw_surface;
+ } else {
+ setenv("HYBRIS_EGLPLATFORM", "wayland", 1);
+- if (gl_renderer->output_create(&output->base,
++ if (gl_renderer->output_window_create(&output->base,
+ (EGLNativeWindowType)NULL, NULL,
+ gl_renderer->opaque_attribs,
+ NULL, 0) < 0) {
+@@ -799,6 +799,7 @@ fbdev_backend_create(struct weston_compositor *compositor, int *argc, char *argv
+
+ if (gl_renderer->create(compositor, NO_EGL_PLATFORM,
+ EGL_DEFAULT_DISPLAY,
++ NULL,
+ gl_renderer->opaque_attribs,
+ NULL, 0) < 0) {
+ weston_log("gl_renderer_create failed.\n");
+diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
+index d1c020d886a1..d38376a9ee38 100644
+--- a/src/compositor-wayland.c
++++ b/src/compositor-wayland.c
+@@ -657,7 +657,7 @@ wayland_output_init_gl_renderer(struct wayland_output *output)
+ return -1;
+ }
+
+- if (gl_renderer->output_create(&output->base,
++ if (gl_renderer->output_window_create(&output->base,
+ output->gl.egl_window,
+ output->gl.egl_window,
+ gl_renderer->alpha_attribs,
+@@ -2250,6 +2250,7 @@ wayland_backend_create(struct weston_compositor *compositor, int use_pixman,
+ if (gl_renderer->create(compositor,
+ EGL_PLATFORM_WAYLAND_KHR,
+ b->parent.wl_display,
++ NULL,
+ gl_renderer->alpha_attribs,
+ NULL,
+ 0) < 0) {
+diff --git a/src/compositor-x11.c b/src/compositor-x11.c
+index 13a5d7304568..bc35db66f6fc 100644
+--- a/src/compositor-x11.c
++++ b/src/compositor-x11.c
+@@ -932,7 +932,7 @@ x11_backend_create_output(struct x11_backend *b, int x, int y,
+ * but eglCreateWindowSurface takes a Window. */
+ Window xid = (Window) output->window;
+
+- ret = gl_renderer->output_create(&output->base,
++ ret = gl_renderer->output_window_create(&output->base,
+ (EGLNativeWindowType) output->window,
+ &xid,
+ gl_renderer->opaque_attribs,
+@@ -1562,7 +1562,7 @@ init_gl_renderer(struct x11_backend *b)
+ return -1;
+
+ ret = gl_renderer->create(b->compositor, EGL_PLATFORM_X11_KHR, (void *) b->dpy,
+- gl_renderer->opaque_attribs, NULL, 0);
++ NULL, gl_renderer->opaque_attribs, NULL, 0);
+
+ return ret;
+ }
+diff --git a/src/gl-renderer.c b/src/gl-renderer.c
+index cb083448bfdb..0c55e0b9ebd2 100644
+--- a/src/gl-renderer.c
++++ b/src/gl-renderer.c
+@@ -2493,7 +2493,7 @@ egl_choose_config(struct gl_renderer *gr, const EGLint *attribs,
+ goto out;
+ }
+
+- if (!visual_id)
++ if (!visual_id || n_ids == 0)
+ config_index = 0;
+
+ for (i = 0; config_index == -1 && i < n_ids; i++)
+@@ -2547,10 +2547,10 @@ static int
+ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface);
+
+ static int
+-gl_renderer_output_create(struct weston_output *output,
++gl_renderer_output_window_create(struct weston_output *output,
+ EGLNativeWindowType window_for_legacy,
+ void *window_for_platform,
+- const EGLint *attribs,
++ const EGLint *config_attribs,
+ const EGLint *visual_id,
+ int n_ids)
+ {
+@@ -2560,7 +2560,7 @@ gl_renderer_output_create(struct weston_output *output,
+ EGLConfig egl_config;
+ int i;
+
+- if (egl_choose_config(gr, attribs, visual_id,
++ if (egl_choose_config(gr, config_attribs, visual_id,
+ n_ids, &egl_config) == -1) {
+ weston_log("failed to choose EGL config for output\n");
+ return -1;
+@@ -2846,8 +2846,8 @@ platform_to_extension(EGLenum platform)
+
+ static int
+ gl_renderer_create(struct weston_compositor *ec, EGLenum platform,
+- void *native_window, const EGLint *attribs,
+- const EGLint *visual_id, int n_ids)
++ void *native_window, const EGLint* platform_attribs,
++ const EGLint *config_attribs, const EGLint *visual_id, int n_ids)
+ {
+ struct gl_renderer *gr;
+ EGLint major, minor;
+@@ -2889,7 +2889,7 @@ gl_renderer_create(struct weston_compositor *ec, EGLenum platform,
+ if (get_platform_display && platform) {
+ gr->egl_display = get_platform_display(platform,
+ native_window,
+- NULL);
++ platform_attribs);
+ }
+ }
+
+@@ -2910,7 +2910,7 @@ gl_renderer_create(struct weston_compositor *ec, EGLenum platform,
+ goto fail_with_error;
+ }
+
+- if (egl_choose_config(gr, attribs, visual_id,
++ if (egl_choose_config(gr, config_attribs, visual_id,
+ n_ids, &gr->egl_config) < 0) {
+ weston_log("failed to choose EGL config\n");
+ goto fail_terminate;
+@@ -3121,7 +3121,7 @@ WL_EXPORT struct gl_renderer_interface gl_renderer_interface = {
+
+ .create = gl_renderer_create,
+ .display = gl_renderer_display,
+- .output_create = gl_renderer_output_create,
++ .output_window_create = gl_renderer_output_window_create,
+ .output_destroy = gl_renderer_output_destroy,
+ .output_surface = gl_renderer_output_surface,
+ .output_set_border = gl_renderer_output_set_border,
+diff --git a/src/gl-renderer.h b/src/gl-renderer.h
+index 71f6b46e49e1..af8dd267e700 100644
+--- a/src/gl-renderer.h
++++ b/src/gl-renderer.h
+@@ -78,16 +78,17 @@ struct gl_renderer_interface {
+ int (*create)(struct weston_compositor *ec,
+ EGLenum platform,
+ void *native_window,
+- const EGLint *attribs,
++ const EGLint *platform_attribs,
++ const EGLint *config_attribs,
+ const EGLint *visual_id,
+ const int n_ids);
+
+ EGLDisplay (*display)(struct weston_compositor *ec);
+
+- int (*output_create)(struct weston_output *output,
++ int (*output_window_create)(struct weston_output *output,
+ EGLNativeWindowType window_for_legacy,
+ void *window_for_platform,
+- const EGLint *attribs,
++ const EGLint *config_attribs,
+ const EGLint *visual_id,
+ const int n_ids);
+
+--
+2.7.4
+
diff --git a/0002-gl-renderer-Refactor-gl_renderer_output_window_creat.patch b/0002-gl-renderer-Refactor-gl_renderer_output_window_creat.patch
new file mode 100644
index 000000000000..2c4528b94998
--- /dev/null
+++ b/0002-gl-renderer-Refactor-gl_renderer_output_window_creat.patch
@@ -0,0 +1,169 @@
+From 1a6f5e3586cf62029a8bed8072bd41e845746bad Mon Sep 17 00:00:00 2001
+From: "Miguel A. Vico" <mvicomoya@nvidia.com>
+Date: Mon, 21 Mar 2016 17:37:32 +0100
+Subject: [PATCH 2/7] gl-renderer: Refactor gl_renderer_output_window_create()
+X-NVConfidentiality: public
+
+In preparation for follow-on changes to support frame presentation
+through EGLDevice+EGLOutput, this change refactors
+gl_renderer_output_window_create() to separate out window surface
+creation code from output common creation code.
+
+Bonus: Fix EGLSurface leakage upon gl_renderer_setup() failure.
+
+Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
+Reviewed-by: Andy Ritger <aritger@nvidia.com>
+---
+ src/gl-renderer.c | 91 +++++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 62 insertions(+), 29 deletions(-)
+
+diff --git a/src/gl-renderer.c b/src/gl-renderer.c
+index 0c55e0b9ebd2..1d6d98c9b86b 100644
+--- a/src/gl-renderer.c
++++ b/src/gl-renderer.c
+@@ -1,6 +1,7 @@
+ /*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2015 Collabora, Ltd.
++ * Copyright © 2016 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+@@ -2546,24 +2547,21 @@ gl_renderer_output_set_border(struct weston_output *output,
+ static int
+ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface);
+
+-static int
+-gl_renderer_output_window_create(struct weston_output *output,
++static EGLSurface
++gl_renderer_create_window_surface(struct gl_renderer *gr,
+ EGLNativeWindowType window_for_legacy,
+ void *window_for_platform,
+ const EGLint *config_attribs,
+ const EGLint *visual_id,
+ int n_ids)
+ {
+- struct weston_compositor *ec = output->compositor;
+- struct gl_renderer *gr = get_renderer(ec);
+- struct gl_output_state *go;
++ EGLSurface egl_surface = EGL_NO_SURFACE;
+ EGLConfig egl_config;
+- int i;
+
+ if (egl_choose_config(gr, config_attribs, visual_id,
+ n_ids, &egl_config) == -1) {
+ weston_log("failed to choose EGL config for output\n");
+- return -1;
++ return EGL_NO_SURFACE;
+ }
+
+ if (egl_config != gr->egl_config &&
+@@ -2571,48 +2569,83 @@ gl_renderer_output_window_create(struct weston_output *output,
+ weston_log("attempted to use a different EGL config for an "
+ "output but EGL_MESA_configless_context is not "
+ "supported\n");
+- return -1;
++ return EGL_NO_SURFACE;
+ }
+
+- go = zalloc(sizeof *go);
+- if (go == NULL)
+- return -1;
++ log_egl_config_info(gr->egl_display, egl_config);
+
+- if (gr->create_platform_window) {
+- go->egl_surface =
+- gr->create_platform_window(gr->egl_display,
+- egl_config,
+- window_for_platform,
+- NULL);
+- } else {
+- go->egl_surface =
+- eglCreateWindowSurface(gr->egl_display,
+- egl_config,
+- window_for_legacy, NULL);
+- }
++ if (gr->create_platform_window)
++ egl_surface = gr->create_platform_window(gr->egl_display,
++ egl_config,
++ window_for_platform,
++ NULL);
++ else
++ egl_surface = eglCreateWindowSurface(gr->egl_display,
++ egl_config,
++ window_for_legacy, NULL);
++
++ return egl_surface;
++}
++
++static int
++gl_renderer_output_create(struct weston_output *output,
++ EGLSurface surface)
++{
++ struct weston_compositor *ec = output->compositor;
++ struct gl_renderer *gr = get_renderer(ec);
++ struct gl_output_state *go;
++ int i;
+
+- if (go->egl_surface == EGL_NO_SURFACE) {
++ if (surface == EGL_NO_SURFACE) {
+ weston_log("failed to create egl surface\n");
+- free(go);
+ return -1;
+ }
+
+ if (gr->egl_context == NULL)
+- if (gl_renderer_setup(ec, go->egl_surface) < 0) {
+- free(go);
++ if (gl_renderer_setup(ec, surface) < 0) {
+ return -1;
+ }
+
++ go = zalloc(sizeof *go);
++ if (go == NULL)
++ return -1;
++
++ go->egl_surface = surface;
++
+ for (i = 0; i < BUFFER_DAMAGE_COUNT; i++)
+ pixman_region32_init(&go->buffer_damage[i]);
+
+ output->renderer_state = go;
+
+- log_egl_config_info(gr->egl_display, egl_config);
+-
+ return 0;
+ }
+
++static int
++gl_renderer_output_window_create(struct weston_output *output,
++ EGLNativeWindowType window_for_legacy,
++ void *window_for_platform,
++ const EGLint *config_attribs,
++ const EGLint *visual_id,
++ int n_ids)
++{
++ struct weston_compositor *ec = output->compositor;
++ struct gl_renderer *gr = get_renderer(ec);
++ EGLSurface egl_surface = EGL_NO_SURFACE;
++ int ret = 0;
++
++ egl_surface = gl_renderer_create_window_surface(gr,
++ window_for_legacy,
++ window_for_platform,
++ config_attribs,
++ visual_id, n_ids);
++
++ ret = gl_renderer_output_create(output, egl_surface);
++ if (ret < 0 && egl_surface != EGL_NO_SURFACE)
++ eglDestroySurface(gr->egl_display, egl_surface);
++
++ return ret;
++}
++
+ static void
+ gl_renderer_output_destroy(struct weston_output *output)
+ {
+--
+2.7.4
+
diff --git a/0003-gl-renderer-Implement-use-check_extension.patch b/0003-gl-renderer-Implement-use-check_extension.patch
new file mode 100644
index 000000000000..deed6e719faa
--- /dev/null
+++ b/0003-gl-renderer-Implement-use-check_extension.patch
@@ -0,0 +1,167 @@
+From c513bd330d06c7e57ca294f5e3cf7f0824afefc4 Mon Sep 17 00:00:00 2001
+From: "Miguel A. Vico" <mvicomoya@nvidia.com>
+Date: Mon, 21 Mar 2016 17:37:33 +0100
+Subject: [PATCH 3/7] gl-renderer: Implement & use check_extension
+X-NVConfidentiality: public
+
+Using strstr(3) for checking for extensions is an error-prone mechanism
+as extension names can be prefixes of other extension names (see
+https://www.opengl.org/registry/doc/rules.html#using).
+
+This change implements the check_extension() function to properly check
+for an extension and replaces all usages of strstr(3).
+
+Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
+Reviewed-by: Andy Ritger <aritger@nvidia.com>
+Reviewed-by: Daniel Stone <daniels@collabora.com>
+[Pekka: move 'bool' to the same line with 'static']
+Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+
+(cherry picked from commit cc3a192b448153a7911d44aa0fa549099607911d)
+---
+ src/gl-renderer.c | 56 +++++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 42 insertions(+), 14 deletions(-)
+
+diff --git a/src/gl-renderer.c b/src/gl-renderer.c
+index 1d6d98c9b86b..887d131674f5 100644
+--- a/src/gl-renderer.c
++++ b/src/gl-renderer.c
+@@ -2701,6 +2701,34 @@ gl_renderer_destroy(struct weston_compositor *ec)
+ free(gr);
+ }
+
++static bool
++check_extension(const char *extensions, const char *extension)
++{
++ size_t extlen = strlen(extension);
++ const char *end = extensions + strlen(extensions);
++
++ while (extensions < end) {
++ size_t n = 0;
++
++ /* Skip whitespaces, if any */
++ if (*extensions == ' ') {
++ extensions++;
++ continue;
++ }
++
++ n = strcspn(extensions, " ");
++
++ /* Compare strings */
++ if (n == extlen && strncmp(extension, extensions, n) == 0)
++ return true; /* Found */
++
++ extensions += n;
++ }
++
++ /* Not found */
++ return false;
++}
++
+ static void
+ renderer_setup_egl_client_extensions(struct gl_renderer *gr)
+ {
+@@ -2712,7 +2740,7 @@ renderer_setup_egl_client_extensions(struct gl_renderer *gr)
+ return;
+ }
+
+- if (strstr(extensions, "EGL_EXT_platform_base"))
++ if (check_extension(extensions, "EGL_EXT_platform_base"))
+ gr->create_platform_window =
+ (void *) eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
+ else
+@@ -2742,7 +2770,7 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+ return -1;
+ }
+
+- if (strstr(extensions, "EGL_WL_bind_wayland_display"))
++ if (check_extension(extensions, "EGL_WL_bind_wayland_display"))
+ gr->has_bind_display = 1;
+ if (gr->has_bind_display) {
+ ret = gr->bind_display(gr->egl_display, ec->wl_display);
+@@ -2750,14 +2778,14 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+ gr->has_bind_display = 0;
+ }
+
+- if (strstr(extensions, "EGL_EXT_buffer_age"))
++ if (check_extension(extensions, "EGL_EXT_buffer_age"))
+ gr->has_egl_buffer_age = 1;
+ else
+ weston_log("warning: EGL_EXT_buffer_age not supported. "
+ "Performance could be affected.\n");
+
+ #ifdef EGL_EXT_swap_buffers_with_damage
+- if (strstr(extensions, "EGL_EXT_swap_buffers_with_damage"))
++ if (check_extension(extensions, "EGL_EXT_swap_buffers_with_damage"))
+ gr->swap_buffers_with_damage =
+ (void *) eglGetProcAddress("eglSwapBuffersWithDamageEXT");
+ else
+@@ -2766,12 +2794,12 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+ #endif
+
+ #ifdef EGL_MESA_configless_context
+- if (strstr(extensions, "EGL_MESA_configless_context"))
++ if (check_extension(extensions, "EGL_MESA_configless_context"))
+ gr->has_configless_context = 1;
+ #endif
+
+ #ifdef EGL_EXT_image_dma_buf_import
+- if (strstr(extensions, "EGL_EXT_image_dma_buf_import"))
++ if (check_extension(extensions, "EGL_EXT_image_dma_buf_import"))
+ gr->has_dmabuf_import = 1;
+ #endif
+
+@@ -2840,19 +2868,19 @@ gl_renderer_supports(struct weston_compositor *ec,
+ extensions);
+ }
+
+- if (!strstr(extensions, "EGL_EXT_platform_base"))
++ if (!check_extension(extensions, "EGL_EXT_platform_base"))
+ return 0;
+
+ snprintf(s, sizeof s, "EGL_KHR_platform_%s", extension_suffix);
+- if (strstr(extensions, s))
++ if (check_extension(extensions, s))
+ return 1;
+
+ snprintf(s, sizeof s, "EGL_EXT_platform_%s", extension_suffix);
+- if (strstr(extensions, s))
++ if (check_extension(extensions, s))
+ return 1;
+
+ snprintf(s, sizeof s, "EGL_MESA_platform_%s", extension_suffix);
+- if (strstr(extensions, s))
++ if (check_extension(extensions, s))
+ return 1;
+
+ /* at this point we definitely have some platform extensions but
+@@ -3104,22 +3132,22 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
+ return -1;
+ }
+
+- if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
++ if (!check_extension(extensions, "GL_EXT_texture_format_BGRA8888")) {
+ weston_log("GL_EXT_texture_format_BGRA8888 not available\n");
+ return -1;
+ }
+
+- if (strstr(extensions, "GL_EXT_read_format_bgra"))
++ if (check_extension(extensions, "GL_EXT_read_format_bgra"))
+ ec->read_format = PIXMAN_a8r8g8b8;
+ else
+ ec->read_format = PIXMAN_a8b8g8r8;
+
+ #ifdef GL_EXT_unpack_subimage
+- if (strstr(extensions, "GL_EXT_unpack_subimage"))
++ if (check_extension(extensions, "GL_EXT_unpack_subimage"))
+ gr->has_unpack_subimage = 1;
+ #endif
+
+- if (strstr(extensions, "GL_OES_EGL_image_external"))
++ if (check_extension(extensions, "GL_OES_EGL_image_external"))
+ gr->has_egl_image_external = 1;
+
+ glActiveTexture(GL_TEXTURE0);
+--
+2.7.4
+
diff --git a/0004-gl-renderer-Add-support-for-EGLDevice-EGLOutput.patch b/0004-gl-renderer-Add-support-for-EGLDevice-EGLOutput.patch
new file mode 100644
index 000000000000..f720cef9b67c
--- /dev/null
+++ b/0004-gl-renderer-Add-support-for-EGLDevice-EGLOutput.patch
@@ -0,0 +1,820 @@
+From 89af96dc92477e94383ea02712b46fa2da03a438 Mon Sep 17 00:00:00 2001
+From: "Miguel A. Vico" <mvicomoya@nvidia.com>
+Date: Mon, 21 Mar 2016 17:37:34 +0100
+Subject: [PATCH 4/7] gl-renderer: Add support for EGLDevice+EGLOutput
+X-NVConfidentiality: public
+
+EGLDevice provides means to enumerate native devices, and then create
+an EGL display connection from them.
+
+Similarly, EGLOutput will provide means to access different
+portions of display control hardware associated with an EGLDevice.
+
+For instance, EGLOutputLayer represents a portion of display
+control hardware that accepts an image as input and processes it
+for presentation on a display device.
+
+EGLStream implements a mechanism to communicate frame producers and
+frame consumers. By attaching an EGLOutputLayer consumer to a stream,
+a producer will be able to present frames on a display device.
+
+Thus, a compositor could produce frames and feed them to an
+EGLOutputLayer through an EGLStream for presentation on a display
+device.
+
+In a similar way, by attaching a GLTexture consumer to a stream, a
+producer (wayland client) could feed frames to a texture, which in
+turn can be used by a compositor to prepare the final frame to be
+presented.
+
+This change adds required logic to support presentation approach
+described above.
+
+Note that some unpublished EGL extensions were needed:
+
+ - EGL_NV_stream_attrib:
+ https://github.com/aritger/eglstreams-kms-example/blob/master/proposed-extensions/EGL_NV_stream_attrib.txt
+
+ - EGL_EXT_stream_acquire_mode:
+ https://github.com/aritger/eglstreams-kms-example/blob/master/proposed-extensions/EGL_EXT_stream_acquire_mode.txt
+
+ - EGL_NV_output_drm_flip_event:
+ https://github.com/aritger/eglstreams-kms-example/blob/master/proposed-extensions/EGL_NV_output_drm_flip_event.txt
+
+Also, in order to allow wl_buffers to be bound to EGLStreams, we
+kludged eglQueryWaylandBufferWL(EGL_WAYLAND_BUFFER_WL) to return
+the stream file descriptor.
+
+We think the proper way to handle this should be:
+
+ - Update WL_bind_wayland_display such that eglQueryWaylandBufferWL() accepts
+ a new attribute EGL_WAYLAND_BUFFER_TYPE_WL, returning
+ EGL_WAYLAND_BUFFER_EGLIMAGE_WL for the non-stream case.
+
+ - Add a new WL_wayland_buffer_eglstream extension, which would define
+ EGL_WAYLAND_BUFFER_EGLSTREAM_WL as a return value for
+ EGL_WAYLAND_BUFFER_TYPE_WL, and yet another attribute
+ EGL_WAYLAND_BUFFER_EGLSTREAM_FD_WL to query the stream file descriptor.
+
+Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
+Reviewed-by: Andy Ritger <aritger@nvidia.com>
+Reviewed-by: Adam Cheney <acheney@nvidia.com>
+---
+ src/gl-renderer.c | 476 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/gl-renderer.h | 26 +++
+ src/weston-egl-ext.h | 19 ++
+ 3 files changed, 517 insertions(+), 4 deletions(-)
+
+diff --git a/src/gl-renderer.c b/src/gl-renderer.c
+index 887d131674f5..07879cb83b60 100644
+--- a/src/gl-renderer.c
++++ b/src/gl-renderer.c
+@@ -30,6 +30,7 @@
+ #include <GLES2/gl2.h>
+ #include <GLES2/gl2ext.h>
+
++#include <unistd.h>
+ #include <stdbool.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -84,6 +85,8 @@ struct gl_output_state {
+ struct gl_border_image borders[4];
+ enum gl_border_status border_status;
+
++ EGLStreamKHR egl_stream;
++
+ struct weston_matrix output_matrix;
+ };
+
+@@ -159,6 +162,9 @@ struct gl_surface_state {
+ int height; /* in pixels */
+ int y_inverted;
+
++ EGLStreamKHR egl_stream;
++ bool stream_frame_acquired;
++
+ struct weston_surface *surface;
+
+ struct wl_listener surface_destroy_listener;
+@@ -202,6 +208,36 @@ struct gl_renderer {
+
+ int has_configless_context;
+
++ PFNEGLCREATESTREAMKHRPROC create_stream;
++ PFNEGLDESTROYSTREAMKHRPROC destroy_stream;
++ PFNEGLQUERYSTREAMKHRPROC query_stream;
++ int has_egl_stream;
++
++ PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC create_stream_producer_surface;
++ int has_egl_stream_producer_eglsurface;
++
++ PFNEGLSTREAMCONSUMEROUTPUTEXTPROC stream_consumer_output;
++ int has_egl_stream_consumer_egloutput;
++
++ PFNEGLSTREAMCONSUMERACQUIREKHRPROC stream_consumer_acquire;
++#ifdef EGL_EXT_stream_acquire_mode
++ PFNEGLSTREAMCONSUMERACQUIREATTRIBEXTPROC stream_consumer_acquire_attrib;
++#endif
++ int has_egl_stream_acquire_mode;
++
++ int has_egl_output_drm;
++ int has_egl_output_drm_flip_event;
++
++ PFNEGLGETOUTPUTLAYERSEXTPROC get_output_layers;
++ PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC query_output_layer_attrib;
++ int has_egl_output_base;
++
++ PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC create_stream_from_file_descriptor;
++ int has_egl_stream_cross_process_fd;
++
++ PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC stream_consumer_gltexture;
++ int has_egl_stream_consumer_gltexture;
++
+ int has_dmabuf_import;
+ struct wl_list dmabuf_images;
+
+@@ -735,6 +771,7 @@ draw_view(struct weston_view *ev, struct weston_output *output,
+ /* non-opaque region in surface coordinates: */
+ pixman_region32_t surface_blend;
+ GLint filter;
++ EGLint stream_state = EGL_STREAM_STATE_EMPTY_KHR;
+ int i;
+
+ /* In case of a runtime switch of renderers, we may not have received
+@@ -743,6 +780,21 @@ draw_view(struct weston_view *ev, struct weston_output *output,
+ if (!gs->shader)
+ return;
+
++ /* If using EGLStreams, only continue if we are certain we have something to
++ * render, i.e. a new frame is available or an old one was previously
++ * acquired and is ready to be re-used */
++ if (gs->egl_stream != EGL_NO_STREAM_KHR) {
++ if (gr->query_stream(gr->egl_display,
++ gs->egl_stream,
++ EGL_STREAM_STATE_KHR,
++ &stream_state) != EGL_TRUE)
++ return;
++
++ if (stream_state != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
++ !gs->stream_frame_acquired)
++ return;
++ }
++
+ pixman_region32_init(&repaint);
+ pixman_region32_intersect(&repaint,
+ &ev->transform.boundingbox, damage);
+@@ -774,6 +826,16 @@ draw_view(struct weston_view *ev, struct weston_output *output,
+ glTexParameteri(gs->target, GL_TEXTURE_MAG_FILTER, filter);
+ }
+
++ /* If using EGLStreams, we need to acquire the new frame, if any */
++ if (gs->egl_stream != EGL_NO_STREAM_KHR &&
++ stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) {
++ if (gr->stream_consumer_acquire(gr->egl_display,
++ gs->egl_stream) != EGL_TRUE)
++ goto out;
++
++ gs->stream_frame_acquired = true;
++ }
++
+ /* blended region is whole surface minus opaque region: */
+ pixman_region32_init_rect(&surface_blend, 0, 0,
+ ev->surface->width, ev->surface->height);
+@@ -1193,6 +1255,37 @@ gl_renderer_repaint_output(struct weston_output *output,
+ }
+
+ static int
++gl_renderer_output_stream_flip(struct weston_output *output,
++ void *flip_data)
++{
++#ifdef EGL_EXT_stream_acquire_mode
++ struct gl_output_state *go = get_output_state(output);
++ struct weston_compositor *compositor = output->compositor;
++ struct gl_renderer *gr = get_renderer(compositor);
++
++ EGLAttrib acquire_attribs[3] = { EGL_NONE };
++
++#ifdef EGL_NV_output_drm_flip_event
++ if (gr->has_egl_output_drm_flip_event) {
++ acquire_attribs[0] = EGL_DRM_FLIP_EVENT_DATA_NV;
++ acquire_attribs[1] = (EGLAttrib)flip_data;
++ acquire_attribs[2] = EGL_NONE;
++ }
++#endif
++
++ if (go->egl_stream != EGL_NO_STREAM_KHR)
++ if (EGL_TRUE != gr->stream_consumer_acquire_attrib(gr->egl_display,
++ go->egl_stream,
++ acquire_attribs))
++ return -1;
++
++ return 0;
++#else
++ return -1;
++#endif
++}
++
++static int
+ gl_renderer_read_pixels(struct weston_output *output,
+ pixman_format_code_t format, void *pixels,
+ uint32_t x, uint32_t y,
+@@ -1884,6 +1977,72 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
+ }
+
+ static void
++gl_renderer_attach_egl_fd_texture(struct weston_surface *es,
++ struct weston_buffer *buffer,
++ EGLNativeFileDescriptorKHR streamFd)
++{
++ struct weston_compositor *ec = es->compositor;
++ struct gl_renderer *gr = get_renderer(ec);
++ struct gl_surface_state *gs = get_surface_state(es);
++
++ /* If an invalid streamFd is provided, either there was an error creating
++ * the buffer or this buffer is already attached. Either case, there's
++ * nothing to be done */
++ if (streamFd < 0)
++ return;
++
++ /* Clean up current stream resources, if needed */
++ if (gs->egl_stream != EGL_NO_STREAM_KHR) {
++ gr->destroy_stream(gr->egl_display, gs->egl_stream);
++ gs->egl_stream = EGL_NO_STREAM_KHR;
++ gs->stream_frame_acquired = false;
++ }
++
++ gs->egl_stream =
++ gr->create_stream_from_file_descriptor(gr->egl_display, streamFd);
++ close(streamFd);
++
++ if (gs->egl_stream == EGL_NO_STREAM_KHR) {
++ weston_log("failed to create egl stream\n");
++ goto err_attach_egl_fd_base;
++ }
++
++ gs->shader = &gr->texture_shader_egl_external;
++ gs->target = GL_TEXTURE_EXTERNAL_OES;
++
++ glActiveTexture(GL_TEXTURE0);
++ ensure_textures(gs, 1);
++ glBindTexture(gs->target, gs->textures[0]);
++
++ if (gr->stream_consumer_gltexture(gr->egl_display, gs->egl_stream) != EGL_TRUE) {
++ weston_log("failed to set stream consumer\n");
++ goto err_attach_egl_fd_stream;
++ }
++
++ buffer->legacy_buffer = (void *)buffer->resource;
++ gr->query_buffer(gr->egl_display, buffer->legacy_buffer,
++ EGL_WIDTH, &buffer->width);
++ gr->query_buffer(gr->egl_display, buffer->legacy_buffer,
++ EGL_HEIGHT, &buffer->height);
++ buffer->y_inverted = 0;
++
++ gs->pitch = buffer->width;
++ gs->height = buffer->height;
++ gs->buffer_type = BUFFER_TYPE_EGL;
++ gs->y_inverted = buffer->y_inverted;
++
++ return;
++
++err_attach_egl_fd_stream:
++ gr->destroy_stream(gr->egl_display, gs->egl_stream);
++ gs->egl_stream = EGL_NO_STREAM_KHR;
++
++err_attach_egl_fd_base:
++ gl_renderer_print_egl_error_state();
++ return;
++}
++
++static void
+ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
+ {
+ struct weston_compositor *ec = es->compositor;
+@@ -1891,6 +2050,7 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
+ struct gl_surface_state *gs = get_surface_state(es);
+ struct wl_shm_buffer *shm_buffer;
+ struct linux_dmabuf_buffer *dmabuf;
++ EGLNativeFileDescriptorKHR streamFd;
+ EGLint format;
+ int i;
+
+@@ -1906,6 +2066,13 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
+ gs->num_textures = 0;
+ gs->buffer_type = BUFFER_TYPE_NULL;
+ gs->y_inverted = 1;
++
++ if (gs->egl_stream != EGL_NO_STREAM_KHR) {
++ gr->destroy_stream(gr->egl_display, gs->egl_stream);
++ gs->egl_stream = EGL_NO_STREAM_KHR;
++ gs->stream_frame_acquired = false;
++ }
++
+ return;
+ }
+
+@@ -1918,7 +2085,11 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
+ gl_renderer_attach_egl(es, buffer, format);
+ else if ((dmabuf = linux_dmabuf_buffer_get(buffer->resource)))
+ gl_renderer_attach_dmabuf(es, buffer, dmabuf);
+- else {
++ else if (gr->query_buffer(gr->egl_display, (void *) buffer->resource,
++ EGL_WAYLAND_BUFFER_WL, &streamFd)) {
++ /* FIXME: WL_bind_wayland_display violation */
++ gl_renderer_attach_egl_fd_texture(es, buffer, streamFd);
++ } else {
+ weston_log("unhandled buffer type!\n");
+ weston_buffer_reference(&gs->buffer_ref, NULL);
+ gs->buffer_type = BUFFER_TYPE_NULL;
+@@ -2106,6 +2277,10 @@ surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
+
+ weston_buffer_reference(&gs->buffer_ref, NULL);
+ pixman_region32_fini(&gs->texture_damage);
++
++ if (gs->egl_stream != EGL_NO_STREAM_KHR)
++ gr->destroy_stream(gr->egl_display, gs->egl_stream);
++
+ free(gs);
+ }
+
+@@ -2156,6 +2331,8 @@ gl_renderer_create_surface(struct weston_surface *surface)
+
+ gs->surface = surface;
+
++ gs->egl_stream = EGL_NO_STREAM_KHR;
++
+ pixman_region32_init(&gs->texture_damage);
+ surface->renderer_state = gs;
+
+@@ -2587,9 +2764,92 @@ gl_renderer_create_window_surface(struct gl_renderer *gr,
+ return egl_surface;
+ }
+
++static EGLSurface
++gl_renderer_create_stream_surface(struct gl_renderer *gr,
++ uint32_t plane_id,
++ uint32_t crtc_id,
++ EGLint width, EGLint height,
++ EGLStreamKHR *egl_stream)
++{
++ EGLint stream_attribs[] = {
++ EGL_STREAM_FIFO_LENGTH_KHR, 1,
++#ifdef EGL_EXT_stream_acquire_mode
++ EGL_CONSUMER_AUTO_ACQUIRE_EXT, EGL_FALSE,
++#endif
++ EGL_NONE
++ };
++ EGLAttrib output_attribs[3];
++ EGLint stream_producer_attribs[] = {
++ EGL_WIDTH, width,
++ EGL_HEIGHT, height,
++ EGL_NONE
++ };
++
++ EGLint num_layers;
++ EGLOutputLayerEXT output_layer;
++ EGLSurface egl_surface = EGL_NO_SURFACE;
++
++ *egl_stream = gr->create_stream(gr->egl_display, stream_attribs);
++
++ if (*egl_stream == EGL_NO_STREAM_KHR) {
++ weston_log("Failed to create EGL stream.\n");
++ goto err_egl_create_surf_base;
++ }
++
++ if (plane_id != ~0u) {
++ output_attribs[0] = EGL_DRM_PLANE_EXT;
++ output_attribs[1] = plane_id;
++ } else {
++ assert(crtc_id != ~0u);
++ output_attribs[0] = EGL_DRM_CRTC_EXT;
++ output_attribs[1] = crtc_id;
++ }
++ output_attribs[2] = EGL_NONE;
++
++ if (gr->get_output_layers(gr->egl_display,
++ output_attribs,
++ &output_layer,
++ 1, &num_layers) != EGL_TRUE) {
++ weston_log("Failed to get output layer.\n");
++ goto err_egl_create_surf_stream;
++ }
++
++ if (num_layers < 1) {
++ weston_log("Unable to find output layers.\n");
++ goto err_egl_create_surf_stream;
++ }
++
++ if (gr->stream_consumer_output(gr->egl_display, *egl_stream,
++ output_layer) != EGL_TRUE) {
++ weston_log("Failed to set EGL stream consumer.\n");
++ goto err_egl_create_surf_stream;
++ }
++
++ egl_surface = gr->create_stream_producer_surface(gr->egl_display,
++ gr->egl_config,
++ *egl_stream,
++ stream_producer_attribs);
++
++ if (egl_surface == EGL_NO_SURFACE) {
++ weston_log("Failed to create EGL producer surface.\n");
++ goto err_egl_create_surf_stream;
++ }
++
++ return egl_surface;
++
++err_egl_create_surf_stream:
++ gr->destroy_stream(gr->egl_display, *egl_stream);
++ *egl_stream = EGL_NO_STREAM_KHR;
++
++err_egl_create_surf_base:
++ gl_renderer_print_egl_error_state();
++ return EGL_NO_SURFACE;
++}
++
+ static int
+ gl_renderer_output_create(struct weston_output *output,
+- EGLSurface surface)
++ EGLSurface surface,
++ EGLStreamKHR stream)
+ {
+ struct weston_compositor *ec = output->compositor;
+ struct gl_renderer *gr = get_renderer(ec);
+@@ -2611,6 +2871,7 @@ gl_renderer_output_create(struct weston_output *output,
+ return -1;
+
+ go->egl_surface = surface;
++ go->egl_stream = stream;
+
+ for (i = 0; i < BUFFER_DAMAGE_COUNT; i++)
+ pixman_region32_init(&go->buffer_damage[i]);
+@@ -2639,13 +2900,41 @@ gl_renderer_output_window_create(struct weston_output *output,
+ config_attribs,
+ visual_id, n_ids);
+
+- ret = gl_renderer_output_create(output, egl_surface);
++ ret = gl_renderer_output_create(output, egl_surface, EGL_NO_STREAM_KHR);
+ if (ret < 0 && egl_surface != EGL_NO_SURFACE)
+ eglDestroySurface(gr->egl_display, egl_surface);
+
+ return ret;
+ }
+
++static int
++gl_renderer_output_stream_create(struct weston_output *output,
++ uint32_t plane_id, uint32_t crtc_id)
++{
++ struct weston_compositor *ec = output->compositor;
++ struct gl_renderer *gr = get_renderer(ec);
++ EGLSurface egl_surface = EGL_NO_SURFACE;
++ EGLStreamKHR egl_stream = EGL_NO_STREAM_KHR;
++ int ret;
++
++ egl_surface =
++ gl_renderer_create_stream_surface(gr,
++ plane_id, crtc_id,
++ output->current_mode->width,
++ output->current_mode->height,
++ &egl_stream);
++
++ ret = gl_renderer_output_create(output, egl_surface, egl_stream);
++ if (ret < 0) {
++ if (egl_surface != EGL_NO_SURFACE)
++ eglDestroySurface(gr->egl_display, egl_surface);
++ if (egl_stream != EGL_NO_STREAM_KHR)
++ gr->destroy_stream(gr->egl_display, egl_stream);
++ }
++
++ return ret;
++}
++
+ static void
+ gl_renderer_output_destroy(struct weston_output *output)
+ {
+@@ -2658,6 +2947,9 @@ gl_renderer_output_destroy(struct weston_output *output)
+
+ eglDestroySurface(gr->egl_display, go->egl_surface);
+
++ if (go->egl_stream != EGL_NO_STREAM_KHR)
++ gr->destroy_stream(gr->egl_display, go->egl_stream);
++
+ free(go);
+ }
+
+@@ -2762,6 +3054,26 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+ (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
+ gr->query_buffer =
+ (void *) eglGetProcAddress("eglQueryWaylandBufferWL");
++ gr->create_stream = (void *) eglGetProcAddress("eglCreateStreamKHR");
++ gr->destroy_stream = (void *) eglGetProcAddress("eglDestroyStreamKHR");
++ gr->query_stream = (void *) eglGetProcAddress("eglQueryStreamKHR");
++ gr->create_stream_producer_surface =
++ (void *) eglGetProcAddress("eglCreateStreamProducerSurfaceKHR");
++ gr->stream_consumer_output =
++ (void *) eglGetProcAddress("eglStreamConsumerOutputEXT");
++ gr->get_output_layers = (void *) eglGetProcAddress("eglGetOutputLayersEXT");
++ gr->query_output_layer_attrib =
++ (void *) eglGetProcAddress("eglQueryOutputLayerAttribEXT");
++ gr->create_stream_from_file_descriptor =
++ (void *) eglGetProcAddress("eglCreateStreamFromFileDescriptorKHR");
++ gr->stream_consumer_gltexture =
++ (void *) eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR");
++ gr->stream_consumer_acquire =
++ (void *) eglGetProcAddress("eglStreamConsumerAcquireKHR");
++#ifdef EGL_EXT_stream_acquire_mode
++ gr->stream_consumer_acquire_attrib =
++ (void *) eglGetProcAddress("eglStreamConsumerAcquireAttribEXT");
++#endif
+
+ extensions =
+ (const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
+@@ -2803,6 +3115,33 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+ gr->has_dmabuf_import = 1;
+ #endif
+
++ if (check_extension(extensions, "EGL_KHR_stream"))
++ gr->has_egl_stream = 1;
++
++ if (check_extension(extensions, "EGL_KHR_stream_producer_eglsurface"))
++ gr->has_egl_stream_producer_eglsurface = 1;
++
++ if (check_extension(extensions, "EGL_EXT_stream_consumer_egloutput"))
++ gr->has_egl_stream_consumer_egloutput = 1;
++
++ if (check_extension(extensions, "EGL_KHR_stream_consumer_gltexture"))
++ gr->has_egl_stream_consumer_gltexture = 1;
++
++ if (check_extension(extensions, "EGL_EXT_stream_acquire_mode"))
++ gr->has_egl_stream_acquire_mode = 1;
++
++ if (check_extension(extensions, "EGL_EXT_output_base"))
++ gr->has_egl_output_base = 1;
++
++ if (check_extension(extensions, "EGL_EXT_output_drm"))
++ gr->has_egl_output_drm = 1;
++
++ if (check_extension(extensions, "EGL_NV_output_drm_flip_event"))
++ gr->has_egl_output_drm_flip_event = 1;
++
++ if (check_extension(extensions, "EGL_KHR_stream_cross_process_fd"))
++ gr->has_egl_stream_cross_process_fd = 1;
++
+ renderer_setup_egl_client_extensions(gr);
+
+ return 0;
+@@ -2828,6 +3167,16 @@ static const EGLint gl_renderer_alpha_attribs[] = {
+ EGL_NONE
+ };
+
++static const EGLint gl_renderer_opaque_stream_attribs[] = {
++ EGL_SURFACE_TYPE, EGL_STREAM_BIT_KHR,
++ EGL_RED_SIZE, 1,
++ EGL_GREEN_SIZE, 1,
++ EGL_BLUE_SIZE, 1,
++ EGL_ALPHA_SIZE, 0,
++ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
++ EGL_NONE
++};
++
+ /** Checks whether a platform EGL client extension is supported
+ *
+ * \param ec The weston compositor
+@@ -2900,6 +3249,8 @@ platform_to_extension(EGLenum platform)
+ return "wayland";
+ case EGL_PLATFORM_X11_KHR:
+ return "x11";
++ case EGL_PLATFORM_DEVICE_EXT:
++ return "device";
+ default:
+ assert(0 && "bad EGL platform enum");
+ }
+@@ -2985,6 +3336,38 @@ gl_renderer_create(struct weston_compositor *ec, EGLenum platform,
+ if (gl_renderer_setup_egl_extensions(ec) < 0)
+ goto fail_with_error;
+
++ if (platform == EGL_PLATFORM_DEVICE_EXT) {
++ if (!gr->has_egl_output_base ||
++ !gr->has_egl_output_drm ||
++ !gr->has_egl_stream ||
++ !gr->has_egl_stream_producer_eglsurface ||
++ !gr->has_egl_stream_consumer_egloutput ||
++ !gr->has_egl_stream_consumer_gltexture ||
++ !gr->has_egl_stream_acquire_mode ||
++ !gr->has_egl_stream_cross_process_fd) {
++ weston_log("following required extensions not supported:\n"
++ "%s%s%s%s%s%s%s%s",
++ (gr->has_egl_output_base ? " EGL_EXT_output_base\n" : ""),
++ (gr->has_egl_output_drm ? " EGL_EXT_output_drm\n" : ""),
++ (gr->has_egl_stream ? " EGL_KHR_stream\n" : ""),
++ (gr->has_egl_stream_producer_eglsurface ?
++ " EGL_KHR_stream_producer_eglsurface\n" : ""),
++ (gr->has_egl_stream_consumer_egloutput ?
++ " EGL_EXT_stream_consumer_egloutput\n" : ""),
++ (gr->has_egl_stream_consumer_gltexture ?
++ " EGL_KHR_stream_consumer_gltexture\n" : ""),
++ (gr->has_egl_stream_acquire_mode ?
++ " EGL_EXT_stream_acquire_mode\n" : ""),
++ (gr->has_egl_stream_cross_process_fd ?
++ " EGL_KHR_stream_cross_process_fd\n" : ""));
++ goto fail_terminate;
++ }
++
++ if (!gr->has_egl_output_drm_flip_event)
++ weston_log("warning: EGL page flip event notification not"
++ " supported\n");
++ }
++
+ wl_list_init(&gr->dmabuf_images);
+ if (gr->has_dmabuf_import)
+ gr->base.import_dmabuf = gl_renderer_import_dmabuf;
+@@ -3176,15 +3559,100 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
+ return 0;
+ }
+
++static int
++gl_renderer_get_devices(EGLint max_devices, EGLDeviceEXT *devices,
++ EGLint *num_devices)
++{
++ const char *extensions;
++ PFNEGLQUERYDEVICESEXTPROC query_devices;
++
++ extensions = (const char *)eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
++ if (!extensions) {
++ weston_log("Retrieving EGL extension string failed.\n");
++ return -1;
++ }
++
++ if (!check_extension(extensions, "EGL_EXT_device_base")) {
++ weston_log("EGL_EXT_device_base not supported\n");
++ return -1;
++ }
++
++ query_devices = (void *) eglGetProcAddress("eglQueryDevicesEXT");
++ if (!query_devices) {
++ weston_log("Failed to get eglQueryDevicesEXT function\n");
++ return -1;
++ }
++
++ if (query_devices(max_devices, devices, num_devices) != EGL_TRUE) {
++ weston_log("Failed to query EGL Devices\n");
++ gl_renderer_print_egl_error_state();
++ return -1;
++ }
++
++ return 0;
++}
++
++static int
++gl_renderer_get_drm_device_file(EGLDeviceEXT device,
++ const char **drm_device_file)
++{
++ const char *extensions;
++ PFNEGLQUERYDEVICESTRINGEXTPROC query_device_string;
++
++ extensions = (const char *)eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
++ if (!extensions) {
++ weston_log("Retrieving EGL extension string failed.\n");
++ return -1;
++ }
++
++ if (!check_extension(extensions, "EGL_EXT_device_base")) {
++ weston_log("EGL_EXT_device_base not supported.\n");
++ return -1;
++ }
++
++ query_device_string = (void *) eglGetProcAddress("eglQueryDeviceStringEXT");
++ if (!query_device_string) {
++ weston_log("Failed to get eglQueryDeviceStringEXT function\n");
++ return -1;
++ }
++
++ extensions = query_device_string(device, EGL_EXTENSIONS);
++ if (!extensions) {
++ weston_log("Retrieving EGL extension string failed.\n");
++ return -1;
++ }
++
++ if (!check_extension(extensions, "EGL_EXT_device_drm")) {
++ weston_log("EGL_EXT_device_drm not supported.\n");
++ return -1;
++ }
++
++ (*drm_device_file) = query_device_string(device, EGL_DRM_DEVICE_FILE_EXT);
++ if (*drm_device_file == NULL) {
++ weston_log("Failed to query DRM device name.\n");
++ gl_renderer_print_egl_error_state();
++ return -1;
++ }
++
++ return 0;
++}
++
+ WL_EXPORT struct gl_renderer_interface gl_renderer_interface = {
+ .opaque_attribs = gl_renderer_opaque_attribs,
+ .alpha_attribs = gl_renderer_alpha_attribs,
++ .opaque_stream_attribs = gl_renderer_opaque_stream_attribs,
+
+ .create = gl_renderer_create,
+ .display = gl_renderer_display,
+ .output_window_create = gl_renderer_output_window_create,
++ .output_stream_create = gl_renderer_output_stream_create,
+ .output_destroy = gl_renderer_output_destroy,
+ .output_surface = gl_renderer_output_surface,
+ .output_set_border = gl_renderer_output_set_border,
+- .print_egl_error_state = gl_renderer_print_egl_error_state
++ .print_egl_error_state = gl_renderer_print_egl_error_state,
++
++ .get_devices = gl_renderer_get_devices,
++ .get_drm_device_file = gl_renderer_get_drm_device_file,
++
++ .output_stream_flip = gl_renderer_output_stream_flip
+ };
+diff --git a/src/gl-renderer.h b/src/gl-renderer.h
+index af8dd267e700..d1dc009b2f5e 100644
+--- a/src/gl-renderer.h
++++ b/src/gl-renderer.h
+@@ -62,6 +62,10 @@ typedef EGLSurface (*PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy,
+ #define EGL_PLATFORM_X11_KHR 0x31D5
+ #endif
+
++#ifndef EGL_PLATFORM_DEVICE_EXT
++#define EGL_PLATFORM_DEVICE_EXT 0x313F
++#endif
++
+ #define NO_EGL_PLATFORM 0
+
+ enum gl_renderer_border_side {
+@@ -74,6 +78,7 @@ enum gl_renderer_border_side {
+ struct gl_renderer_interface {
+ const EGLint *opaque_attribs;
+ const EGLint *alpha_attribs;
++ const EGLint *opaque_stream_attribs;
+
+ int (*create)(struct weston_compositor *ec,
+ EGLenum platform,
+@@ -92,6 +97,9 @@ struct gl_renderer_interface {
+ const EGLint *visual_id,
+ const int n_ids);
+
++ int (*output_stream_create)(struct weston_output *output,
++ uint32_t plane_id, uint32_t crtc_id);
++
+ void (*output_destroy)(struct weston_output *output);
+
+ EGLSurface (*output_surface)(struct weston_output *output);
+@@ -129,5 +137,23 @@ struct gl_renderer_interface {
+ int32_t tex_width, unsigned char *data);
+
+ void (*print_egl_error_state)(void);
++
++ int (*get_devices)(EGLint max_devices,
++ EGLDeviceEXT *devices,
++ EGLint *num_devices);
++
++ int (*get_drm_device_file)(EGLDeviceEXT device,
++ const char **drm_device_file);
++
++ /*
++ * output_stream_flip() makes the EGLOutput consumer attached to the
++ * corresponding <output> stream acquire the new available frame
++ * (repaint_output() has been called previously) and queue a page flip.
++ * Whenever DRM is the underlying API and EGL_NV_output_drm_flip_event is
++ * supported, page flip notification can be requested by passing a non-NULL
++ * <flip_data> pointer. Otherwise, compositors should rely on a different
++ * mechanism in order to re-schedule output repaints.
++ */
++ int (*output_stream_flip)(struct weston_output *output, void *flip_data);
+ };
+
+diff --git a/src/weston-egl-ext.h b/src/weston-egl-ext.h
+index 32f6108fbb83..2faab1567c77 100644
+--- a/src/weston-egl-ext.h
++++ b/src/weston-egl-ext.h
+@@ -116,5 +116,24 @@ typedef struct wl_buffer * (EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL) (
+ #define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+ #endif
+
++/*
++ * FIXME: Remove both EGL_EXT_stream_acquire_mode and
++ * EGL_NV_output_drm_flip_event definitions below once both extensions
++ * get published by Khronos and incorportated into Khronos' header files
++ */
++#ifndef EGL_EXT_stream_acquire_mode
++#define EGL_EXT_stream_acquire_mode 1
++#define EGL_CONSUMER_AUTO_ACQUIRE_EXT 0x332B
++typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
++#ifdef EGL_EGLEXT_PROTOTYPES
++EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribEXT (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
++#endif
++#endif /* EGL_EXT_stream_acquire_mode */
++
++#ifndef EGL_NV_output_drm_flip_event
++#define EGL_NV_output_drm_flip_event 1
++#define EGL_DRM_FLIP_EVENT_DATA_NV 0x333E
++#endif /* EGL_NV_output_drm_flip_event */
++
+
+ #endif
+--
+2.7.4
+
diff --git a/0005-compositor-drm-Gracefully-handle-vblank-and-flip-inv.patch b/0005-compositor-drm-Gracefully-handle-vblank-and-flip-inv.patch
new file mode 100644
index 000000000000..3c98a74abc15
--- /dev/null
+++ b/0005-compositor-drm-Gracefully-handle-vblank-and-flip-inv.patch
@@ -0,0 +1,82 @@
+From 851f5b55210835e6e7c5699d87e18e09cbbe69e3 Mon Sep 17 00:00:00 2001
+From: "Miguel A. Vico" <mvicomoya@nvidia.com>
+Date: Mon, 21 Mar 2016 17:37:35 +0100
+Subject: [PATCH 5/7] compositor-drm: Gracefully handle vblank and flip invalid
+ timestamps
+X-NVConfidentiality: public
+
+Instant query for vblank timestamp may always fail, resulting in
+never scheduling a full repaint in drm_output_start_repaint_loop().
+
+Additionally, timestamp provided in page_flip_handler() may also be
+invalid.
+
+This change makes both drm_output_start_repaint_loop() and
+page_flip_handler() to schedule a full repaint in any of the
+situations above.
+
+Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
+Reviewed-by: Andy Ritger <aritger@nvidia.com>
+---
+ src/compositor-drm.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/src/compositor-drm.c b/src/compositor-drm.c
+index ded15f83c3e6..a6d4573a922f 100644
+--- a/src/compositor-drm.c
++++ b/src/compositor-drm.c
+@@ -1,6 +1,7 @@
+ /*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
++ * Copyright © 2016 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+@@ -761,8 +762,16 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
+ vbl.request.type |= drm_waitvblank_pipe(output);
+ ret = drmWaitVBlank(backend->drm.fd, &vbl);
+
+- /* Error ret or zero timestamp means failure to get valid timestamp */
+- if ((ret == 0) && (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0)) {
++ if (ret) {
++ /* Immediate query failed. It may always fail so we'll never get a valid
++ * timestamp to update msc and call into finish frame. Hence, jump to
++ * finish frame here.
++ */
++ goto finish_frame;
++ }
++
++ /* Zero timestamp means failure to get valid timestamp */
++ if (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0) {
+ ts.tv_sec = vbl.reply.tval_sec;
+ ts.tv_nsec = vbl.reply.tval_usec * 1000;
+
+@@ -783,7 +792,7 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
+ }
+ }
+
+- /* Immediate query didn't provide valid timestamp.
++ /* Immediate query succeeded, but didn't provide valid timestamp.
+ * Use pageflip fallback.
+ */
+ fb_id = output->current->fb_id;
+@@ -869,6 +878,15 @@ page_flip_handler(int fd, unsigned int frame,
+ else if (!output->vblank_pending) {
+ ts.tv_sec = sec;
+ ts.tv_nsec = usec * 1000;
++
++ /* Zero timestamp means failure to get valid timestamp, so immediately
++ * finish frame */
++ if (ts.tv_sec == 0 && ts.tv_nsec == 0) {
++ weston_compositor_read_presentation_clock(output->base.compositor,
++ &ts);
++ flags = PRESENTATION_FEEDBACK_INVALID;
++ }
++
+ weston_output_finish_frame(&output->base, &ts, flags);
+
+ /* We can't call this from frame_notify, because the output's
+--
+2.7.4
+
diff --git a/0006-compositor-drm-Renaming-of-gbm-fields.patch b/0006-compositor-drm-Renaming-of-gbm-fields.patch
new file mode 100644
index 000000000000..7048d84cad69
--- /dev/null
+++ b/0006-compositor-drm-Renaming-of-gbm-fields.patch
@@ -0,0 +1,228 @@
+From b50d1674382c982747b9091215bb02c860380fd9 Mon Sep 17 00:00:00 2001
+From: "Miguel A. Vico" <mvicomoya@nvidia.com>
+Date: Mon, 21 Mar 2016 17:41:03 +0100
+Subject: [PATCH 6/7] compositor-drm: Renaming of gbm fields
+X-NVConfidentiality: public
+
+In preparation for follow-on changes to support frame presentation
+through EGLDevice+EGLOutput, this change includes the following:
+ - Rename drm_backend::format to gbm_format
+ - Rename drm_output::format to gbm_format
+ - Rename drm_output::surface to gbm_surface
+ - Rename drm_output::cursor_bo to gbm_cursor_bo
+
+Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
+Reviewed-by: Andy Ritger <aritger@nvidia.com>
+Reviewed-by: Daniel Stone <daniels@collabora.com>
+[Pekka: trivial rebase out of the series]
+Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+
+(cherry picked from commit fcf4b6c0aef3d2e3afda5fa8a4d4127585f7231b)
+
+Conflicts:
+ src/compositor-drm.c
+---
+ src/compositor-drm.c | 58 ++++++++++++++++++++++++++--------------------------
+ 1 file changed, 29 insertions(+), 29 deletions(-)
+
+diff --git a/src/compositor-drm.c b/src/compositor-drm.c
+index a6d4573a922f..6c2816152307 100644
+--- a/src/compositor-drm.c
++++ b/src/compositor-drm.c
+@@ -107,7 +107,7 @@ struct drm_backend {
+ uint32_t crtc_allocator;
+ uint32_t connector_allocator;
+ struct wl_listener session_listener;
+- uint32_t format;
++ uint32_t gbm_format;
+
+ /* we need these parameters in order to not fail drmModeAddFB2()
+ * due to out of bounds dimensions, and then mistakenly set
+@@ -170,7 +170,7 @@ struct drm_output {
+ drmModeCrtcPtr original_crtc;
+ struct drm_edid edid;
+ drmModePropertyPtr dpms_prop;
+- uint32_t format;
++ uint32_t gbm_format;
+
+ enum dpms_enum dpms;
+
+@@ -178,8 +178,8 @@ struct drm_output {
+ int page_flip_pending;
+ int destroy_pending;
+
+- struct gbm_surface *surface;
+- struct gbm_bo *cursor_bo[2];
++ struct gbm_surface *gbm_surface;
++ struct gbm_bo *gbm_cursor_bo[2];
+ struct weston_plane cursor_plane;
+ struct weston_plane fb_plane;
+ struct weston_view *cursor_view;
+@@ -439,7 +439,7 @@ drm_output_release_fb(struct drm_output *output, struct drm_fb *fb)
+ if (fb->is_client_buffer)
+ gbm_bo_destroy(fb->bo);
+ else
+- gbm_surface_release_buffer(output->surface,
++ gbm_surface_release_buffer(output->gbm_surface,
+ fb->bo);
+ }
+ }
+@@ -468,7 +468,7 @@ drm_output_check_scanout_format(struct drm_output *output,
+ pixman_region32_fini(&r);
+ }
+
+- if (output->format == format)
++ if (output->gbm_format == format)
+ return format;
+
+ return 0;
+@@ -531,16 +531,16 @@ drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
+ output->base.compositor->renderer->repaint_output(&output->base,
+ damage);
+
+- bo = gbm_surface_lock_front_buffer(output->surface);
++ bo = gbm_surface_lock_front_buffer(output->gbm_surface);
+ if (!bo) {
+ weston_log("failed to lock front buffer: %m\n");
+ return;
+ }
+
+- output->next = drm_fb_get_from_bo(bo, b, output->format);
++ output->next = drm_fb_get_from_bo(bo, b, output->gbm_format);
+ if (!output->next) {
+ weston_log("failed to get drm_fb for bo\n");
+- gbm_surface_release_buffer(output->surface, bo);
++ gbm_surface_release_buffer(output->gbm_surface, bo);
+ return;
+ }
+ }
+@@ -1210,7 +1210,7 @@ drm_output_set_cursor(struct drm_output *output)
+ pixman_region32_fini(&output->cursor_plane.damage);
+ pixman_region32_init(&output->cursor_plane.damage);
+ output->current_cursor ^= 1;
+- bo = output->cursor_bo[output->current_cursor];
++ bo = output->gbm_cursor_bo[output->current_cursor];
+
+ cursor_bo_update(b, bo, ev);
+ handle = gbm_bo_get_handle(bo).s32;
+@@ -1362,7 +1362,7 @@ drm_output_destroy(struct weston_output *output_base)
+ drm_output_fini_pixman(output);
+ } else {
+ gl_renderer->output_destroy(output_base);
+- gbm_surface_destroy(output->surface);
++ gbm_surface_destroy(output->gbm_surface);
+ }
+
+ weston_plane_release(&output->fb_plane);
+@@ -1463,7 +1463,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
+ }
+ } else {
+ gl_renderer->output_destroy(&output->base);
+- gbm_surface_destroy(output->surface);
++ gbm_surface_destroy(output->gbm_surface);
+
+ if (drm_output_init_egl(output, b) < 0) {
+ weston_log("failed to init output egl state with "
+@@ -1595,8 +1595,8 @@ static int
+ drm_backend_create_gl_renderer(struct drm_backend *b)
+ {
+ EGLint format[3] = {
+- b->format,
+- fallback_format_for(b->format),
++ b->gbm_format,
++ fallback_format_for(b->gbm_format),
+ 0,
+ };
+ int n_formats = 2;
+@@ -1853,18 +1853,18 @@ static int
+ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
+ {
+ EGLint format[2] = {
+- output->format,
+- fallback_format_for(output->format),
++ output->gbm_format,
++ fallback_format_for(output->gbm_format),
+ };
+ int i, flags, n_formats = 1;
+
+- output->surface = gbm_surface_create(b->gbm,
++ output->gbm_surface = gbm_surface_create(b->gbm,
+ output->base.current_mode->width,
+ output->base.current_mode->height,
+ format[0],
+ GBM_BO_USE_SCANOUT |
+ GBM_BO_USE_RENDERING);
+- if (!output->surface) {
++ if (!output->gbm_surface) {
+ weston_log("failed to create gbm surface\n");
+ return -1;
+ }
+@@ -1872,28 +1872,28 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
+ if (format[1])
+ n_formats = 2;
+ if (gl_renderer->output_window_create(&output->base,
+- (EGLNativeWindowType)output->surface,
+- output->surface,
++ (EGLNativeWindowType)output->gbm_surface,
++ output->gbm_surface,
+ gl_renderer->opaque_attribs,
+ format,
+ n_formats) < 0) {
+ weston_log("failed to create gl renderer output state\n");
+- gbm_surface_destroy(output->surface);
++ gbm_surface_destroy(output->gbm_surface);
+ return -1;
+ }
+
+ flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE;
+
+ for (i = 0; i < 2; i++) {
+- if (output->cursor_bo[i])
++ if (output->gbm_cursor_bo[i])
+ continue;
+
+- output->cursor_bo[i] =
++ output->gbm_cursor_bo[i] =
+ gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
+ GBM_FORMAT_ARGB8888, flags);
+ }
+
+- if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
++ if (output->gbm_cursor_bo[0] == NULL || output->gbm_cursor_bo[1] == NULL) {
+ weston_log("cursor buffers unavailable, using gl cursors\n");
+ b->cursors_are_broken = 1;
+ }
+@@ -2375,9 +2375,9 @@ create_output_for_connector(struct drm_backend *b,
+ free(s);
+
+ if (get_gbm_format_from_section(section,
+- b->format,
+- &output->format) == -1)
+- output->format = b->format;
++ b->gbm_format,
++ &output->gbm_format) == -1)
++ output->gbm_format = b->gbm_format;
+
+ weston_config_section_get_string(section, "seat", &s, "");
+ setup_output_seat_constraint(b, &output->base, s);
+@@ -2992,7 +2992,7 @@ recorder_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key,
+ struct drm_output, base.link);
+
+ if (!output->recorder) {
+- if (output->format != GBM_FORMAT_XRGB8888) {
++ if (output->gbm_format != GBM_FORMAT_XRGB8888) {
+ weston_log("failed to start vaapi recorder: "
+ "output format not supported\n");
+ return;
+@@ -3118,7 +3118,7 @@ drm_backend_create(struct weston_compositor *compositor,
+ section = weston_config_get_section(config, "core", NULL, NULL);
+ if (get_gbm_format_from_section(section,
+ GBM_FORMAT_XRGB8888,
+- &b->format) == -1)
++ &b->gbm_format) == -1)
+ goto err_base;
+
+ b->use_pixman = param->use_pixman;
+--
+2.7.4
+
diff --git a/0007-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch b/0007-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch
new file mode 100644
index 000000000000..dc1cf8129649
--- /dev/null
+++ b/0007-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch
@@ -0,0 +1,552 @@
+From c285314728543280bf9ebd4e2776fe5cf4d096b1 Mon Sep 17 00:00:00 2001
+From: "Miguel A. Vico" <mvicomoya@nvidia.com>
+Date: Mon, 21 Mar 2016 17:41:32 +0100
+Subject: [PATCH 7/7] compositor-drm: Add support for EGLDevice+EGLOutput
+X-NVConfidentiality: public
+
+As previously stated, EGLDevice and EGLOutput will provide means
+to access native device objects and different portions of display
+control hardware respectively.
+
+Whenever EGL_EXT_device_drm extension is present, EGLDevice can
+be used to enumerate and access DRM KMS devices, and EGLOutputLayer
+to enumerate and access DRM KMS crtcs and planes.
+
+By using EGLStreams and attaching an EGLOutputLayer consumer
+(representing a DRM KMS crtc or plane) to it, compositor-drm can
+produce final composition frames and present them on a DRM device.
+
+This change adds required logic to support presentation through
+EGLDevice+EGLOutput+EGLStream. Whether GBM or EGLDevice should be
+used can be controlled by --use-egldevice backend argument.
+
+Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
+Reviewed-by: Andy Ritger <aritger@nvidia.com>
+Reviewed-by: Adam Cheney <acheney@nvidia.com>
+---
+ src/compositor-drm.c | 319 +++++++++++++++++++++++++++++++++++----------------
+ src/main.c | 1 +
+ 2 files changed, 224 insertions(+), 96 deletions(-)
+
+diff --git a/src/compositor-drm.c b/src/compositor-drm.c
+index 6c2816152307..58f916a27fc8 100644
+--- a/src/compositor-drm.c
++++ b/src/compositor-drm.c
+@@ -75,6 +75,10 @@
+ #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
+ #endif
+
++#ifndef EGL_DRM_MASTER_FD_EXT
++#define EGL_DRM_MASTER_FD_EXT 0x333C
++#endif
++
+ static int option_current_mode = 0;
+
+ enum output_config {
+@@ -101,7 +105,10 @@ struct drm_backend {
+ int fd;
+ char *filename;
+ } drm;
++
++ EGLDeviceEXT egldevice;
+ struct gbm_device *gbm;
++
+ uint32_t *crtcs;
+ int num_crtcs;
+ uint32_t crtc_allocator;
+@@ -124,6 +131,7 @@ struct drm_backend {
+ int cursors_are_broken;
+
+ int use_pixman;
++ int use_egldevice;
+
+ uint32_t prev_state;
+
+@@ -225,6 +233,7 @@ struct drm_parameters {
+ int connector;
+ int tty;
+ int use_pixman;
++ int use_egldevice;
+ const char *seat_id;
+ };
+
+@@ -531,17 +540,21 @@ drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
+ output->base.compositor->renderer->repaint_output(&output->base,
+ damage);
+
+- bo = gbm_surface_lock_front_buffer(output->gbm_surface);
+- if (!bo) {
+- weston_log("failed to lock front buffer: %m\n");
+- return;
+- }
++ if (b->use_egldevice)
++ output->next = output->dumb[0];
++ else {
++ bo = gbm_surface_lock_front_buffer(output->gbm_surface);
++ if (!bo) {
++ weston_log("failed to lock front buffer: %m\n");
++ return;
++ }
+
+- output->next = drm_fb_get_from_bo(bo, b, output->gbm_format);
+- if (!output->next) {
+- weston_log("failed to get drm_fb for bo\n");
+- gbm_surface_release_buffer(output->gbm_surface, bo);
+- return;
++ output->next = drm_fb_get_from_bo(bo, b, output->gbm_format);
++ if (!output->next) {
++ weston_log("failed to get drm_fb for bo\n");
++ gbm_surface_release_buffer(output->gbm_surface, bo);
++ return;
++ }
+ }
+ }
+
+@@ -666,9 +679,14 @@ drm_output_repaint(struct weston_output *output_base,
+ output_base->set_dpms(output_base, WESTON_DPMS_ON);
+ }
+
+- if (drmModePageFlip(backend->drm.fd, output->crtc_id,
+- output->next->fb_id,
+- DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
++ if (backend->use_egldevice)
++ ret = gl_renderer->output_stream_flip(&output->base, output);
++ else
++ ret = drmModePageFlip(backend->drm.fd, output->crtc_id,
++ output->next->fb_id,
++ DRM_MODE_PAGE_FLIP_EVENT, output);
++
++ if (ret < 0) {
+ weston_log("queueing pageflip failed: %m\n");
+ goto err_pageflip;
+ }
+@@ -739,7 +757,6 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
+ struct drm_output *output = (struct drm_output *) output_base;
+ struct drm_backend *backend = (struct drm_backend *)
+ output_base->compositor->backend;
+- uint32_t fb_id;
+ struct timespec ts, tnow;
+ struct timespec vbl2now;
+ int64_t refresh_nsec;
+@@ -795,10 +812,14 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
+ /* Immediate query succeeded, but didn't provide valid timestamp.
+ * Use pageflip fallback.
+ */
+- fb_id = output->current->fb_id;
++ if (backend->use_egldevice)
++ ret = gl_renderer->output_stream_flip(&output->base, output);
++ else
++ ret = drmModePageFlip(backend->drm.fd, output->crtc_id,
++ output->current->fb_id,
++ DRM_MODE_PAGE_FLIP_EVENT, output);
+
+- if (drmModePageFlip(backend->drm.fd, output->crtc_id, fb_id,
+- DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
++ if (ret < 0) {
+ weston_log("queueing pageflip failed: %m\n");
+ goto finish_frame;
+ }
+@@ -1328,6 +1349,9 @@ static void
+ drm_output_fini_pixman(struct drm_output *output);
+
+ static void
++drm_output_fini_egl(struct drm_output *output);
++
++static void
+ drm_output_destroy(struct weston_output *output_base)
+ {
+ struct drm_output *output = (struct drm_output *) output_base;
+@@ -1358,12 +1382,10 @@ drm_output_destroy(struct weston_output *output_base)
+ b->crtc_allocator &= ~(1 << output->crtc_id);
+ b->connector_allocator &= ~(1 << output->connector_id);
+
+- if (b->use_pixman) {
++ if (b->use_pixman)
+ drm_output_fini_pixman(output);
+- } else {
+- gl_renderer->output_destroy(output_base);
+- gbm_surface_destroy(output->gbm_surface);
+- }
++ else
++ drm_output_fini_egl(output);
+
+ weston_plane_release(&output->fb_plane);
+ weston_plane_release(&output->cursor_plane);
+@@ -1462,9 +1484,7 @@ drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mo
+ return -1;
+ }
+ } else {
+- gl_renderer->output_destroy(&output->base);
+- gbm_surface_destroy(output->gbm_surface);
+-
++ drm_output_fini_egl(output);
+ if (drm_output_init_egl(output, b) < 0) {
+ weston_log("failed to init output egl state with "
+ "new mode");
+@@ -1551,11 +1571,6 @@ create_gbm_device(int fd)
+ {
+ struct gbm_device *gbm;
+
+- gl_renderer = weston_load_module("gl-renderer.so",
+- "gl_renderer_interface");
+- if (!gl_renderer)
+- return NULL;
+-
+ /* GBM will load a dri driver, but even though they need symbols from
+ * libglapi, in some version of Mesa they are not linked to it. Since
+ * only the gl-renderer module links to it, the call above won't make
+@@ -1568,6 +1583,39 @@ create_gbm_device(int fd)
+ return gbm;
+ }
+
++static EGLDeviceEXT
++create_egldevice(const char *filename)
++{
++ EGLDeviceEXT egldevice = EGL_NO_DEVICE_EXT;
++ EGLDeviceEXT *devices;
++ EGLint num_devices;
++ const char *drm_path;
++ int i;
++
++ if (gl_renderer->get_devices(0, NULL, &num_devices) < 0 ||
++ num_devices < 1)
++ return EGL_NO_DEVICE_EXT;
++
++ devices = zalloc(num_devices * sizeof *devices);
++ if (!devices)
++ return EGL_NO_DEVICE_EXT;
++
++ if (gl_renderer->get_devices(num_devices, devices, &num_devices) < 0) {
++ free(devices);
++ return EGL_NO_DEVICE_EXT;
++ }
++
++ for (i = 0; i < num_devices; i++)
++ if (gl_renderer->get_drm_device_file(devices[i], &drm_path) == 0 &&
++ strcmp(filename, drm_path) == 0) {
++ egldevice = devices[i];
++ break;
++ }
++
++ free(devices);
++ return egldevice;
++}
++
+ /* When initializing EGL, if the preferred buffer format isn't available
+ * we may be able to susbstitute an ARGB format for an XRGB one.
+ *
+@@ -1594,38 +1642,59 @@ fallback_format_for(uint32_t format)
+ static int
+ drm_backend_create_gl_renderer(struct drm_backend *b)
+ {
+- EGLint format[3] = {
++ EGLint platform_attribs[] = {
++ EGL_DRM_MASTER_FD_EXT, b->drm.fd,
++ EGL_NONE
++ };
++ EGLint format[] = {
+ b->gbm_format,
+ fallback_format_for(b->gbm_format),
+- 0,
++ 0
+ };
+ int n_formats = 2;
+
+ if (format[1])
+ n_formats = 3;
+- if (gl_renderer->create(b->compositor,
+- EGL_PLATFORM_GBM_KHR,
+- (void *)b->gbm,
+- NULL,
+- gl_renderer->opaque_attribs,
+- format,
+- n_formats) < 0) {
+- return -1;
+- }
+
+- return 0;
++ if (b->use_egldevice)
++ return gl_renderer->create(b->compositor,
++ EGL_PLATFORM_DEVICE_EXT,
++ (void *)b->egldevice,
++ platform_attribs,
++ gl_renderer->opaque_stream_attribs,
++ NULL,
++ 0);
++ else
++ return gl_renderer->create(b->compositor,
++ EGL_PLATFORM_GBM_KHR,
++ b->gbm,
++ NULL,
++ gl_renderer->opaque_attribs,
++ format,
++ n_formats);
+ }
+
+ static int
+ init_egl(struct drm_backend *b)
+ {
+- b->gbm = create_gbm_device(b->drm.fd);
+-
+- if (!b->gbm)
++ gl_renderer = weston_load_module("gl-renderer.so",
++ "gl_renderer_interface");
++ if (!gl_renderer)
+ return -1;
+
++ if (b->use_egldevice) {
++ b->egldevice = create_egldevice(b->drm.filename);
++ if (b->egldevice == EGL_NO_DEVICE_EXT)
++ return -1;
++ } else {
++ b->gbm = create_gbm_device(b->drm.fd);
++ if (!b->gbm)
++ return -1;
++ }
++
+ if (drm_backend_create_gl_renderer(b) < 0) {
+- gbm_device_destroy(b->gbm);
++ if (b->gbm)
++ gbm_device_destroy(b->gbm);
+ return -1;
+ }
+
+@@ -1852,55 +1921,94 @@ find_crtc_for_connector(struct drm_backend *b,
+ static int
+ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
+ {
+- EGLint format[2] = {
+- output->gbm_format,
+- fallback_format_for(output->gbm_format),
+- };
+- int i, flags, n_formats = 1;
+-
+- output->gbm_surface = gbm_surface_create(b->gbm,
+- output->base.current_mode->width,
+- output->base.current_mode->height,
+- format[0],
+- GBM_BO_USE_SCANOUT |
+- GBM_BO_USE_RENDERING);
+- if (!output->gbm_surface) {
+- weston_log("failed to create gbm surface\n");
+- return -1;
+- }
++ if (b->use_egldevice) {
++ int w = output->base.current_mode->width;
++ int h = output->base.current_mode->height;
+
+- if (format[1])
+- n_formats = 2;
+- if (gl_renderer->output_window_create(&output->base,
+- (EGLNativeWindowType)output->gbm_surface,
+- output->gbm_surface,
+- gl_renderer->opaque_attribs,
+- format,
+- n_formats) < 0) {
+- weston_log("failed to create gl renderer output state\n");
+- gbm_surface_destroy(output->gbm_surface);
+- return -1;
+- }
++ /* Create a dumb fb for modesetting */
++ output->dumb[0] = drm_fb_create_dumb(b, w, h);
++ if (!output->dumb[0]) {
++ weston_log("failed to create dumb framebuffer\n");
++ return -1;
++ }
+
+- flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE;
++ if (gl_renderer->output_stream_create(&output->base, ~0u,
++ output->crtc_id) < 0) {
++ weston_log("failed to create gl renderer output stream state\n");
++ drm_fb_destroy_dumb(output->dumb[0]);
++ output->dumb[0] = NULL;
++ return -1;
++ }
+
+- for (i = 0; i < 2; i++) {
+- if (output->gbm_cursor_bo[i])
+- continue;
++ /* FIXME: Add hw planes and cursors for EGL device when supported */
++ b->sprites_are_broken = 1;
++ b->cursors_are_broken = 1;
++ } else {
++ EGLint format[2] = {
++ output->gbm_format,
++ fallback_format_for(output->gbm_format),
++ };
++ int i, flags, n_formats = 1;
++
++ output->gbm_surface = gbm_surface_create(b->gbm,
++ output->base.current_mode->width,
++ output->base.current_mode->height,
++ format[0],
++ GBM_BO_USE_SCANOUT |
++ GBM_BO_USE_RENDERING);
++ if (!output->gbm_surface) {
++ weston_log("failed to create gbm surface\n");
++ return -1;
++ }
+
+- output->gbm_cursor_bo[i] =
+- gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
+- GBM_FORMAT_ARGB8888, flags);
+- }
++ if (format[1])
++ n_formats = 2;
++ if (gl_renderer->output_window_create(
++ &output->base,
++ (EGLNativeWindowType)output->gbm_surface,
++ output->gbm_surface,
++ gl_renderer->opaque_attribs,
++ format,
++ n_formats) < 0) {
++ weston_log("failed to create gl renderer output state\n");
++ gbm_surface_destroy(output->gbm_surface);
++ return -1;
++ }
+
+- if (output->gbm_cursor_bo[0] == NULL || output->gbm_cursor_bo[1] == NULL) {
+- weston_log("cursor buffers unavailable, using gl cursors\n");
+- b->cursors_are_broken = 1;
++ flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE;
++
++ for (i = 0; i < 2; i++) {
++ if (output->gbm_cursor_bo[i])
++ continue;
++
++ output->gbm_cursor_bo[i] =
++ gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
++ GBM_FORMAT_ARGB8888, flags);
++ }
++
++ if (output->gbm_cursor_bo[0] == NULL || output->gbm_cursor_bo[1] == NULL) {
++ weston_log("cursor buffers unavailable, using gl cursors\n");
++ b->cursors_are_broken = 1;
++ }
+ }
+
+ return 0;
+ }
+
++static void
++drm_output_fini_egl(struct drm_output *output)
++{
++ gl_renderer->output_destroy(&output->base);
++
++ if (output->dumb[0]) {
++ drm_fb_destroy_dumb(output->dumb[0]);
++ output->dumb[0] = NULL;
++ }
++
++ if (output->gbm_surface)
++ gbm_surface_destroy(output->gbm_surface);
++}
++
+ static int
+ drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
+ {
+@@ -2374,10 +2482,11 @@ create_output_for_connector(struct drm_backend *b,
+
+ free(s);
+
+- if (get_gbm_format_from_section(section,
+- b->gbm_format,
+- &output->gbm_format) == -1)
+- output->gbm_format = b->gbm_format;
++ if (!b->use_egldevice)
++ if (get_gbm_format_from_section(section,
++ b->gbm_format,
++ &output->gbm_format) == -1)
++ output->gbm_format = b->gbm_format;
+
+ weston_config_section_get_string(section, "seat", &s, "");
+ setup_output_seat_constraint(b, &output->base, s);
+@@ -2988,6 +3097,11 @@ recorder_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key,
+ struct drm_output *output;
+ int width, height;
+
++ if (b->use_egldevice) {
++ weston_log("recorder not supported with EGL device\n");
++ return;
++ }
++
+ output = container_of(b->compositor->output_list.next,
+ struct drm_output, base.link);
+
+@@ -3043,11 +3157,20 @@ switch_to_gl_renderer(struct drm_backend *b)
+
+ weston_log("Switching to GL renderer\n");
+
+- b->gbm = create_gbm_device(b->drm.fd);
+- if (!b->gbm) {
+- weston_log("Failed to create gbm device. "
+- "Aborting renderer switch\n");
+- return;
++ if (b->use_egldevice) {
++ b->egldevice = create_egldevice(b->drm.filename);
++ if (b->egldevice == EGL_NO_DEVICE_EXT) {
++ weston_log("Failed to create EGL device. "
++ "Aborting renderer switch\n");
++ return;
++ }
++ } else {
++ b->gbm = create_gbm_device(b->drm.fd);
++ if (!b->gbm) {
++ weston_log("Failed to create gbm device. "
++ "Aborting renderer switch\n");
++ return;
++ }
+ }
+
+ wl_list_for_each(output, &b->compositor->output_list, base.link)
+@@ -3056,7 +3179,8 @@ switch_to_gl_renderer(struct drm_backend *b)
+ b->compositor->renderer->destroy(b->compositor);
+
+ if (drm_backend_create_gl_renderer(b) < 0) {
+- gbm_device_destroy(b->gbm);
++ if (b->gbm)
++ gbm_device_destroy(b->gbm);
+ weston_log("Failed to create GL renderer. Quitting.\n");
+ /* FIXME: we need a function to shutdown cleanly */
+ assert(0);
+@@ -3122,6 +3246,7 @@ drm_backend_create(struct weston_compositor *compositor,
+ goto err_base;
+
+ b->use_pixman = param->use_pixman;
++ b->use_egldevice = param->use_egldevice;
+
+ /* Check if we run drm-backend using weston-launch */
+ compositor->launcher = weston_launcher_connect(compositor, param->tty,
+@@ -3246,7 +3371,8 @@ err_drm_source:
+ err_udev_input:
+ udev_input_destroy(&b->input);
+ err_sprite:
+- gbm_device_destroy(b->gbm);
++ if (b->gbm)
++ gbm_device_destroy(b->gbm);
+ destroy_sprites(b);
+ err_udev_dev:
+ udev_device_unref(drm_device);
+@@ -3275,6 +3401,7 @@ backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
+ { WESTON_OPTION_INTEGER, "tty", 0, &param.tty },
+ { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
+ { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &param.use_pixman },
++ { WESTON_OPTION_BOOLEAN, "use-egldevice", 0, &param.use_egldevice },
+ };
+
+ param.seat_id = default_seat;
+diff --git a/src/main.c b/src/main.c
+index 1850fa633554..2494414138a8 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -266,6 +266,7 @@ usage(int error_code)
+ " --seat=SEAT\t\tThe seat that weston should run on\n"
+ " --tty=TTY\t\tThe tty to use\n"
+ " --use-pixman\t\tUse the pixman (CPU) renderer\n"
++ " --use-egldevice\tUse EGLDevice and EGLOutput with the GL renderer\n"
+ " --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
+ #endif
+
+--
+2.7.4
+
diff --git a/PKGBUILD b/PKGBUILD
index 4cb8d1c6c3e7..0f6494f9b58e 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,21 +1,49 @@
-# $Id: PKGBUILD 162349 2016-02-18 12:04:33Z seblu $
-# Maintainer: Sébastien Luttringer
+# Maintainer: Aaron Plattner <aplattner@nvidia.com>
+# Contributor: Sébastien Luttringer
# Contributor: Joel Teichroeb <joel@teichroeb.net>
-pkgname=weston
+pkgname=weston-eglstream
pkgver=1.10.0
pkgrel=1
-pkgdesc='Reference implementation of a Wayland compositor'
+pkgdesc='Reference implementation of a Wayland compositor with EGLStream support'
arch=('i686' 'x86_64')
url='http://wayland.freedesktop.org'
license=('MIT')
depends=('wayland' 'libxkbcommon' 'libinput' 'libunwind' 'poppler-glib' 'mtdev' 'libxcursor' 'glu' 'pango' 'colord')
makedepends=('wayland-protocols')
-source=("http://wayland.freedesktop.org/releases/$pkgname-$pkgver.tar.xz")
-sha1sums=('c9c2c8e2e798b25e7bf6b31bf0c4ef08724a7ebb')
+provides=('weston')
+conflicts=('weston')
+source=("http://wayland.freedesktop.org/releases/weston-$pkgver.tar.xz"
+ '0001-gl-renderer-Renaming-of-things-and-minor-improvement.patch'
+ '0002-gl-renderer-Refactor-gl_renderer_output_window_creat.patch'
+ '0003-gl-renderer-Implement-use-check_extension.patch'
+ '0004-gl-renderer-Add-support-for-EGLDevice-EGLOutput.patch'
+ '0005-compositor-drm-Gracefully-handle-vblank-and-flip-inv.patch'
+ '0006-compositor-drm-Renaming-of-gbm-fields.patch'
+ '0007-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch')
+sha1sums=('c9c2c8e2e798b25e7bf6b31bf0c4ef08724a7ebb'
+ 'c623cdf628a20a4bde5a98cc40867c32a8300e79'
+ '3441d0a7da0ae64835a5b29545caab4bc7977417'
+ 'f6742fadb973ec6c2b55e5500127309e70579312'
+ '31e3a447a1209712d604d739d0ac7e5b1925e940'
+ 'b483f21b3f880d3978cc678bf5f97802f7ddddaf'
+ '13d217d76a0811f5eb8d7180d31ec7a69fbbaabd'
+ '6bab10ac02a7e69b1bb1bf1982b5804e87870e0e')
+
+prepare() {
+ cd weston-$pkgver
+
+ patch -Np1 -i "${srcdir}/0001-gl-renderer-Renaming-of-things-and-minor-improvement.patch"
+ patch -Np1 -i "${srcdir}/0002-gl-renderer-Refactor-gl_renderer_output_window_creat.patch"
+ patch -Np1 -i "${srcdir}/0003-gl-renderer-Implement-use-check_extension.patch"
+ patch -Np1 -i "${srcdir}/0004-gl-renderer-Add-support-for-EGLDevice-EGLOutput.patch"
+ patch -Np1 -i "${srcdir}/0005-compositor-drm-Gracefully-handle-vblank-and-flip-inv.patch"
+ patch -Np1 -i "${srcdir}/0006-compositor-drm-Renaming-of-gbm-fields.patch"
+ patch -Np1 -i "${srcdir}/0007-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch"
+}
build() {
- cd $pkgname-$pkgver
+ cd weston-$pkgver
./configure \
--prefix=/usr \
--libexecdir=/usr/lib/weston \
@@ -25,7 +53,7 @@ build() {
}
package() {
- cd $pkgname-$pkgver
+ cd weston-$pkgver
make DESTDIR="$pkgdir" install
# license
install -Dm644 COPYING "$pkgdir/usr/share/licenses/$pkgname/COPYING"