mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-27 20:24:30 +08:00
580b9d11ff
Reviewed-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7060>
247 lines
9.4 KiB
ReStructuredText
247 lines
9.4 KiB
ReStructuredText
EGL
|
|
===
|
|
|
|
The current version of EGL in Mesa implements EGL 1.4. More information
|
|
about EGL can be found at https://www.khronos.org/egl/.
|
|
|
|
The Mesa's implementation of EGL uses a driver architecture. The main
|
|
library (``libEGL``) is window system neutral. It provides the EGL API
|
|
entry points and helper functions for use by the drivers. Drivers are
|
|
dynamically loaded by the main library and most of the EGL API calls are
|
|
directly dispatched to the drivers.
|
|
|
|
The driver in use decides the window system to support.
|
|
|
|
Build EGL
|
|
---------
|
|
|
|
#. Configure your build with the desired client APIs and enable the
|
|
driver for your hardware. For example:
|
|
|
|
.. code-block:: console
|
|
|
|
$ meson configure \
|
|
-D egl=true \
|
|
-D gles1=true \
|
|
-D gles2=true \
|
|
-D dri-drivers=... \
|
|
-D gallium-drivers=...
|
|
|
|
The main library and OpenGL is enabled by default. The first two
|
|
options above enables :doc:`OpenGL ES 1.x and 2.x <opengles>`. The
|
|
last two options enables the listed classic and Gallium drivers
|
|
respectively.
|
|
|
|
#. Build and install Mesa as usual.
|
|
|
|
In the given example, it will build and install ``libEGL``, ``libGL``,
|
|
``libGLESv1_CM``, ``libGLESv2``, and one or more EGL drivers.
|
|
|
|
Configure Options
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
There are several options that control the build of EGL at configuration
|
|
time
|
|
|
|
``-D egl=true``
|
|
By default, EGL is enabled. When disabled, the main library and the
|
|
drivers will not be built.
|
|
|
|
``-D platforms=...``
|
|
List the platforms (window systems) to support. Its argument is a
|
|
comma separated string such as ``-D platforms=x11,wayland``. It decides
|
|
the platforms a driver may support. The first listed platform is also
|
|
used by the main library to decide the native platform.
|
|
|
|
The available platforms are ``x11``, ``wayland``,
|
|
``android``, and ``haiku``. The ``android`` platform
|
|
can either be built as a system component, part of AOSP, using
|
|
``Android.mk`` files, or cross-compiled using appropriate options.
|
|
Unless for special needs, the build system should select the right
|
|
platforms automatically.
|
|
|
|
``-D gles1=true`` and ``-D gles2=true``
|
|
These options enable OpenGL ES support in OpenGL. The result is one
|
|
big internal library that supports multiple APIs.
|
|
|
|
``-D shared-glapi=true``
|
|
By default, ``libGL`` has its own copy of ``libglapi``. This options
|
|
makes ``libGL`` use the shared ``libglapi``. This is required if
|
|
applications mix OpenGL and OpenGL ES.
|
|
|
|
Use EGL
|
|
-------
|
|
|
|
Demos
|
|
~~~~~
|
|
|
|
There are demos for the client APIs supported by EGL. They can be found
|
|
in mesa/demos repository.
|
|
|
|
Environment Variables
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
There are several environment variables that control the behavior of EGL
|
|
at runtime
|
|
|
|
``EGL_PLATFORM``
|
|
This variable specifies the native platform. The valid values are the
|
|
same as those for ``-D platforms=...``. When the variable is not set,
|
|
the main library uses the first platform listed in
|
|
``-D platforms=...`` as the native platform.
|
|
|
|
Extensions like ``EGL_MESA_drm_display`` define new functions to
|
|
create displays for non-native platforms. These extensions are
|
|
usually used by applications that support non-native platforms.
|
|
Setting this variable is probably required only for some of the demos
|
|
found in mesa/demo repository.
|
|
|
|
``EGL_LOG_LEVEL``
|
|
This changes the log level of the main library and the drivers. The
|
|
valid values are: ``debug``, ``info``, ``warning``, and ``fatal``.
|
|
|
|
Packaging
|
|
---------
|
|
|
|
The ABI between the main library and its drivers are not stable. Nor is
|
|
there a plan to stabilize it at the moment.
|
|
|
|
Developers
|
|
----------
|
|
|
|
The sources of the main library and drivers can be found at
|
|
``src/egl/``.
|
|
|
|
The code basically consists of two things:
|
|
|
|
1. An EGL API dispatcher. This directly routes all the ``eglFooBar()``
|
|
API calls into driver-specific functions.
|
|
|
|
2. Two EGL drivers (``dri2`` and ``haiku``), implementing the API
|
|
functions handling the platforms' specifics.
|
|
|
|
Two of API functions are optional (``eglQuerySurface()`` and
|
|
``eglSwapInterval()``); the former provides fallback for all the
|
|
platform-agnostic attributes (i.e. everything except ``EGL_WIDTH``
|
|
& ``EGL_HEIGHT``), and the latter just silently pretends the API call
|
|
succeeded (as per EGL spec).
|
|
|
|
A driver _could_ implement all the other EGL API functions, but several of
|
|
them are only needed for extensions, like ``eglSwapBuffersWithDamageEXT()``.
|
|
See ``src/egl/main/egldriver.h`` to see which driver hooks are only
|
|
required by extensions.
|
|
|
|
Bootstrapping
|
|
~~~~~~~~~~~~~
|
|
|
|
When the apps calls ``eglInitialize()``, the driver's ``Initialize()``
|
|
function is called. If the first driver initialization attempt fails,
|
|
a second one is tried using only software components (this can be forced
|
|
using the ``LIBGL_ALWAYS_SOFTWARE`` environment variable). Typically,
|
|
this function takes care of setting up visual configs, creating EGL
|
|
devices, etc.
|
|
|
|
Teardown
|
|
~~~~~~~~
|
|
|
|
When ``eglTerminate()`` is called, the ``driver->Terminate()`` function
|
|
is called. The driver should clean up after itself.
|
|
|
|
Subclassing
|
|
~~~~~~~~~~~
|
|
|
|
The internal libEGL data structures such as ``_EGLDisplay``,
|
|
``_EGLContext``, ``_EGLSurface``, etc. should be considered base classes
|
|
from which drivers will derive subclasses.
|
|
|
|
EGL Drivers
|
|
-----------
|
|
|
|
``egl_dri2``
|
|
This driver supports several platforms: ``android``, ``device``,
|
|
``drm, ``surfaceless``, ``wayland`` and ``x11``. It functions as
|
|
a DRI driver loader. For ``x11`` support, it talks to the X server
|
|
directly using (XCB-)DRI3 protocol when available, and falls back to
|
|
DRI2 if necessary (can be forced with ``LIBGL_DRI3_DISABLE``).
|
|
|
|
This driver can share DRI drivers with ``libGL``.
|
|
|
|
``haiku``
|
|
This driver supports only the `Haiku <https://haiku-os.org>`__
|
|
platform. It is also much less feature-complete than ``egl_dri2``,
|
|
supporting only part of EGL 1.4 and none of the extensions beyond it.
|
|
|
|
Lifetime of Display Resources
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Contexts and surfaces are examples of display resources. They might live
|
|
longer than the display that creates them.
|
|
|
|
In EGL, when a display is terminated through ``eglTerminate``, all
|
|
display resources should be destroyed. Similarly, when a thread is
|
|
released through ``eglReleaseThread``, all current display resources
|
|
should be released. Another way to destroy or release resources is
|
|
through functions such as ``eglDestroySurface`` or ``eglMakeCurrent``.
|
|
|
|
When a resource that is current to some thread is destroyed, the
|
|
resource should not be destroyed immediately. EGL requires the resource
|
|
to live until it is no longer current. A driver usually calls
|
|
``eglIs<Resource>Bound`` to check if a resource is bound (current) to
|
|
any thread in the destroy callbacks. If it is still bound, the resource
|
|
is not destroyed.
|
|
|
|
The main library will mark destroyed current resources as unlinked. In a
|
|
driver's ``MakeCurrent`` callback, ``eglIs<Resource>Linked`` can then be
|
|
called to check if a newly released resource is linked to a display. If
|
|
it is not, the last reference to the resource is removed and the driver
|
|
should destroy the resource. But it should be careful here because
|
|
``MakeCurrent`` might be called with an uninitialized display.
|
|
|
|
This is the only mechanism provided by the main library to help manage
|
|
the resources. The drivers are responsible to the correct behavior as
|
|
defined by EGL.
|
|
|
|
``EGL_RENDER_BUFFER``
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In EGL, the color buffer a context should try to render to is decided by
|
|
the binding surface. It should try to render to the front buffer if the
|
|
binding surface has ``EGL_RENDER_BUFFER`` set to ``EGL_SINGLE_BUFFER``;
|
|
If the same context is later bound to a surface with
|
|
``EGL_RENDER_BUFFER`` set to ``EGL_BACK_BUFFER``, the context should try
|
|
to render to the back buffer. However, the context is allowed to make
|
|
the final decision as to which color buffer it wants to or is able to
|
|
render to.
|
|
|
|
For pbuffer surfaces, the render buffer is always ``EGL_BACK_BUFFER``.
|
|
And for pixmap surfaces, the render buffer is always
|
|
``EGL_SINGLE_BUFFER``. Unlike window surfaces, EGL spec requires their
|
|
``EGL_RENDER_BUFFER`` values to be honored. As a result, a driver should
|
|
never set ``EGL_PIXMAP_BIT`` or ``EGL_PBUFFER_BIT`` bits of a config if
|
|
the contexts created with the config won't be able to honor the
|
|
``EGL_RENDER_BUFFER`` of pixmap or pbuffer surfaces.
|
|
|
|
It should also be noted that pixmap and pbuffer surfaces are assumed to
|
|
be single-buffered, in that ``eglSwapBuffers`` has no effect on them. It
|
|
is desirable that a driver allocates a private color buffer for each
|
|
pbuffer surface created. If the window system the driver supports has
|
|
native pbuffers, or if the native pixmaps have more than one color
|
|
buffers, the driver should carefully attach the native color buffers to
|
|
the EGL surfaces, re-route them if required.
|
|
|
|
There is no defined behavior as to, for example, how ``glDrawBuffer``
|
|
interacts with ``EGL_RENDER_BUFFER``. Right now, it is desired that the
|
|
draw buffer in a client API be fixed for pixmap and pbuffer surfaces.
|
|
Therefore, the driver is responsible to guarantee that the client API
|
|
renders to the specified render buffer for pixmap and pbuffer surfaces.
|
|
|
|
``EGLDisplay`` Mutex
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The ``EGLDisplay`` will be locked before calling any of the dispatch
|
|
functions (well, except for GetProcAddress which does not take an
|
|
``EGLDisplay``). This guarantees that the same dispatch function will
|
|
not be called with the same display at the same time. If a driver has
|
|
access to an ``EGLDisplay`` without going through the EGL APIs, the
|
|
driver should as well lock the display before using it.
|