Which will be used in our next step, to make libEGL free waffle.
Paving the way of waffle to have little to-no dependencies.

Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com>
---
 src/waffle/egl/wegl_platform.c | 70 ++++++++++++++++++++++++++++++++++++++++--
 src/waffle/egl/wegl_platform.h | 36 ++++++++++++++++++++++
 2 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/src/waffle/egl/wegl_platform.c b/src/waffle/egl/wegl_platform.c
index b67e8d2..5766adb 100644
--- a/src/waffle/egl/wegl_platform.c
+++ b/src/waffle/egl/wegl_platform.c
@@ -23,14 +23,32 @@
 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#include <dlfcn.h>
+
+#include "wcore_error.h"
 #include "wegl_platform.h"
 
+// XXX: Use the actual SONAME for linux ?
+// Should we treat Android the same way as linux ?
+static const char *libEGL_filename = "libEGL.so";
+
 bool
 wegl_platform_teardown(struct wegl_platform *self)
 {
-    bool ok;
+    bool ok = true;
+    int error = 0;
 
-    ok = wcore_platform_teardown(&self->wcore);
+    if (self->eglHandle) {
+        error = dlclose(self->eglHandle);
+        if (error) {
+            ok = false;
+            wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+                         "dlclose(\"%s\") failed: %s",
+                         libEGL_filename, dlerror());
+        }
+    }
+
+    ok &= wcore_platform_teardown(&self->wcore);
     return ok;
 }
 bool
@@ -39,6 +57,54 @@ wegl_platform_init(struct wegl_platform *self)
     bool ok;
 
     ok = wcore_platform_init(&self->wcore);
+    if (!ok)
+        goto error;
+
+    self->eglHandle = dlopen(libEGL_filename, RTLD_LAZY | RTLD_LOCAL);
+    if (!self->eglHandle) {
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
+                     "dlopen(\"%s\") failed: %s",
+                     libEGL_filename, dlerror());
+        goto error;
+    }
+
+#define RETREIVE_EGL_SYMBOL(function)                                  \
+    self->function = dlsym(self->eglHandle, #function);                \
+    if (!self->function) {                                             \
+        wcore_errorf(WAFFLE_ERROR_UNKNOWN,                             \
+                     "dlsym(\"%s\", \"" #function "\") failed: %s",    \
+                     libEGL_filename, dlerror());                      \
+        goto error;                                                    \
+    }
+
+    RETREIVE_EGL_SYMBOL(eglMakeCurrent);
+    RETREIVE_EGL_SYMBOL(eglGetProcAddress);
+
+    // display
+    RETREIVE_EGL_SYMBOL(eglGetDisplay);
+    RETREIVE_EGL_SYMBOL(eglInitialize);
+    RETREIVE_EGL_SYMBOL(eglQueryString);
+    RETREIVE_EGL_SYMBOL(eglGetError);
+    RETREIVE_EGL_SYMBOL(eglTerminate);
+
+    // config
+    RETREIVE_EGL_SYMBOL(eglChooseConfig);
+
+    // context
+    RETREIVE_EGL_SYMBOL(eglBindAPI);
+    RETREIVE_EGL_SYMBOL(eglCreateContext);
+    RETREIVE_EGL_SYMBOL(eglDestroyContext);
+
+    // window
+    RETREIVE_EGL_SYMBOL(eglGetConfigAttrib);
+    RETREIVE_EGL_SYMBOL(eglCreateWindowSurface);
+    RETREIVE_EGL_SYMBOL(eglDestroySurface);
+    RETREIVE_EGL_SYMBOL(eglSwapBuffers);
+
+#undef RETREIVE_EGL_SYMBOL
 
+error:
+    // On failure the caller of wegl_platform_init will trigger it's own
+    // destruction which will execute wegl_platform_teardown.
     return ok;
 }
diff --git a/src/waffle/egl/wegl_platform.h b/src/waffle/egl/wegl_platform.h
index 43108dc..645c3f8 100644
--- a/src/waffle/egl/wegl_platform.h
+++ b/src/waffle/egl/wegl_platform.h
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include <EGL/egl.h>
+
 #include "wcore_platform.h"
 #include "wcore_util.h"
 
@@ -32,6 +34,40 @@ struct wegl_platform {
     struct wcore_platform wcore;
 
     // EGL function pointers
+    void *eglHandle;
+
+    EGLBoolean (*eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw,
+                                 EGLSurface read, EGLContext ctx);
+    __eglMustCastToProperFunctionPointerType
+       (*eglGetProcAddress)(const char *procname);
+
+    // display
+    EGLDisplay (*eglGetDisplay)(EGLNativeDisplayType display_id);
+    EGLBoolean (*eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+    const char * (*eglQueryString)(EGLDisplay dpy, EGLint name);
+    EGLint (*eglGetError)(void);
+    EGLBoolean (*eglTerminate)(EGLDisplay dpy);
+
+    // config
+    EGLBoolean (*eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list,
+                                  EGLConfig *configs, EGLint config_size,
+                                  EGLint *num_config);
+
+    // context
+    EGLBoolean (*eglBindAPI)(EGLenum api);
+    EGLContext (*eglCreateContext)(EGLDisplay dpy, EGLConfig config,
+                                   EGLContext share_context,
+                                   const EGLint *attrib_list);
+    EGLBoolean (*eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
+
+    // window
+    EGLBoolean (*eglGetConfigAttrib)(EGLDisplay dpy, EGLConfig config,
+                                     EGLint attribute, EGLint *value);
+    EGLSurface (*eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config,
+                                         EGLNativeWindowType win,
+                                         const EGLint *attrib_list);
+    EGLBoolean (*eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+    EGLBoolean (*eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
 };
 
 DEFINE_CONTAINER_CAST_FUNC(wegl_platform,
-- 
2.0.2

_______________________________________________
waffle mailing list
waffle@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/waffle

Reply via email to