EGLDevice

This topic describes EGL mechanisms that you can use to render 3D images on a pure EGL display. Such a display does not use a window system.

EGLDevice

EGLDevice provides a mechanism to access graphics functionality in the absence of or without reference to a native window system. It is a method to initialize EGL displays and surfaces directly on top of GPUs/devices rather than native window system objects. It is a cross-platform method to discover media devices like displays, GPUs, etc. The set of EGLDevice extensions boot strap EGL, without the use of any native APIs.

EGLOutput

EGLOutput is to graphical outputs what EGLDevice is to devices. It allows enumeration of outputs on a device. EGLOutput allows rendering directly to a screen in the absence of a window system. Additionally, it allows applications to bypass native window systems for direct rendering. It defines certain EGL resources for referencing display control hardware associated with an EGL device. EGLOutput provides a binding between GL, NVIDIA® CUDA®, and multimedia rendering and the display output. In a typical Embedded setting, the outputs are often initialized to a fixed state at system startup. But in cases where they are configurable, other interfaces such as DRM must be used.

EGLStream

Refer to EGLStream for more information.

Extensions

EGL extensions specify the behavior, procedures, and functions for these EGL mechanisms.

  • EGLDevice

    • EGL_EXT_device_base

    • EGL_EXT_platform_base

    • EGL_EXT_platform_device

  • EGLOutput

    • EGL_EXT_output_base

  • EGLStream

    • EGL_KHR_stream

    • EGL_KHR_stream_producer_eglsurface

    • EGL_EXT_stream_consumer_egloutput

For a description of these EGL extensions, see:

Rendering to EGLDevice

Here are the steps to render to an EGLDevice using a EGLStream producer surface:

  1. Create an EGLDisplay from an EGLDevice.

  2. Create an EGLContext from the EGLDisplay.

  3. Create an EGLStream producer surface.

  4. Bind a GL context to the EGLStream producer surface.

  5. Post the surface contents to the EGLStream using swap buffers.

Creating a EGLStream Producer Surface

In the absence of an underlying window system, you need the EGLStream producer surface for on screen rendering. EGLStream producer surfaces behave like any other EGLSurface. For example, eglSwapBuffers() must still be called to indicate the end of a frame. However, EGLStream producer surfaces are stream producers, so eglSwapBuffers() submits rendering to the EGLStream rather than presenting it to a native window directly. Typically, an EGLOutput consumer can use any producer attached to the EGLStream but needs a surface producer when the rendering API is OpenGL.

A common use case for EGLStream producer surfaces is an application that produces display frames using OpenGL and attaching these frames as a producer to one end of an EGLStream. The EGLstream consumer on the other end is an EGLOutput layer that sends frames directly to a display device.

Creating a EGLStream producer surface uses the following functions:

Function

Extension and Function Description

eglCreateStreamProducerSurfaceKHR()

EGL_KHR_stream_producer_eglsurface

Creates an EGLSurface and connects it as the producer of a stream.

eglStreamConsumerOutputEXT()

EGL_EXT_stream_consumer_egloutput

Binds an EGLOutput layer as a stream consumer to send rendering directly to a display device.

According to the EGL_KHR_stream specification, the EGLStream cannot be used until it has been connected to a consumer and producer. The consumer must be connected before the producer is connected.

Rendering to an EGLDevice Through the EGLStream

  1. Query EGL extensions with eglGetProcAddress().

  2. Query available EGLDevices with eglQueryDevicesEXT().

  3. Obtain an EGLDisplay from the EGLDevice with eglGetPlatformDisplayEXT().

    This step creates an EGLDisplay that does not belong to any native platform.

  4. Initialize EGL with eglInitialize().

  5. Set up an EGLOutput. For detailed steps, see Setting Up the Display with DRM.

    • Select an output.

      • Can be done by enumerating all outputs and selecting a known index.

      • Can be done by looking up an output associated with a native (e.g. DRM) screen handle.

    • If necessary, initialize display settings with native interfaces.

  6. Direct rendering to an EGLOutput.

    • Create an EGLStream with eglCreateStreamKHR().

    • Connect the output layer to the EGLStream. Bind consumer end of stream to EGLOutput window object with eglStreamConsumerOutputEXT().

  7. Set the buffer configurations by choosing an EGLConfig.

  8. To feed the EGLStream, create an EGLStream producer surface with eglCreateStreamProducerSurfaceKHR().

  9. Create an EGLContext and make it current by binding it to the stream surface with eglMakeCurrent().

  10. Post the surface contents to the EGLStream with eglSwapBuffers().

Setting Up the Display with DRM

The Direct Rendering Manager (DRM) is a framework to manage GPUs and displays. Managing connected monitors and displays and changing the current modes is called mode-setting and is one of the functions of DRM. As mentioned in the “If necessary, initialize display settings …” part in Step 5 in Creating a Stream Surface, this native interface can be used to initialize the display setting.

To select an encoder, CRTC, and connector

  1. Open a DRM device file with drmOpen().

  2. Obtain DRM-KMS resources with drmModeGetResources().

  3. (Optional) Get the plane information with drmModeGetPlane() and drmModeGetPlaneResources().

  4. Query the desired connector with drmModeGetConnector().

    All valid modes for a connector can be retrieved with a call to drmModeGetConnector(). Select the mode to be used and save it. The first mode in the list is the default mode with the highest resolution possible and often a suitable choice.

  5. If there is already an encoder attached to the connector, select it with drmModeGetEncoder().

    If the attached encoder is incompatible with CRTC/plane find another one by iterating over all available encoders.

  6. Select a suitable CRTC.

    • For each connector, find a CRTC to drive this connector. To find a suitable CRTC, iterate over the list of encoders that are available for each connector. Each encoder contains a list of CRTCs that it can work with and select one of these CRTCs.

    • Query the information for CRTC with drmModeGetCrtc().

  7. If necessary, set the mode with drmModeSetCrtc() and obtain the layer for the plane/CRTC.

    Use CRTC to drive the selected connector with a call to drmModeSetCrtc().

  8. If a plane must be used, set it with drmModeSetPlane().

More information

  • For API details, see “DRM API” in NVIDIA Jetson Linux API Reference.

  • Ask your NVIDIA Customer Engineer for a sample implementation, window_egldevice.zip.

Board-to-Display Connectors

For information about the connectors on your platform and the relationship between connectors and displays, see the documentation for your hardware.