# EGL ICD enumeration

EGL can't rely on asking an X server for a vendor name like GLX can, so
instead, it enumerates and loads every available vendor library. Loading every
vendor is also needed to support extensions such as
EGL\_EXT\_device\_enumeration.

In order to find the available vendor libraries, each vendor provides a JSON
file in a well-known directory, similar to how Vulkan ICDs are loaded.

## ICD discovery

* All environment variables mentioned here are ignored (treated as though
    they were unset) if the process is setuid.

* If the environment variable `__EGL_VENDOR_LIBRARY_FILENAMES` is set,
    it is a colon-separated list of JSON filenames. The ICDs described in
    those files are loaded, in the order given. No other ICDs are loaded.

* Otherwise, if the environment variable `__EGL_VENDOR_LIBRARY_DIRS`
    is set, it is a colon-separated list of directories. Each directory in
    turn is scanned for files named `*.json` and the ICDs that they describe
    are loaded. Files in the same directory are loaded in `strcmp()` order,
    so `40_myvendor.json` is considered to be higher-priority than
    `50_yourvendor.json`.

* If neither environment variable is set, GLVND behaves
    as though `__EGL_VENDOR_LIBRARY_DIRS` had been set to
    `${sysconfdir}/glvnd/egl_vendor.d:${datadir}/glvnd/egl_vendor.d`,
    replacing `${sysconfdir}` and `${datadir}` with the values that were
    set when GLVND was compiled.

* Each JSON file describing an ICD must have a JSON object at top level.
    * The key `file_format_version` must have a string value giving the
        file format `major.minor.micro` version number. This specification
        describes version `1.0.0`. Versions 1.0.x are required to be
        compatible with this specification, in the sense that an EGL loader
        that only implements file format version 1.0.0 will load all version
        1.0.x JSON files successfully. Different major and minor versions
        might require loader changes.
    * The key `ICD` must have an object value.
        * In the `ICD` object, the key `library_path` must have a string value.
            * If the library path is a bare filename with no directory
                separators, for example `libEGL_mesa.so.0`, or an absolute
                path, for example `/opt/myvendor/libEGL_myvendor.so`,
                then the loader is expected to pass it directly to `dlopen()`.
                See the documentation of `dlopen()` for full details of
                how it searches for a library.
            * If the library path is a relative path containing at least
                one directory separator, for example `./libEGL_myvendor.so`,
                then the loader is expected to treat it as being relative
                to the directory containing the JSON file.

## ICD installation

The JSON files describing ICDs can be installed into
`${datadir}/glvnd/egl_vendor.d` or `${sysconfdir}/glvnd/egl_vendor.d`,
where `${datadir}` and `${sysconfdir}` are the data and system
configuration directories with which which GLVND was configured,
normally `/usr/share` and `/etc` respectively. These paths can be
discovered by using pkg-config.

ICDs installed into the same directory hierarchy (prefix) as GLVND itself
should normally have their JSON files installed into the `${datadir}`.

If a vendor installs ICD libraries into one of the system's default
runtime library directories, they must install a JSON file referencing
the ICD library by either its absolute path or its bare filename.

If a vendor installs ICD libraries into a non-standard directory, they
must install a JSON file referencing the ICD library by its absolute path.

If a vendor installs matching ICD libraries for more than one ABI
(for example 32- and 64-bit versions), each library has the same name,
and each library is in a directory searched by default by the runtime
linker and referenced by its bare filename, then they may install a
single JSON file to describe all of those ICD libraries. For example,
Mesa on Debian installs `/usr/lib/x86_64-linux-gnu/libEGL_mesa.so.0` and
`/usr/lib/i386-linux-gnu/libEGL_mesa.so.0`, which can both be described
by a JSON file with `"library_path": "libEGL_mesa.so.0"`. Similarly, Mesa
on Arch Linux installs 64-bit `/usr/lib/libEGL_mesa.so.0` and 32-bit
`/usr/lib32/libEGL_mesa.so.0`, with a similar JSON file, while some
other distributions use `lib64` for 64-bit libraries.

## Examples

On systems with the Mesa EGL drivers, this file is typically installed at
`/usr/share/glvnd/egl_vendor.d/50_mesa.json`:

```
{
    "file_format_version" : "1.0.0",
    "ICD" : {
        "library_path" : "libEGL_mesa.so.0"
    }
}
```

A third-party ICD installed at `/opt/myvendor/lib64/libEGL_myvendor.so`
could install this file in `/etc/glvnd/egl_vendor.d/10_myvendor.x86_64.json`:

```
{
    "file_format_version" : "1.0.0",
    "ICD" : {
        "library_path" : "/opt/myvendor/lib64/libEGL_myvendor.so"
    }
}
```
