NVIDIA Tegra
NVIDIA DRIVE AGX Communications and Security Services

Developer Guide
5.1.6.0 Release


 
EGLDevice
 
Extensions
Runtime Configuration
Conditions Requiring a Stream Surface
Implementation
Rendering to EGLDevice
Creating a Stream Surface
Cross-Process and Cross-Partition EGLStream Applications
Connecting a Surface to a Screen
Setting Up the Display with DRM
Board-to-Display Connectors
This topic describes EGL mechanisms that you can use to implement 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
EGLStream is a mechanism to share data efficiently between different APIs without copying data. APIs could be OpenGL, CUDA, Multimedia, etc. A producer and a consumer are attached to two ends of a stream object:
Producer adds content into the stream.
Consumer retrieves this content.
EGLOutput instances can also be specified as consumers, allowing APIs to direct their output to the screen.
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:
EGL and EGL Extensions in the References
Khronos EGL extension specifications at:
https://www.khronos.org/registry/egl
Runtime Configuration
The sections below describe runtime configurations.
Conditions Requiring a Stream Surface
In the absence of an underlying window system, the stream surface is necessary for on screen rendering. Stream surfaces behave like any other EGLSurface. For example, the eglSwapBuffers function must still be called to indicate the end of a frame. However, stream surfaces are stream producers, so eglSwapBuffers submits rendering to the stream rather than presenting it to a native window directly. Typically, an EGLOutput consumer can use any producer attached to the stream but needs a surface producer when rendering API is OpenGL. For more information, see Creating a Stream Surface in this topic.
A common use case for stream producer surfaces is an application producing display frames using OpenGL, attached as a producer to one end of an EGL stream. The stream consumer on the other end is an EGLOutput layer sending frames directly to a display device.
Implementation
The following two sub-sections describe the steps to render to an EGL device using a stream surface.
Rendering to EGLDevice
These are the steps to render to an EGL device (more detailed steps follow):
1. Create an EGL display from an EGL device.
2. Create an EGL context from the EGL display.
3. Create an EGL stream producer surface.
4. Bind a GL context to the stream surface, i.e. make current.
5. Post the surface contents to the stream using swap buffers.
Creating a Stream Surface
Creating a stream 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.
To render to an EGLDevice through stream
1. Query EGL extensions using eglGetProcAddress.
2. Query available EGLDevices with eglQueryDevicesEXT.
3. Obtain an EGL display from the EGL device using eglGetPlatformDisplayEXT.
This step creates an EGLDisplay that does not belong to any native platform.
4. Initialize/setup EGL using eglInitialize.
5. Setup an EGLOutput. For detailed steps, see Setting Up the Display.
Selecting 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 using native interfaces.
6. Direct rendering to an EGLOutput.
Create an EGL stream using eglCreateStreamKHR.
Connect the output layer to the stream. Bind consumer end of stream to EGLOutput window object using eglStreamConsumerOutputEXT.
7. Set buffer configurations by choosing an EGLConfig
8. Create a stream producer surface to feed the stream using eglCreateStreamProducerSurfaceKHR.
9. Create an EGL context, make it current by binding it to the stream surface using eglMakeCurrent.
10. Post surface contents to the stream using eglSwapBuffers.
To use an EGLStream in cross-process mode
1. Make the following additions and changes to nvm_eglstream.int:
AddressSpace nvm_eglstream_producer
Filename nvm_eglstream_as0
Arguments -producer 0 -f /nfsmount/welcome_animation.264 -standalone 1
MemoryPoolSize 32M
ExtendedMemoryPoolSize 64M
HeapExtensionReservedSize 64M
Language C
Task Initial
StartIt false
StackLength 2M
EndTask
EndAddressSpace
 
AddressSpace nvm_eglstream_consumer
Filename nvm_eglstream_as0
Arguments -consumer 0 -d 2 -standalone 2
MemoryPoolSize 32M
ExtendedMemoryPoolSize 64M
HeapExtensionReservedSize 64M
Language C
Task Initial
StartIt false
StackLength 2M
EndTask
EndAddressSpace
2. Rebuild the application.
3. Load the application binary with the following command:
Load /nfsmount/nvm_eglstream_egldevice
4. Start the consumer with the following command:
rt nvm_eglstream_consumer Initial
5. Start the producer with the following command:
rt nvm_eglstream_producer Initial
This procedure enables a video producer and video consumer combination. The same procedure can also be extended for other producer/consumer combinations.
Cross-Process and Cross-Partition EGLStream Applications
This release includes the simple cross-process EGLDevice consumer and producer applications helloconsumer and helloproducer. The applications listen on 127.0.0.1, port 8888 by default. They can be used as cross-partition applications by passing --crosspart or -c to the consumer and --crosspart [<consumer_ip>] or -c [<consumer_ip>] to the producer.
The applications are built into demo_dd.
To use the applications
1. Load demo_dd.
2. Start helloconsumer on the target with the following command:
rt helloconsumer Initial
3. Start helloproducer on the target with the following command:
rt helloproducer Initial
If the applications run correctly, the upper-left corner of display 2 contains a flashing square.
Using EGL_KHR_stream_consumer_gltexture functionality, the EGLStream can also be bound to a gltexture consumer (requiring an EGLContext.) The consumer texture buffer can then be rendered to an EGLSurface, for example.
For more information on EGL_KHR_stream_consumer_gltexture see the following website:
https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_stream_consumer_gltexture.txt
 
Connecting a Surface to a Screen
You must use an EGLStream to connect a surface (i.e., a stream surface) to a screen. The surface is the stream producer, and the screen is the stream consumer.
eglGetPlatformDisplayEXT returns an EGLDisplay handle belonging to a screen as specified by platform argument in the function call.
eglMakeCurrent attaches an EGL rendering context to draw and read an EGL surface. It also binds a context and a surface to the current rendering thread.
Steps 6 through 9 in Creating a Stream Surface are required for connecting a stream surface to a screen.
eglGetPlatformDisplayEXT returns a handle to screen.
eglMakeCurrent binds the handle to the current context and surface.
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 using drmOpen.
2. Obtain DRM-KMS resources using drmModeGetResources.
3. (Optional) Get plane info using drmModeGetPlane and drmModeGetPlaneResources.
4. Query the desired connector using 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, choose it using 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 info for CRTC, drmModeGetCrtc.
7. If necessary, set the mode using drmModeSetCrtc. 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 using drmModeSetPlane.
More information
For API details, see the DRM API.
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.