summarylogtreecommitdiffstats
path: root/0009-gl-renderer-Add-EGL-client-support-for-EGLStream-fra.patch
diff options
context:
space:
mode:
Diffstat (limited to '0009-gl-renderer-Add-EGL-client-support-for-EGLStream-fra.patch')
-rw-r--r--0009-gl-renderer-Add-EGL-client-support-for-EGLStream-fra.patch224
1 files changed, 122 insertions, 102 deletions
diff --git a/0009-gl-renderer-Add-EGL-client-support-for-EGLStream-fra.patch b/0009-gl-renderer-Add-EGL-client-support-for-EGLStream-fra.patch
index c802e157a4d4..c8700ce21a1d 100644
--- a/0009-gl-renderer-Add-EGL-client-support-for-EGLStream-fra.patch
+++ b/0009-gl-renderer-Add-EGL-client-support-for-EGLStream-fra.patch
@@ -1,7 +1,7 @@
-From c3a7bff36253229bfbfed8c72a82f334819ba3e5 Mon Sep 17 00:00:00 2001
+From decfa267d12c6b48720e5263c71011b64638bbda Mon Sep 17 00:00:00 2001
From: "Miguel A. Vico" <mvicomoya@nvidia.com>
Date: Mon, 2 May 2016 18:22:47 +0200
-Subject: [PATCH 09/11] gl-renderer: Add EGL client support for EGLStream frame
+Subject: [PATCH 09/12] gl-renderer: Add EGL client support for EGLStream frame
presentation
X-NVConfidentiality: public
@@ -17,31 +17,22 @@ 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_WL_wayland_eglstream:
+ https://github.com/aritger/eglstreams-kms-example/blob/master/proposed-extensions/EGL_WL_wayland_eglstream.txt
Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
Reviewed-by: Adam Cheney <acheney@nvidia.com>
Reviewed-by: James Jones <jajones@nvidia.com>
-
-[aplattner@nvidia.com: rebased on top of Weston 1.12.0]
---
- libweston/gl-renderer.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 174 insertions(+), 1 deletion(-)
+ libweston/gl-renderer.c | 183 ++++++++++++++++++++++++++++++++++++++++++++-
+ libweston/weston-egl-ext.h | 5 ++
+ 2 files changed, 187 insertions(+), 1 deletion(-)
diff --git a/libweston/gl-renderer.c b/libweston/gl-renderer.c
-index 01c5933966ca..be0c5e9b4745 100644
+index a0efea2ed648..a3440fc7162c 100644
--- a/libweston/gl-renderer.c
+++ b/libweston/gl-renderer.c
-@@ -30,6 +30,7 @@
- #include <GLES2/gl2.h>
- #include <GLES2/gl2ext.h>
-
-+#include <unistd.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <stdlib.h>
-@@ -163,6 +164,9 @@ struct gl_surface_state {
+@@ -163,6 +163,9 @@ struct gl_surface_state {
int height; /* in pixels */
int y_inverted;
@@ -51,7 +42,7 @@ index 01c5933966ca..be0c5e9b4745 100644
struct weston_surface *surface;
struct wl_listener surface_destroy_listener;
-@@ -214,6 +218,7 @@ struct gl_renderer {
+@@ -214,6 +217,7 @@ struct gl_renderer {
PFNEGLCREATESTREAMKHRPROC create_stream;
PFNEGLDESTROYSTREAMKHRPROC destroy_stream;
@@ -59,21 +50,24 @@ index 01c5933966ca..be0c5e9b4745 100644
int has_egl_stream;
PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC create_stream_producer_surface;
-@@ -227,6 +232,13 @@ struct gl_renderer {
+@@ -223,11 +227,16 @@ struct gl_renderer {
+ int has_egl_stream_consumer_egloutput;
+
+ #ifdef EGL_NV_stream_attrib
++ PFNEGLCREATESTREAMATTRIBNVPROC create_stream_attrib;
+ PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC stream_consumer_acquire_attrib;
#endif
+ int has_egl_stream_attrib;
int has_egl_stream_acquire_mode;
-+ PFNEGLSTREAMCONSUMERACQUIREKHRPROC stream_consumer_acquire;
+ PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC stream_consumer_gltexture;
+ int has_egl_stream_consumer_gltexture;
-+
-+ PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC create_stream_from_fd;
-+ int has_egl_stream_cross_process_fd;
++ int has_egl_wayland_eglstream;
+
int has_dmabuf_import;
struct wl_list dmabuf_images;
-@@ -1934,6 +1946,132 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
+@@ -1936,6 +1945,145 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
gs->y_inverted = buffer->y_inverted;
}
@@ -88,64 +82,73 @@ index 01c5933966ca..be0c5e9b4745 100644
+ */
+static bool
+gl_renderer_attach_stream_texture(struct weston_surface *es,
-+ struct weston_buffer *buffer)
++ struct weston_buffer *buffer)
+{
++#ifdef EGL_NV_stream_attrib
+ struct weston_compositor *ec = es->compositor;
+ struct gl_renderer *gr = get_renderer(ec);
+ struct gl_surface_state *gs = get_surface_state(es);
-+ EGLNativeFileDescriptorKHR fd = EGL_NO_FILE_DESCRIPTOR_KHR;
++ EGLStreamKHR stream = EGL_NO_STREAM_KHR;
++ EGLAttrib stream_attribs[] = {
++#ifdef EGL_WL_wayland_eglstream
++ EGL_WAYLAND_EGLSTREAM_WL, (EGLAttrib)buffer->resource,
++#endif
++ EGL_NONE
++ };
+ EGLint stream_state = EGL_STREAM_STATE_EMPTY_KHR;
+
-+ /* Check for required extensions. If they arent supported, there's no way
-+ * the given buffer corresponds to an EGLStream */
-+ if (!gr->has_egl_stream_consumer_gltexture ||
-+ !gr->has_egl_stream_cross_process_fd)
++ /* Check for required extensions. If they arent supported, there's no
++ * way the given buffer corresponds to an EGLStream */
++ if (!gr->has_egl_stream_attrib ||
++ !gr->has_egl_stream_consumer_gltexture ||
++ !gr->has_egl_wayland_eglstream)
+ return false;
+
-+ /* Try to get the stream file descriptor. If the query fails, the given
-+ * buffer does not corresponds to an EGLStream
-+ *
-+ * FIXME: Use EGL_WL_wayland_eglstream instead */
-+ if (!gr->query_buffer(gr->egl_display, buffer->resource,
-+ EGL_WAYLAND_BUFFER_WL, &fd))
-+ return false;
++ stream = gr->create_stream_attrib(gr->egl_display, stream_attribs);
++ if (stream == EGL_NO_STREAM_KHR) {
++ EGLint err = eglGetError();
+
-+ /* If invalid file descriptor returned, buffer->resource corresponds to a
-+ * previously created stream so we must have a valid stream handle already
-+ * we can use to acquire next frame; otherwise, try to create the stream */
-+ if (fd != EGL_NO_FILE_DESCRIPTOR_KHR) {
-+ EGLStreamKHR stream = EGL_NO_STREAM_KHR;
++ switch (err) {
++ case EGL_BAD_ACCESS:
++ /* EGL_BAD_ACCESS is generated whenever buffer->resource
++ * does not corresponds to a stream */
++ return false;
+
-+ stream = gr->create_stream_from_fd(gr->egl_display, fd);
-+ close(fd);
++ case EGL_BAD_STREAM_KHR:
++ /* EGL_BAD_STREAM_KHR is generated whenever
++ * buffer->resource corresponds to a previously created
++ * stream so we must have a valid stream handle already
++ * we can use to acquire next frame */
++ break;
+
-+ if (stream == EGL_NO_STREAM_KHR) {
-+ gl_renderer_print_egl_error_state();
-+ return true; /* buffer->resource is EGLStream */
-+ } else {
-+ /* Clean up current stream resources if needed */
-+ if (gs->egl_stream != EGL_NO_STREAM_KHR)
-+ gr->destroy_stream(gr->egl_display, gs->egl_stream);
++ default:
++ /* An unknown error was generated */
++ assert(0);
++ return false;
++ }
++ } else {
++ /* 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 = stream;
-+ gs->shader = &gr->texture_shader_egl_external;
-+ gs->target = GL_TEXTURE_EXTERNAL_OES;
++ gs->egl_stream = stream;
++ gs->shader = &gr->texture_shader_egl_external;
++ gs->target = GL_TEXTURE_EXTERNAL_OES;
+
-+ glActiveTexture(GL_TEXTURE0);
-+ ensure_textures(gs, 2);
-+ glBindTexture(gs->target, gs->textures[1]);
++ glActiveTexture(GL_TEXTURE0);
++ ensure_textures(gs, 2);
++ glBindTexture(gs->target, gs->textures[1]);
+
-+ gs->new_stream = (EGL_TRUE == gr->stream_consumer_gltexture(
-+ gr->egl_display,
-+ gs->egl_stream));
++ gs->new_stream = (gr->stream_consumer_gltexture(
++ gr->egl_display,
++ gs->egl_stream) == EGL_TRUE);
+
-+ if (!gs->new_stream) {
-+ weston_log("failed to set stream consumer\n");
-+ gl_renderer_print_egl_error_state();
-+ gr->destroy_stream(gr->egl_display, gs->egl_stream);
-+ gs->egl_stream = EGL_NO_STREAM_KHR;
-+ return true; /* buffer->resource is EGLStream */
-+ }
++ if (!gs->new_stream) {
++ weston_log("failed to set stream consumer\n");
++ gl_renderer_print_egl_error_state();
++ gr->destroy_stream(gr->egl_display, gs->egl_stream);
++ gs->egl_stream = EGL_NO_STREAM_KHR;
++ return true; /* buffer->resource is EGLStream */
+ }
+ }
+
@@ -154,9 +157,9 @@ index 01c5933966ca..be0c5e9b4745 100644
+
+ /* Check whether there are new frames available */
+ if (gr->query_stream(gr->egl_display,
-+ gs->egl_stream,
-+ EGL_STREAM_STATE_KHR,
-+ &stream_state) != EGL_TRUE) {
++ gs->egl_stream,
++ EGL_STREAM_STATE_KHR,
++ &stream_state) != EGL_TRUE) {
+ weston_log("failed to query stream state\n");
+ gl_renderer_print_egl_error_state();
+ return true; /* buffer->resource is EGLStream */
@@ -170,8 +173,9 @@ index 01c5933966ca..be0c5e9b4745 100644
+ return true; /* buffer->resource is EGLStream */
+ }
+
-+ if (gr->stream_consumer_acquire(gr->egl_display,
-+ gs->egl_stream) != EGL_TRUE) {
++ if (gr->stream_consumer_acquire_attrib(gr->egl_display,
++ gs->egl_stream,
++ NULL) != EGL_TRUE) {
+ weston_log("failed to acquire buffer\n");
+ gl_renderer_print_egl_error_state();
+ return true; /* buffer->resource is EGLStream */
@@ -189,11 +193,11 @@ index 01c5933966ca..be0c5e9b4745 100644
+ /* Update buffer and surface data */
+ buffer->legacy_buffer = (void *)buffer->resource;
+ gr->query_buffer(gr->egl_display, buffer->legacy_buffer,
-+ EGL_WIDTH, &buffer->width);
++ EGL_WIDTH, &buffer->width);
+ gr->query_buffer(gr->egl_display, buffer->legacy_buffer,
-+ EGL_HEIGHT, &buffer->height);
++ EGL_HEIGHT, &buffer->height);
+ gr->query_buffer(gr->egl_display, buffer->legacy_buffer,
-+ EGL_WAYLAND_Y_INVERTED_WL, &buffer->y_inverted);
++ EGL_WAYLAND_Y_INVERTED_WL, &buffer->y_inverted);
+
+ gs->pitch = buffer->width;
+ gs->height = buffer->height;
@@ -201,12 +205,15 @@ index 01c5933966ca..be0c5e9b4745 100644
+ gs->y_inverted = buffer->y_inverted;
+
+ return true; /* buffer->resource is EGLStream */
++#else
++ return false;
++#endif
+}
+
static void
gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
{
-@@ -1957,6 +2095,12 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
+@@ -1959,6 +2107,12 @@ 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;
@@ -219,7 +226,7 @@ index 01c5933966ca..be0c5e9b4745 100644
return;
}
-@@ -1969,7 +2113,7 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
+@@ -1971,7 +2125,7 @@ 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);
@@ -228,7 +235,7 @@ index 01c5933966ca..be0c5e9b4745 100644
weston_log("unhandled buffer type!\n");
weston_buffer_reference(&gs->buffer_ref, NULL);
gs->buffer_type = BUFFER_TYPE_NULL;
-@@ -2157,6 +2301,10 @@ surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
+@@ -2159,6 +2313,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);
@@ -239,7 +246,7 @@ index 01c5933966ca..be0c5e9b4745 100644
free(gs);
}
-@@ -2207,6 +2355,8 @@ gl_renderer_create_surface(struct weston_surface *surface)
+@@ -2209,6 +2367,8 @@ gl_renderer_create_surface(struct weston_surface *surface)
gs->surface = surface;
@@ -248,7 +255,7 @@ index 01c5933966ca..be0c5e9b4745 100644
pixman_region32_init(&gs->texture_damage);
surface->renderer_state = gs;
-@@ -2902,6 +3052,7 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+@@ -2905,14 +3065,19 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
(void *) eglGetProcAddress("eglQueryOutputLayerAttribEXT");
gr->create_stream = (void *) eglGetProcAddress("eglCreateStreamKHR");
gr->destroy_stream = (void *) eglGetProcAddress("eglDestroyStreamKHR");
@@ -256,49 +263,62 @@ index 01c5933966ca..be0c5e9b4745 100644
gr->create_stream_producer_surface =
(void *) eglGetProcAddress("eglCreateStreamProducerSurfaceKHR");
gr->stream_consumer_output =
-@@ -2910,6 +3061,12 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+ (void *) eglGetProcAddress("eglStreamConsumerOutputEXT");
+ #ifdef EGL_NV_stream_attrib
++ gr->create_stream_attrib =
++ (void *) eglGetProcAddress("eglCreateStreamAttribNV");
gr->stream_consumer_acquire_attrib =
- (void *) eglGetProcAddress("eglStreamConsumerAcquireAttribEXT");
+ (void *) eglGetProcAddress("eglStreamConsumerAcquireAttribNV");
#endif
-+ gr->stream_consumer_acquire =
-+ (void *) eglGetProcAddress("eglStreamConsumerAcquireKHR");
+ gr->stream_consumer_gltexture =
+ (void *) eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR");
-+ gr->create_stream_from_fd =
-+ (void *) eglGetProcAddress("eglCreateStreamFromFileDescriptorKHR");
extensions =
(const char *) eglQueryString(gr->egl_display, EGL_EXTENSIONS);
-@@ -2969,6 +3126,12 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
+@@ -2975,6 +3140,12 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
if (weston_check_egl_extension(extensions, "EGL_EXT_stream_acquire_mode"))
gr->has_egl_stream_acquire_mode = 1;
+ if (weston_check_egl_extension(extensions, "EGL_KHR_stream_consumer_gltexture"))
+ gr->has_egl_stream_consumer_gltexture = 1;
+
-+ if (weston_check_egl_extension(extensions, "EGL_KHR_stream_cross_process_fd"))
-+ gr->has_egl_stream_cross_process_fd = 1;
++ if (weston_check_egl_extension(extensions, "EGL_WL_wayland_eglstream"))
++ gr->has_egl_wayland_eglstream = 1;
+
renderer_setup_egl_client_extensions(gr);
return 0;
-@@ -3236,6 +3399,16 @@ gl_renderer_display_create(struct weston_compositor *ec, EGLenum platform,
+@@ -3247,6 +3418,16 @@ gl_renderer_display_create(struct weston_compositor *ec, EGLenum platform,
goto fail_terminate;
}
+ if (!gr->has_egl_stream_consumer_gltexture ||
-+ !gr->has_egl_stream_cross_process_fd)
-+ weston_log("warning: following required extensions for EGL client "
-+ "frame presentation through EGLDevice not supported:\n"
-+ "%s%s",
-+ (gr->has_egl_stream_consumer_gltexture ?
-+ " EGL_KHR_stream_consumer_gltexture\n" : ""),
-+ (gr->has_egl_stream_cross_process_fd ?
-+ " EGL_KHR_stream_cross_process_fd\n" : ""));
++ !gr->has_egl_wayland_eglstream)
++ weston_log("warning: following required extensions for "
++ "EGL client frame presentation through "
++ "EGLDevice not supported:\n%s%s",
++ (gr->has_egl_stream_consumer_gltexture ? "" :
++ " EGL_KHR_stream_consumer_gltexture\n"),
++ (gr->has_egl_wayland_eglstream ? "" :
++ " EGL_WL_wayland_eglstream\n"));
+
if (!gr->has_egl_output_drm_flip_event)
- weston_log("warning: EGL page flip event notification not"
- " supported\n");
+ weston_log("warning: EGL page flip event notification "
+ "not supported\n");
+diff --git a/libweston/weston-egl-ext.h b/libweston/weston-egl-ext.h
+index 709c80959b66..f5ae44848fee 100644
+--- a/libweston/weston-egl-ext.h
++++ b/libweston/weston-egl-ext.h
+@@ -191,4 +191,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribEXT (EGLDisplay dpy,
+ #define EGL_DRM_FLIP_EVENT_DATA_NV 0x333E
+ #endif /* EGL_NV_output_drm_flip_event */
+
++#ifndef EGL_WL_wayland_eglstream
++#define EGL_WL_wayland_eglstream 1
++#define EGL_WAYLAND_EGLSTREAM_WL 0x334B
++#endif /* EGL_WL_wayland_eglstream */
++
+ #endif
--
-2.10.0
+2.10.2