pmaports/hybris/libhybris/0005-eglplatform_wayland-link-libEGL-at-runtime.patch

91 lines
3.7 KiB
Diff
Raw Normal View History

From 1f4d73a7c3ebfbbeaa91de51ef50c69676da730d Mon Sep 17 00:00:00 2001
From: Alexey Min <alexey.min@gmail.com>
Date: Sat, 31 Aug 2019 01:51:55 +0300
Subject: [PATCH] eglplatform_wayland: link libEGL at runtime
hybris_egl_display_get_mapping() function is implemented
in libhybris's libEGL.so. However, eglplatform_wayland.so
is not linked to libEGL directly, causing undefined symbol
errors during loading, if libEGL was not already loaded by
some other dependencies. Therefore, we should load libEGL
at runtime here and resolve this function dynamically.
---
.../platforms/wayland/eglplatform_wayland.cpp | 40 ++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/hybris/egl/platforms/wayland/eglplatform_wayland.cpp b/hybris/egl/platforms/wayland/eglplatform_wayland.cpp
index 191ae76..7668c32 100644
--- a/hybris/egl/platforms/wayland/eglplatform_wayland.cpp
+++ b/hybris/egl/platforms/wayland/eglplatform_wayland.cpp
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
+#include <dlfcn.h>
extern "C" {
#include <eglplatformcommon.h>
};
@@ -61,6 +62,13 @@ static EGLSyncKHR (*_eglCreateSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLin
static EGLBoolean (*_eglDestroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync) = NULL;
static EGLint (*_eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) = NULL;
+/* The following function is implemented in libhybris's libEGL.so.
+ * However, eglplatform_wayland.so is not linking to libEGL directly,
+ * causing undefined symbol errors during loading, if libEGL was not
+ * already loaded by some other dependencies. Therefore, we should try
+ * to load libEGL at runtime here and resolve this function dynamically */
+typedef struct _EGLDisplay *(*PFNHYBRISEGLDISPLAYGETMAPPINGPROC)(EGLDisplay dpy);
+
struct WaylandDisplay {
_EGLDisplay base;
@@ -202,6 +210,36 @@ extern "C" int waylandws_post(EGLNativeWindowType win, void *buffer)
return ((WaylandNativeWindow *) eglwin->nativewindow)->postBuffer((ANativeWindowBuffer *) buffer);
}
+/**
+ * Loads libhybris's libEGL at runtime to call hybris_egl_display_get_mapping()
+ */
+static struct _EGLDisplay *_hybris_egl_display_get_mapping(EGLDisplay dpy)
+{
+ static void *libEGL_handle = NULL;
+ static PFNHYBRISEGLDISPLAYGETMAPPINGPROC hybris_egl_display_get_mapping_fn = NULL;
+
+ if (!libEGL_handle) {
+ dlerror(); // cleanup error buffer
+ libEGL_handle = dlopen("libEGL.so.1", RTLD_NOW | RTLD_GLOBAL);
+ if (!libEGL_handle) {
+ HYBRIS_ERROR("ERROR: Failed to dlopen libEGL! %s", dlerror());
+ abort();
+ }
+ }
+
+ if (!hybris_egl_display_get_mapping_fn) {
+ dlerror(); // cleanup error buffer
+ hybris_egl_display_get_mapping_fn = (PFNHYBRISEGLDISPLAYGETMAPPINGPROC)dlsym(
+ libEGL_handle, "hybris_egl_display_get_mapping");
+ if (!hybris_egl_display_get_mapping_fn) {
+ HYBRIS_ERROR("ERROR: Cannot resolve 'hybris_egl_display_get_mapping' in libEGL! %s", dlerror());
+ abort();
+ }
+ }
+
+ return hybris_egl_display_get_mapping_fn(dpy);
+}
+
extern "C" wl_buffer *waylandws_createWlBuffer(EGLDisplay dpy, EGLImageKHR image)
{
egl_image *img = reinterpret_cast<egl_image *>(image);
@@ -211,7 +249,7 @@ extern "C" wl_buffer *waylandws_createWlBuffer(EGLDisplay dpy, EGLImageKHR image
return NULL;
}
if (img->target == EGL_WAYLAND_BUFFER_WL) {
- WaylandDisplay *wdpy = (WaylandDisplay *)hybris_egl_display_get_mapping(dpy);
+ WaylandDisplay *wdpy = (WaylandDisplay *)_hybris_egl_display_get_mapping(dpy);
server_wlegl_buffer *buf = server_wlegl_buffer_from((wl_resource *)img->egl_buffer);
WaylandNativeWindowBuffer wnb(buf->buf);
// The buffer will be managed by the app, so pass NULL as the queue so that
--
2.21.0