blob: c22c7ac27031ef99cf6cf640ae56ca87d34b8006 [file] [log] [blame]
Name
MESA_platform_gbm
Name Strings
EGL_MESA_platform_gbm
Contributors
Chad Versace <chad.versace@intel.com>
Kristian Høgsberg <krh@bitplanet.org>
Contacts
Chad Versace <chad.versace@intel.com>
Status
Complete
Version
Version 7, 2016/01/04
Number
EGL Extension #62
Extension Type
EGL client extension
Dependencies
Requires EGL_EXT_client_extensions to query its existence without
a display.
Requires EGL_EXT_platform_base.
This extension is written against the wording of version 7 of the
EGL_EXT_platform_base specification.
Overview
This extension defines how to create EGL resources from native GBM
resources using the functions defined by EGL_EXT_platform_base. (GBM is
a Generic Buffer Manager for Linux).
New Types
None
New Procedures and Functions
None
New Tokens
Accepted as the <platform> argument of eglGetPlatformDisplayEXT:
EGL_PLATFORM_GBM_MESA 0x31D7
Additions to the EGL Specification
None.
New Behavior
To determine if the EGL implementation supports this extension, clients
should query the EGL_EXTENSIONS string of EGL_NO_DISPLAY.
To obtain an EGLDisplay from an GBM device, call eglGetPlatformDisplayEXT with
<platform> set to EGL_PLATFORM_GBM_MESA. The <native_display> parameter
specifies the GBM device to use and must either point to a `struct
gbm_device` or be EGL_DEFAULT_DISPLAY. If <native_display> is
EGL_DEFAULT_DISPLAY, then the resultant EGLDisplay will be backed by some
implementation-chosen GBM device.
For each EGLConfig that belongs to the GBM platform, the
EGL_NATIVE_VISUAL_ID attribute is a GBM color format, such as
GBM_FORMAT_XRGB8888.
To obtain a rendering surface from a GBM surface, call
eglCreatePlatformWindowSurfaceEXT with a <dpy> that belongs to the GBM
platform and a <native_window> that points to a `struct gbm_surface`. If
<native_window> was created without the GBM_BO_USE_RENDERING flag, or if
the color format of <native_window> differs from the EGL_NATIVE_VISUAL_ID
of <config>, then the function fails and generates EGL_BAD_MATCH.
It is not valid to call eglCreatePlatformPixmapSurfaceEXT with a <dpy> that
belongs to the GBM platform. Any such call fails and generates
EGL_BAD_PARAMETER.
Issues
1. Should this extension permit EGL_DEFAULT_DISPLAY as input to
eglGetPlatformDisplayEXT?
RESOLUTION: Yes. When given EGL_DEFAULT_DISPLAY, eglGetPlatformDisplayEXT
returns an EGLDisplay backed by an implementation-chosen GBM device.
Example Code
// This example program creates an EGL surface from a GBM surface.
//
// If the macro EGL_MESA_platform_gbm is defined, then the program
// creates the surfaces using the methods defined in this specification.
// Otherwise, it uses the methods defined by the EGL 1.4 specification.
//
// Compile with `cc -std=c99 example.c -lgbm -lEGL`.
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <EGL/egl.h>
#include <gbm.h>
struct my_display {
struct gbm_device *gbm;
EGLDisplay egl;
};
struct my_config {
struct my_display dpy;
EGLConfig egl;
};
struct my_window {
struct my_config config;
struct gbm_surface *gbm;
EGLSurface egl;
};
static void
check_extensions(void)
{
#ifdef EGL_MESA_platform_gbm
const char *client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (!client_extensions) {
// EGL_EXT_client_extensions is unsupported.
abort();
}
if (!strstr(client_extensions, "EGL_MESA_platform_gbm")) {
abort();
}
#endif
}
static struct my_display
get_display(void)
{
struct my_display dpy;
int fd = open("/dev/dri/card0", O_RDWR | FD_CLOEXEC);
if (fd < 0) {
abort();
}
dpy.gbm = gbm_create_device(fd);
if (!dpy.gbm) {
abort();
}
#ifdef EGL_MESA_platform_gbm
dpy.egl = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA, dpy.gbm, NULL);
#else
dpy.egl = eglGetDisplay(dpy.gbm);
#endif
if (dpy.egl == EGL_NO_DISPLAY) {
abort();
}
EGLint major, minor;
if (!eglInitialize(dpy.egl, &major, &minor)) {
abort();
}
return dpy;
}
static struct my_config
get_config(struct my_display dpy)
{
struct my_config config = {
.dpy = dpy,
};
EGLint egl_config_attribs[] = {
EGL_BUFFER_SIZE, 32,
EGL_DEPTH_SIZE, EGL_DONT_CARE,
EGL_STENCIL_SIZE, EGL_DONT_CARE,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE,
};
EGLint num_configs;
if (!eglGetConfigs(dpy.egl, NULL, 0, &num_configs)) {
abort();
}
EGLConfig *configs = malloc(num_configs * sizeof(EGLConfig));
if (!eglChooseConfig(dpy.egl, egl_config_attribs,
configs, num_configs, &num_configs)) {
abort();
}
if (num_configs == 0) {
abort();
}
// Find a config whose native visual ID is the desired GBM format.
for (int i = 0; i < num_configs; ++i) {
EGLint gbm_format;
if (!eglGetConfigAttrib(dpy.egl, configs[i],
EGL_NATIVE_VISUAL_ID, &gbm_format)) {
abort();
}
if (gbm_format == GBM_FORMAT_XRGB8888) {
config.egl = configs[i];
free(configs);
return config;
}
}
// Failed to find a config with matching GBM format.
abort();
}
static struct my_window
get_window(struct my_config config)
{
struct my_window window = {
.config = config,
};
window.gbm = gbm_surface_create(config.dpy.gbm,
256, 256,
GBM_FORMAT_XRGB8888,
GBM_BO_USE_RENDERING);
if (!window.gbm) {
abort();
}
#ifdef EGL_MESA_platform_gbm
window.egl = eglCreatePlatformWindowSurfaceEXT(config.dpy.egl,
config.egl,
window.gbm,
NULL);
#else
window.egl = eglCreateWindowSurface(config.dpy.egl,
config.egl,
window.gbm,
NULL);
#endif
if (window.egl == EGL_NO_SURFACE) {
abort();
}
return window;
}
int
main(void)
{
check_extensions();
struct my_display dpy = get_display();
struct my_config config = get_config(dpy);
struct my_window window = get_window(config);
return 0;
}
Revision History
Version 7, 2016-01-04 (Jon Leech)
- Free config memory allocated in sample code (Public Bug 1445).
Version 6, 2014-02-12 (Chad Versace)
- Change resolution of issue #1 from "no" to "yes". Now
eglGetPlatformDisplayEXT accepts EGL_DEFAULT_DISPLAY for GBM.
Version 5, 2013-010-15 (Chad Versace)
- Specify that EGL_NATIVE_VISUAL_ID is a GBM color format.
- Require for eglCreatePlatformWindowSurfaceEXT that the GBM color
format not differ between the EGLConfig and gbm_surface. (Suggested
by Kristian).
- Update example code to find matching EGL_NATIVE_VISUAL_ID.
Version 4, 2013-09-13 (Chad Versace)
- Update the text and example code to wording of version 7 of
EGL_EXT_platform_base spec.
- Add section "Extension Type".
- Resolve issue #1 to "No".
- Add issue #2.
Version 3, 2013-04-26 (Chad Versace)
- Add missing MESA suffix to new token.
Version 2, 2013-04-23 (Chad Versace)
- Add issue #1 regarding EGL_DEFAULT_DISPLAY.
Version 1, 2013.03.24 (Chad Versace)
- First draft