Unable to load my own EGL external library.

Hi,

I’m working on my own display server and trying to link it with DRM/KMS using EGL stream. I’m testing this on GTX750 with the latest x86 NVIDIA driver(384.90) on 32bit Ubuntu 16.10, kernel 4.8.0.34-generic.

I have some trouble with loading my own version of ‘EGL external platform library’ and I’ve searched for many online samples and mailing lists but I couldn’t get any solution.

NVIDIA driver calls the function loadEGLExternalPlatform(), queries function pointers for every EGL API through getHookAddress(). So far, everything is good. But then, driver unloads my library and loads tries to get another external libraries like libnvidia-egl-wayland.so.1.

I need to find out the reason why my shared object is unloaded. Under which condition the driver unloads the library and finds another library to load?

Regards,
Jiman Jeong

I’ve found a solution for this problem.

EGL driver needs some nessesary hook functions that must be given through getHookAddress() for working with external platform library. The hooks are listed below.

  • eglCreatePbufferSurface
  • eglCreatePlatformPixmapSurface
  • eglCreatePlatformWindowSurface

I don’t know why these have to be given, but the external platform library including these is loaded well without any other hook for EGL API.

This code describes how EGL platform gives hooks through getHookAddress() with 4 EGL entrypoints including eglSwapBuffers.
https://github.com/NVIDIA/eglexternalplatform/blob/master/samples/libsample-egl-platform.c

According to the comment of this repo, pixmap and pbuffer are not nessesary, but the code includes every hook function for them. I have checked this before but it was quite hard to find out these are necessary. It would be nice if there were some notes or details about this.

Hi,

To keep things simple with the design of the EGL external platforms interface, external platforms are required to back EGLDisplay and EGLSurface objects (i.e. implement all EGLSurface creation functions, even if they just return error or pass the call through to the driver).

To make the execution flow be deterministic, any EGL calls made using an external EGLDisplay will be forwarded to the corresponding external platform if the hook exists.

Whenever the hook doesn’t exist, the entrypoint layer will translate the given external handles to internal ones and directly call into the driver.

However, when we are dealing with EGL objects that may be backed by the external platform, we want an all or none behavior: either all objects of a type are backed by the external platform, or none. Otherwise, it’d be hard to handle calls where a mix of internal and external handles of a type are given (e.g. eglMakeCurrent()). We’d have to deal with a ton of corner cases.

Thus, the entrypoint layer will always treat EGLSurface objects created from an external EGLDisplay as external, and rely on the platform to keep track of them and translating them to internal handles when asked for it.

The following lines from https://github.com/NVIDIA/eglexternalplatform#interactions-with-the-egl-driver were intended to note the above, but I understand they fail to do so:

I’ll try to improve that part of the README file.

Hi, I have a similar problem with loading egl platform. As you said, one need to call the loadEGLExternalPlatform. But the function requires the EGLExtDriver which I don’t know how to set it up. Do I call eglGetProcAdress to setup the EGLExtDriver struct or I need to do something else?

Thank your every much

The driver will call into ‘loadEGLExternalPlatform’. It is the driver’s responsibility to fill the EGLExtDriver structure with pointers to the driver’s implementation of the corresponding interfaces:

PEGLEXTFNGETPROCADDRESS     getProcAddress
PEGLEXTFNSETERROR           setError
PEGLEXTFNDEBUGMESSAGE       debugMessage
PEGLEXTFNSTREAMSWAPINTERVAL streamSwapInterval

These interfaces are described in https://github.com/NVIDIA/eglexternalplatform/blob/master/interface/eglexternalplatform.h

The “Interface walk-through” section of the README file may also be useful to answer some of the questions about these interfaces: https://github.com/NVIDIA/eglexternalplatform#interface-walk-through

Please, let me know if something is unclear or out of date and I’ll make the appropriate corrections.

Hi, I just checked these replies.

@mvicomoya, I’ve understood why the driver works that way. thanks!

@tac0r
As mvicomoya said, and also I said, ‘loadEGLExternalPlatform’ is called by driver. When an application linked with EGL is run, the driver enumerates .json formatted manifests in your system and opens your own EGL external library, then calls the function with filled EGLExtDriver structure.

By default, the driver will search manifests in ‘/usr/share/egl/egl_external_platform.d/’ if you didn’t give an option that changes the path when install the driver. You can make your own manifest by referring to ‘10_nvidia_wayland.json’, already installed.

Hi,

thanks both @sixzone11 and @mivicomoya. I was able to create EGLDisplay with the instruction provided. But the egl_external_platform doesn’t work with weston, which I was using. So I guess I couldn’t use this egl-implementation actually.

XZ

@tac0r Please see https://aur.archlinux.org/packages/weston-eglstream

@tac0r,
If you just want to use a EGL on wayland, I think you should stop the progress because it is not very productive thing that make your own platform. Already the EGL external platform library for wayland is provided when the driver is installed. But if you may make your own platform or display server, not wayland, your EGL external platform works with your private platform.

See https://github.com/NVIDIA/egl-wayland, wayland version of external platform library and @blablo mentioned, for server-side.

@blablo, @sixzone11 it is not really the problem of the weston-eglstream, I can successfully create a EGLDisplay and context with it, but just when it comes to binding EGLSurface with a wl_surface. I cannot profit from the nvidia’s implementation anymore, since libweston doens’t support eglstream, every time when the egl swap buffer the problem occurs. The EGL-stream-buffer is not supported and and I experience segmentation fault.

I heard nvidia had a patch to weston to make it work with EGLstream but I happened to have another graphics card and using mesa is way easier.

If you’re using a Pacman-based distribution, you can just install https://aur.archlinux.org/packages/weston-eglstream. Otherwise, it’s fairly easy to build weston yourself from https://cgit.freedesktop.org/~jjones/weston (choose latest branch).

When running weston from above, you can toggle the eglstreams backend with the ‘–use-egldevice’ option.