Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 1 | EGL |
| 2 | === |
| 3 | |
| 4 | The current version of EGL in Mesa implements EGL 1.4. More information |
| 5 | about EGL can be found at https://www.khronos.org/egl/. |
| 6 | |
| 7 | The Mesa's implementation of EGL uses a driver architecture. The main |
| 8 | library (``libEGL``) is window system neutral. It provides the EGL API |
| 9 | entry points and helper functions for use by the drivers. Drivers are |
| 10 | dynamically loaded by the main library and most of the EGL API calls are |
| 11 | directly dispatched to the drivers. |
| 12 | |
| 13 | The driver in use decides the window system to support. |
| 14 | |
| 15 | Build EGL |
| 16 | --------- |
| 17 | |
| 18 | #. Configure your build with the desired client APIs and enable the |
| 19 | driver for your hardware. For example: |
| 20 | |
Erik Faye-Lund | d6be994 | 2019-06-04 14:14:13 +0200 | [diff] [blame] | 21 | .. code-block:: console |
Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 22 | |
| 23 | $ meson configure \ |
| 24 | -D egl=true \ |
| 25 | -D gles1=true \ |
| 26 | -D gles2=true \ |
| 27 | -D dri-drivers=... \ |
| 28 | -D gallium-drivers=... |
| 29 | |
| 30 | The main library and OpenGL is enabled by default. The first two |
Erik Faye-Lund | 9be0e2d | 2020-06-15 12:31:36 +0200 | [diff] [blame] | 31 | options above enables :doc:`OpenGL ES 1.x and 2.x <opengles>`. The |
Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 32 | last two options enables the listed classic and Gallium drivers |
| 33 | respectively. |
| 34 | |
| 35 | #. Build and install Mesa as usual. |
| 36 | |
| 37 | In the given example, it will build and install ``libEGL``, ``libGL``, |
| 38 | ``libGLESv1_CM``, ``libGLESv2``, and one or more EGL drivers. |
| 39 | |
| 40 | Configure Options |
| 41 | ~~~~~~~~~~~~~~~~~ |
| 42 | |
| 43 | There are several options that control the build of EGL at configuration |
| 44 | time |
| 45 | |
| 46 | ``-D egl=true`` |
| 47 | By default, EGL is enabled. When disabled, the main library and the |
| 48 | drivers will not be built. |
| 49 | |
| 50 | ``-D platforms=...`` |
| 51 | List the platforms (window systems) to support. Its argument is a |
Eric Engestrom | e00adef | 2019-06-25 15:44:16 +0100 | [diff] [blame] | 52 | comma separated string such as ``-D platforms=x11,wayland``. It decides |
Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 53 | the platforms a driver may support. The first listed platform is also |
| 54 | used by the main library to decide the native platform. |
| 55 | |
Eric Engestrom | e00adef | 2019-06-25 15:44:16 +0100 | [diff] [blame] | 56 | The available platforms are ``x11``, ``wayland``, |
Eric Engestrom | a38e21d | 2019-06-25 13:47:04 +0100 | [diff] [blame] | 57 | ``android``, and ``haiku``. The ``android`` platform |
Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 58 | can either be built as a system component, part of AOSP, using |
| 59 | ``Android.mk`` files, or cross-compiled using appropriate options. |
| 60 | Unless for special needs, the build system should select the right |
| 61 | platforms automatically. |
| 62 | |
| 63 | ``-D gles1=true`` and ``-D gles2=true`` |
| 64 | These options enable OpenGL ES support in OpenGL. The result is one |
| 65 | big internal library that supports multiple APIs. |
| 66 | |
| 67 | ``-D shared-glapi=true`` |
| 68 | By default, ``libGL`` has its own copy of ``libglapi``. This options |
| 69 | makes ``libGL`` use the shared ``libglapi``. This is required if |
| 70 | applications mix OpenGL and OpenGL ES. |
| 71 | |
| 72 | Use EGL |
| 73 | ------- |
| 74 | |
| 75 | Demos |
| 76 | ~~~~~ |
| 77 | |
| 78 | There are demos for the client APIs supported by EGL. They can be found |
| 79 | in mesa/demos repository. |
| 80 | |
| 81 | Environment Variables |
| 82 | ~~~~~~~~~~~~~~~~~~~~~ |
| 83 | |
| 84 | There are several environment variables that control the behavior of EGL |
| 85 | at runtime |
| 86 | |
| 87 | ``EGL_PLATFORM`` |
| 88 | This variable specifies the native platform. The valid values are the |
| 89 | same as those for ``-D platforms=...``. When the variable is not set, |
| 90 | the main library uses the first platform listed in |
| 91 | ``-D platforms=...`` as the native platform. |
| 92 | |
| 93 | Extensions like ``EGL_MESA_drm_display`` define new functions to |
| 94 | create displays for non-native platforms. These extensions are |
| 95 | usually used by applications that support non-native platforms. |
| 96 | Setting this variable is probably required only for some of the demos |
| 97 | found in mesa/demo repository. |
| 98 | |
| 99 | ``EGL_LOG_LEVEL`` |
| 100 | This changes the log level of the main library and the drivers. The |
| 101 | valid values are: ``debug``, ``info``, ``warning``, and ``fatal``. |
| 102 | |
Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 103 | Packaging |
| 104 | --------- |
| 105 | |
| 106 | The ABI between the main library and its drivers are not stable. Nor is |
| 107 | there a plan to stabilize it at the moment. |
| 108 | |
| 109 | Developers |
| 110 | ---------- |
| 111 | |
| 112 | The sources of the main library and drivers can be found at |
| 113 | ``src/egl/``. |
| 114 | |
Eric Engestrom | ab2e597 | 2020-07-31 00:47:13 +0200 | [diff] [blame] | 115 | The code basically consists of two things: |
| 116 | |
| 117 | 1. An EGL API dispatcher. This directly routes all the ``eglFooBar()`` |
| 118 | API calls into driver-specific functions. |
| 119 | |
| 120 | 2. Two EGL drivers (``dri2`` and ``haiku``), implementing the API |
| 121 | functions handling the platforms' specifics. |
| 122 | |
| 123 | Two of API functions are optional (``eglQuerySurface()`` and |
| 124 | ``eglSwapInterval()``); the former provides fallback for all the |
Erik Faye-Lund | 580b9d1 | 2020-09-30 10:30:19 +0200 | [diff] [blame] | 125 | platform-agnostic attributes (i.e. everything except ``EGL_WIDTH`` |
Eric Engestrom | ab2e597 | 2020-07-31 00:47:13 +0200 | [diff] [blame] | 126 | & ``EGL_HEIGHT``), and the latter just silently pretends the API call |
| 127 | succeeded (as per EGL spec). |
| 128 | |
| 129 | A driver _could_ implement all the other EGL API functions, but several of |
| 130 | them are only needed for extensions, like ``eglSwapBuffersWithDamageEXT()``. |
Eric Engestrom | 98222db | 2020-08-02 02:00:55 +0200 | [diff] [blame] | 131 | See ``src/egl/main/egldriver.h`` to see which driver hooks are only |
| 132 | required by extensions. |
Eric Engestrom | ab2e597 | 2020-07-31 00:47:13 +0200 | [diff] [blame] | 133 | |
| 134 | Bootstrapping |
| 135 | ~~~~~~~~~~~~~ |
| 136 | |
| 137 | When the apps calls ``eglInitialize()``, the driver's ``Initialize()`` |
Erik Faye-Lund | 0894b59 | 2020-09-25 15:09:15 +0200 | [diff] [blame] | 138 | function is called. If the first driver initialization attempt fails, |
Eric Engestrom | ab2e597 | 2020-07-31 00:47:13 +0200 | [diff] [blame] | 139 | a second one is tried using only software components (this can be forced |
| 140 | using the ``LIBGL_ALWAYS_SOFTWARE`` environment variable). Typically, |
| 141 | this function takes care of setting up visual configs, creating EGL |
| 142 | devices, etc. |
| 143 | |
| 144 | Teardown |
| 145 | ~~~~~~~~ |
| 146 | |
| 147 | When ``eglTerminate()`` is called, the ``driver->Terminate()`` function |
| 148 | is called. The driver should clean up after itself. |
| 149 | |
| 150 | Subclassing |
| 151 | ~~~~~~~~~~~ |
| 152 | |
| 153 | The internal libEGL data structures such as ``_EGLDisplay``, |
| 154 | ``_EGLContext``, ``_EGLSurface``, etc. should be considered base classes |
| 155 | from which drivers will derive subclasses. |
| 156 | |
Eric Engestrom | 3909e9d | 2020-07-29 11:06:15 +0200 | [diff] [blame] | 157 | EGL Drivers |
| 158 | ----------- |
| 159 | |
| 160 | ``egl_dri2`` |
Eric Engestrom | c84d304 | 2020-07-29 11:27:21 +0200 | [diff] [blame] | 161 | This driver supports several platforms: ``android``, ``device``, |
| 162 | ``drm, ``surfaceless``, ``wayland`` and ``x11``. It functions as |
| 163 | a DRI driver loader. For ``x11`` support, it talks to the X server |
Eric Engestrom | 12c9418 | 2020-08-01 22:27:46 +0200 | [diff] [blame] | 164 | directly using (XCB-)DRI3 protocol when available, and falls back to |
| 165 | DRI2 if necessary (can be forced with ``LIBGL_DRI3_DISABLE``). |
Eric Engestrom | 3909e9d | 2020-07-29 11:06:15 +0200 | [diff] [blame] | 166 | |
| 167 | This driver can share DRI drivers with ``libGL``. |
| 168 | |
Eric Engestrom | 7897c31 | 2020-07-29 11:33:12 +0200 | [diff] [blame] | 169 | ``haiku`` |
| 170 | This driver supports only the `Haiku <https://haiku-os.org>`__ |
| 171 | platform. It is also much less feature-complete than ``egl_dri2``, |
| 172 | supporting only part of EGL 1.4 and none of the extensions beyond it. |
| 173 | |
Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 174 | Lifetime of Display Resources |
| 175 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 176 | |
| 177 | Contexts and surfaces are examples of display resources. They might live |
| 178 | longer than the display that creates them. |
| 179 | |
| 180 | In EGL, when a display is terminated through ``eglTerminate``, all |
| 181 | display resources should be destroyed. Similarly, when a thread is |
| 182 | released through ``eglReleaseThread``, all current display resources |
| 183 | should be released. Another way to destroy or release resources is |
| 184 | through functions such as ``eglDestroySurface`` or ``eglMakeCurrent``. |
| 185 | |
| 186 | When a resource that is current to some thread is destroyed, the |
| 187 | resource should not be destroyed immediately. EGL requires the resource |
| 188 | to live until it is no longer current. A driver usually calls |
| 189 | ``eglIs<Resource>Bound`` to check if a resource is bound (current) to |
| 190 | any thread in the destroy callbacks. If it is still bound, the resource |
| 191 | is not destroyed. |
| 192 | |
| 193 | The main library will mark destroyed current resources as unlinked. In a |
| 194 | driver's ``MakeCurrent`` callback, ``eglIs<Resource>Linked`` can then be |
| 195 | called to check if a newly released resource is linked to a display. If |
| 196 | it is not, the last reference to the resource is removed and the driver |
| 197 | should destroy the resource. But it should be careful here because |
| 198 | ``MakeCurrent`` might be called with an uninitialized display. |
| 199 | |
| 200 | This is the only mechanism provided by the main library to help manage |
| 201 | the resources. The drivers are responsible to the correct behavior as |
| 202 | defined by EGL. |
| 203 | |
| 204 | ``EGL_RENDER_BUFFER`` |
| 205 | ~~~~~~~~~~~~~~~~~~~~~ |
| 206 | |
| 207 | In EGL, the color buffer a context should try to render to is decided by |
| 208 | the binding surface. It should try to render to the front buffer if the |
| 209 | binding surface has ``EGL_RENDER_BUFFER`` set to ``EGL_SINGLE_BUFFER``; |
| 210 | If the same context is later bound to a surface with |
| 211 | ``EGL_RENDER_BUFFER`` set to ``EGL_BACK_BUFFER``, the context should try |
| 212 | to render to the back buffer. However, the context is allowed to make |
| 213 | the final decision as to which color buffer it wants to or is able to |
| 214 | render to. |
| 215 | |
| 216 | For pbuffer surfaces, the render buffer is always ``EGL_BACK_BUFFER``. |
| 217 | And for pixmap surfaces, the render buffer is always |
| 218 | ``EGL_SINGLE_BUFFER``. Unlike window surfaces, EGL spec requires their |
| 219 | ``EGL_RENDER_BUFFER`` values to be honored. As a result, a driver should |
| 220 | never set ``EGL_PIXMAP_BIT`` or ``EGL_PBUFFER_BIT`` bits of a config if |
| 221 | the contexts created with the config won't be able to honor the |
| 222 | ``EGL_RENDER_BUFFER`` of pixmap or pbuffer surfaces. |
| 223 | |
| 224 | It should also be noted that pixmap and pbuffer surfaces are assumed to |
| 225 | be single-buffered, in that ``eglSwapBuffers`` has no effect on them. It |
| 226 | is desirable that a driver allocates a private color buffer for each |
| 227 | pbuffer surface created. If the window system the driver supports has |
| 228 | native pbuffers, or if the native pixmaps have more than one color |
| 229 | buffers, the driver should carefully attach the native color buffers to |
| 230 | the EGL surfaces, re-route them if required. |
| 231 | |
| 232 | There is no defined behavior as to, for example, how ``glDrawBuffer`` |
| 233 | interacts with ``EGL_RENDER_BUFFER``. Right now, it is desired that the |
| 234 | draw buffer in a client API be fixed for pixmap and pbuffer surfaces. |
| 235 | Therefore, the driver is responsible to guarantee that the client API |
| 236 | renders to the specified render buffer for pixmap and pbuffer surfaces. |
| 237 | |
| 238 | ``EGLDisplay`` Mutex |
| 239 | ~~~~~~~~~~~~~~~~~~~~ |
| 240 | |
| 241 | The ``EGLDisplay`` will be locked before calling any of the dispatch |
| 242 | functions (well, except for GetProcAddress which does not take an |
| 243 | ``EGLDisplay``). This guarantees that the same dispatch function will |
Eric Engestrom | 3704b02 | 2020-07-29 10:58:14 +0200 | [diff] [blame] | 244 | not be called with the same display at the same time. If a driver has |
Erik Faye-Lund | 4d06683 | 2020-06-12 20:09:42 +0200 | [diff] [blame] | 245 | access to an ``EGLDisplay`` without going through the EGL APIs, the |
| 246 | driver should as well lock the display before using it. |