pax_global_header00006660000000000000000000000064146371116220014515gustar00rootroot0000000000000052 comment=3875a836d5e30f01edd31b7318c52f171516224c eglexternalplatform-1.2/000077500000000000000000000000001463711162200154365ustar00rootroot00000000000000eglexternalplatform-1.2/COPYING000066400000000000000000000021761463711162200164770ustar00rootroot00000000000000 Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. eglexternalplatform-1.2/README.md000066400000000000000000000303421463711162200167170ustar00rootroot00000000000000EGL External Platform Interface =============================== Overview -------- This is a work-in-progress specification of the EGL External Platform interface for writing EGL platforms and their interactions with modern window systems on top of existing low-level EGL platform implementations. This keeps window system implementation specifics out of EGL drivers by using application-facing EGL functions. Examples of low-level EGL platforms are `EGL_EXT_platform_device` or `EGL_MESA_platform_surfaceless`. Installing the interface ------------------------ This is a headers-only specification of the interface. A `meson.build` file is included, which will install the header files and generate a matching pkg-config file. Alternately, `meson.build` has the necessary `override_dependency` call to work as a Meson subproject. Definitions ----------- The following terms are used throughout this README file: * *EGL driver* An implementation of the full EGL API, either as a vendor library loaded by GLVND, or as a standalone library linked against by applications. * *EGL platform* A rendering system an EGL driver can support at runtime. An EGL platform may refer to a window system (e.g. X11, Wayland) or a headless rendering platform (e.g. EGLDevice, GBM). See section *2.1 "Native Platforms and Rendering APIs"* of the EGL 1.5 specification, or *EGL_EXT_platform_base* extension. * *EGL platform library* An implementation of a single EGL External Platform interface on top of interfaces provided by an EGL driver. * *EGL entrypoint layer* Thin layer sitting on top of an EGL driver internal implementation that will dispatch calls coming from applications (or GLVND) to either an EGL platform library or the EGL driver itself. * *EGL External Platform interface* Set of functions, hooks, and data structures definitions an EGL entrypoint layer will use to interact with EGL platform libraries. * *EGL external & internal object handle* An external object handle refers to the EGL object handle given to the application. These may be provided by either an EGL platform library or the EGL driver, depending on what platform the object belongs to. In turn, an internal object handle refers to the EGL object handle that only the EGL driver internal implementation understands. Interface walk-through ---------------------- All functions and hooks of an EGL platform library are made available either as an exports table or dynamically loaded hooks to the EGL entrypoint layer. A special entry point `loadEGLExternalPlatform()` function must be used to load all exports and data of a given EGL platform library. `loadEGLExternalPlatform()` takes *major* and *minor* numbers corresponding to the version of the EGL External Platform interface the EGL entrypoint layer will use to interact with the loaded platform. This provides a means for both the interface and EGL platform libraries to evolve separately in a backwards compatible way. Different types of functions and hooks are defined and described below. Unless otherwise specified, the following functions are made available as an exports table to the EGL entrypoint layer: * *Pure EGL hooks* They are intended to be used in replacement of application-facing EGL functions. Pure EGL hooks are not provided as entries of the external exports table, but are retrieved dynamically with the 'getHookAddress()' export. An EGL platform library can provide a hook for most of the application-facing functions the EGL entrypoint layer is aware of. Examples of these are, among others, hooks for `eglCreatePlatformWindowSurface()` or `eglSwapBuffers()`. * *Derivatives of EGL functions* These are variations of application-facing EGL functions that may require extra parameters or will have a sligthly different behavior in order to help the EGL entrypoint layer operate in presence of EGL platform libraries. An example of these is `queryString()` which is symmetric to `eglQueryString()`, but a new EGLExtPlatformString enum is given for the string name instead. It helps `eglQueryString()` to return the appropriate extension string depending on what EGL platform libraries are available, for instance. * *External object validation functions* The goal of this type of function is to help the EGL entrypoint layer to determine which EGL platform library should handle which calls when opaque native resources are given. An example of these functions is `isValidNativeDisplay()`, which helps `eglGetDisplay()`. * *External -> Internal object translation functions* Whenever non-externally implemented EGL functions are called, translation from external (EGL platform library) object handles to internal (EGL driver) ones is required. `getInternalHandle()` returns the EGL internal handle of a given external object. * *Callbacks* Sometimes, there might be operations that require execution of non-application-facing code within the EGL platform library. The EGL External Platform interface provides a means for registering callbacks in such cases. Unlike the previously described functions, which are implemented by an EGL platform library and made available to the EGL entrypoint layer, these callbacks allow the latter to register EGL driver functions with the former. An example of these is the `eglSetError()` callback that allows EGL platform libraries to set EGL error codes to be queried by the application in case of failure. More detailed information of every symbol the EGL External Platform interface defines can be found in the `interface/eglexternalplatform.h` file. Interactions with the EGL driver -------------------------------- Discovery and registration of EGL platform libraries is the EGL entrypoint layer's responsibility. What discovery method to use is specific to each implementation, but it is advisable to use something portable and fully configurable (see JSON-based vendor libraries loader in GLVND). The initial interaction of an EGL entrypoint layer with an EGL platform library happens with `loadEGLExternalPlatform()`. This function allows to retrieve both the exports table and data such as the platform enumeration value. It also provides a means for the EGL entrypoint layer to pass in an EGL driver imports structure such that EGL platform libraries can fetch any driver methods they may require to use. `loadEGLExternalPlatform()` takes *major* and *minor* numbers corresponding to the version of the EGL External Platform interface the EGL entrypoint layer will use. The EGL platform library must then check those numbers against the interface version it implements, and return the appropriate exports and data (or fail if versions are not compatible). EGL platform libraries may initialize their own private platform data structure at load time to be given to the EGL entrypoint layer. The EGL entrypoint layer will in turn pass the structure to all export and hook functions which take another platform's EGLDisplay, or which do not take an EGLDisplay as input (client extensions). All EGLDisplay creation operations will be forwarded to the EGL platform library `getPlatformDisplay()` export. This gives the EGL entrypoint layer the ability to track which EGLDisplay belongs to which platform in order to dispatch subsequent functions. All EGLSurface creation operations will also be forwarded to the appropriate EGL platform library hooks. They are required to be externally implemented for applications to be able to present buffers onto a surface. Any other EGL object creation operation can be also hooked, but the internal handle must be always returned. Note that, by design, all object creation operations must be hooked for objects that are currently required to be externally backed (EGLDisplay and EGLSurface). Some functions need to be handled by a particular EGL platform library, but either do not take an EGLDisplay handle or take an EGLDisplay handle that belongs to a different platform. These functions will require special handling, which will be defined on a case-by-case basis. For example, `eglGetDisplay()` uses the `isValidNativeDisplay()` export in order to determine what EGL platform library to use, and then the `getPlatformDisplay()` export to actually create the display. The following diagram illustrates the control flow between an application, the EGL driver, and two different EGL platform libraries: +-------------------------------+ | | | Application | | | +--------------+----------------+ | | +--------------|----------------+ | | | +------------------------+ | EGL driver | | | | | | | +----> EGL platform library A +-----+ | +-----------v-------------+ | | | | | | | | | | +------------------------+ | | | EGL entrypoint layer +-----+ | | | | | | +------------------------+ | | +-----------+-------------+ | | | | | | | | +----> EGL platform library B +--+ | | | | | | | | | +-----------v-------------+ | +------------------------+ | | | | | | | | | | | | | | | | <--------------------------------------+ | | | EGL driver internal | | | | | | | | | | <-----------------------------------------+ | | | | | +-------------------------+ | | | +-------------------------------+ Sample code ----------- In order to illustrate how to use the EGL External Platform interface, a few files with sample code can be found under the 'samples' folder: * 'samples/sample-egl-server.c': Sample code for a display server working on top of the EGLStream family of extensions. * 'samples/sample-egl-client.c': Sample code for an EGL application that would run on Foo window system. * 'samples/libsample-egl-platform.c': Sample code for an EGL External Platform implementation that would add EGL_PLATFORM_SAMPLE support on top of EGLStream family of extensions. Note that these source files are incomplete, and are not intended to be used as-is. Also, the NVIDIA Wayland implementation can be found at: https://github.com/NVIDIA/egl-wayland Acknowledgements ---------------- Thanks to James Jones for the original implementation of the Wayland external platform that led to the design of the EGL External Platform infrastructure. ### EGL External Platform interface ### The EGL External Platform interface itself is licensed as follows: Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. eglexternalplatform-1.2/interface/000077500000000000000000000000001463711162200173765ustar00rootroot00000000000000eglexternalplatform-1.2/interface/eglexternalplatform.h000066400000000000000000000235761463711162200236430ustar00rootroot00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef EGL_EXTERNAL_PLATFORM_H #define EGL_EXTERNAL_PLATFORM_H #include #include #include "eglexternalplatformversion.h" /* EGL external platform interface objects */ typedef struct EGLExtPlatformExports EGLExtPlatformExports; typedef struct EGLExtPlatform EGLExtPlatform; typedef struct EGLExtDriver EGLExtDriver; /* EGLExtPlatformString enum. This indicates what string to query through * queryString() */ typedef enum { /* * Platform client extensions * * Returns a extension string including the specific platform client * extensions. E.g. EGL_EXT_platform_wayland on Wayland platform. * * The parameter is EGL_NO_DISPLAY. */ EGL_EXT_PLATFORM_PLATFORM_CLIENT_EXTENSIONS = 0, /* * Display extensions * * Returns a extension string including all display extensions supported on * the given display by the external platform implementation. */ EGL_EXT_PLATFORM_DISPLAY_EXTENSIONS, EGL_EXT_PLATFORM_STRING_NAME_COUNT } EGLExtPlatformString; /* * loadEGLExternalPlatform() * * Loads the EGL external platform and returns a EGLExtPlatform object where * external platform data and exported functions have been properly set * according to the given major and minor version numbers * * If a compatible external platform is found for ., EGL_TRUE is * returned and is properly initialized. Otherwise, EGL_FALSE is * returned and remains unchanged * * A reference to the underlying EGL implementation that must be used is passed * in . */ typedef EGLBoolean (*PEGLEXTFNLOADEGLEXTERNALPLATFORM) (int major, int minor, const EGLExtDriver *driver, EGLExtPlatform *platform); /* * unloadEGLExternalPlatform() * * Unloads the EGL external platform, freeing any resources associated to the * given platform data structure that may have been allocated and not yet freed. * * If all resources are properly freed, EGL_TRUE is returned and the given * platform data pointer becomes invalid. Otherwise, EGL_FALSE is returned. * * Prior to version 1.2, the driver called this after it had finished most of * its internal teardown, so calling into the driver was not safe. In version * 1.2 or later, however, it's safe to call into the driver, and any internal * EGLDisplays will still be valid. */ typedef EGLBoolean (*PEGLEXTFNUNLOADEGLEXTERNALPLATFORM) (void *platformData); /* * getHookAddress() * * The EGL external platform interface defines a minimum set of functions that * must be provided by any EGL external platform at loadEGLExternalPlatform() * time. * * However, most of the other EGL functions can be overwritten by an EGL * external platform. * * The EGL implementation will call into getHookAddress() to retrieve any * additional EGL function that the external platform may implement. Its * behavior is comparable to eglGetProcAddress(). * * Returns the hook address if the given functions is implemented; otherwise, * returns NULL. */ typedef void* (*PEGLEXTFNGETHOOKADDRESS) (void *platformData, const char *name); /* * isValidNativeDisplay() * * Validity check function for a native display. It will return EGL_TRUE if the * given native display is valid and belongs to the external platform * implementation; otherwise, it will return EGL_FALSE. */ typedef EGLBoolean (*PEGLEXTFNISVALIDNATIVEDISPLAY) (void *platformData, void *nativeDisplay); /* * getPlatformDisplay() * * Same as eglGetPlatformDisplay() */ typedef EGLDisplay (*PEGLEXTFNGETPLATFORMDISPLAY) (void *platformData, EGLenum platform, void *nativeDisplay, const EGLAttrib* attribs); /* * queryString() * * Similar to eglQueryString(), but takes its own enumeration as the string name * parameter. * * Returns the appropriate extension string which is supported by the external * platform. See descriptions of EGLExtPlatformString enums for more details. */ typedef const char * (*PEGLEXTFNQUERYSTRING) (void *platformData, EGLDisplay dpy, EGLExtPlatformString name); /* * getInternalHandle() * * Conversion function from an EGL external object handle to its corresponding * EGL internal one. It will return the internal EGL object handle if the given * external handle is valid and belongs to the given EGLDisplay; otherwise, it * will return NULL. * * Note that the object handle type must be provided by the caller. Its value * must be one of the object type enums as defined in EGL_KHR_debug. */ typedef void* (*PEGLEXTFNGETINTERNALHANDLE) (EGLDisplay dpy, EGLenum type, void *handle); /* * getObjectLabel() * * Returns an EGL external object label previously attached with * eglLabelObjectKHR() from EGL_KHR_debug. * * Note that the object handle type must be provided by the caller. Its value * must be one of the object type enums as defined in EGL_KHR_debug. */ typedef void* (*PEGLEXTFNGETOBJECTLABEL) (EGLDisplay dpy, EGLenum type, void *handle); /* * EGLExtPlatformExports definition. This is the exports table an external * platform must fill out and make available for the EGL implementation to use */ struct EGLExtPlatformExports { PEGLEXTFNUNLOADEGLEXTERNALPLATFORM unloadEGLExternalPlatform; PEGLEXTFNGETHOOKADDRESS getHookAddress; PEGLEXTFNISVALIDNATIVEDISPLAY isValidNativeDisplay; PEGLEXTFNGETPLATFORMDISPLAY getPlatformDisplay; PEGLEXTFNQUERYSTRING queryString; PEGLEXTFNGETINTERNALHANDLE getInternalHandle; PEGLEXTFNGETOBJECTLABEL getObjectLabel; }; /* * EGLExtPlatform definition. This is common to all external platforms * * Fields: * - major/minor: External platform major/minor version number. Specify the EGL * external platform interface version number the given platform * implements. They are tied to EGL external platform interface * changes. * - micro: External platform micro version number. Similar to * major/minor numbers, but it is tied to specific external * platform implementation changes. * - platform: EGL platform enumeration the corresponding external platform * implements. * - data: Opaque pointer to platform specific data. At platform * load time, the external platform can initialize its own data * structure to store any information that may be required by * any function that does not take an EGLDisplay or the display * belongs to another platform. * - exports: External platform exports table. */ struct EGLExtPlatform { struct { int major; int minor; int micro; } version; EGLenum platform; void *data; EGLExtPlatformExports exports; }; /* * getProcAddress() * * Equivalent to eglGetProcAddress() to fetch EGL methods provided by a * specific EGL driver. */ typedef void* (*PEGLEXTFNGETPROCADDRESS) (const char *name); /* * setError() * * Sets the last EGL error, which can be queried with eglGetError() later on. It * also calls the EGL_KHR_debug callback if such extension is supported by the * driver. * * Takes the EGL error code and both message type and string as defined in * EGL_KHR_debug for the debug callback function. */ typedef void (*PEGLEXTFNSETERROR) (EGLint error, EGLint msgType, const char *msg); /* * debugMessage() * * Calls the EGL_KHR_debug callback if such extension is supported by the * driver. * * Takes both message type and string as defined in EGL_KHR_debug for the debug * callback function. */ typedef void* (*PEGLEXTFNDEBUGMESSAGE) (EGLint msgType, const char *msg); /* * streamSwapInterval() * * Handle swapinterval on the EGLStream consumer side. Should be a noop for * any consumer that does not present directly to a display. * * Takes the stream handle and a pointer to the interval value as parameters. * * Returns one of the following EGL error codes: * - EGL_SUCCESS: The interval setting operation succeeded (or noop). * - EGL_BAD_MATCH: A server-side interval override is in place. The override * value is returned in the parameter. * - EGL_BAD_ACCESS: The interval setting operation failed. */ typedef EGLint (*PEGLEXTFNSTREAMSWAPINTERVAL) (EGLStreamKHR stream, int *interval); /* * EGLExtDriver definition. The EGL external driver is the component in * charge of dispatching EGL calls to the underlying EGL implementation. */ struct EGLExtDriver { PEGLEXTFNGETPROCADDRESS getProcAddress; PEGLEXTFNSETERROR setError; PEGLEXTFNDEBUGMESSAGE debugMessage; PEGLEXTFNSTREAMSWAPINTERVAL streamSwapInterval; #if EGL_EXTERNAL_PLATFORM_HAS(DRIVER_VERSION) int major; int minor; #endif }; #endif // EGL_EXTERNAL_PLATFORM_H eglexternalplatform-1.2/interface/eglexternalplatformversion.h000066400000000000000000000153351463711162200252430ustar00rootroot00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef EGL_EXTERNAL_PLATFORM_VERSION_H #define EGL_EXTERNAL_PLATFORM_VERSION_H /* * . * defines the EGL external platform interface version. * * The includer of this file can override either * EGL_EXTERNAL_PLATFORM_VERSION_MAJOR or EGL_EXTERNAL_PLATFORM_VERSION_MINOR in * order to build against a certain EGL external platform interface version. * * Note that, if only EGL_EXTERNAL_PLATFORM_VERSION_MAJOR is overridden, the * least possible value for EGL_EXTERNAL_PLATFORM_VERSION_MINOR is taken. * * * How to update these version numbers: * * - If a backwards-compatible change is made to the interface, increase * EGL_EXTERNAL_PLATFORM_VERSION_MINOR by 1 * * - If backwards-compatibility is broken by a change, increase * EGL_EXTERNAL_PLATFORM_VERSION_MAJOR by 1 and set * EGL_EXTERNAL_PLATFORM_VERSION_MINOR to 0 (keep these kind of changes to * the minimum) */ #if !defined(EGL_EXTERNAL_PLATFORM_VERSION_MAJOR) #define EGL_EXTERNAL_PLATFORM_VERSION_MAJOR 1 #if !defined(EGL_EXTERNAL_PLATFORM_VERSION_MINOR) #define EGL_EXTERNAL_PLATFORM_VERSION_MINOR 2 #endif #elif !defined(EGL_EXTERNAL_PLATFORM_VERSION_MINOR) #define EGL_EXTERNAL_PLATFORM_VERSION_MINOR 0 #endif /* * EGL_EXTERNAL_PLATFORM_VERSION_CMP * * Helper macro to compare two different version numbers. It evaluates to true * if <_MAJOR1_>.<_MINOR1_> is compatible with <_MAJOR2_>.<_MINOR2_> */ #define EGL_EXTERNAL_PLATFORM_VERSION_CMP(_MAJOR1_, _MINOR1_, _MAJOR2_, _MINOR2_) \ (((_MAJOR1_) == (_MAJOR2_)) && ((_MINOR1_) >= (_MINOR2_))) /* * EGL_EXTERNAL_PLATFORM_VERSION_CHECK * * Helper macro to check whether the current EGL external platform interface * version is compatible with the given version number <_MAJOR_>.<_MINOR_> */ #define EGL_EXTERNAL_PLATFORM_VERSION_CHECK(_MAJOR_, _MINOR_) \ EGL_EXTERNAL_PLATFORM_VERSION_CMP(EGL_EXTERNAL_PLATFORM_VERSION_MAJOR, \ EGL_EXTERNAL_PLATFORM_VERSION_MINOR, \ _MAJOR_, _MINOR_) /* * EGL_EXTERNAL_PLATFORM_HAS * * Helper macro to check whether the current EGL external platform interface * version implements the given feature <_FEATURE_> */ #define EGL_EXTERNAL_PLATFORM_HAS(_FEATURE_) \ EGL_EXTERNAL_PLATFORM_VERSION_CHECK(EGL_EXTERNAL_PLATFORM_ ## _FEATURE_ ## _SINCE_MAJOR, \ EGL_EXTERNAL_PLATFORM_ ## _FEATURE_ ## _SINCE_MINOR) /* * EGL_EXTERNAL_PLATFORM_SUPPORTS * * Helper macro to check whether the given EGL external platform interface * version number <_MAJOR_>.<_MINOR_> supports the given feature <_FEATURE_> */ #define EGL_EXTERNAL_PLATFORM_SUPPORTS(_MAJOR_, _MINOR_, _FEATURE_) \ EGL_EXTERNAL_PLATFORM_VERSION_CMP(_MAJOR_, _MINOR_, \ EGL_EXTERNAL_PLATFORM_ ## _FEATURE_ ## _SINCE_MAJOR, \ EGL_EXTERNAL_PLATFORM_ ## _FEATURE_ ## _SINCE_MINOR) /* * List of supported features * * Whenever a new feature/function is added to the EGL external platform * interface, along with the corresponding version number bump, a pair of * . numbers * must be added. * * All new symbols and usages of the new feature/function must be protected with * EGL_EXTERNAL_PLATFORM_HAS(). * * Additionally, any external platform implementation that supports the new * feature/function, must also protect the corresponding export initialization * in function 'loadEGLExternalPlatform()' with * EGL_EXTERNAL_PLATFORM_SUPPORTS(, , ) using the * given version number. * * Example: * * In eglexternalplatformversion.h: * * #define EGL_EXTERNAL_PLATFORM_FOO_SINCE_MAJOR 1 * #define EGL_EXTERNAL_PLATFORM_FOO_SINCE_MINOR 0 * * In eglexternalplatform.h: * * #if EGL_EXTERNAL_PLATFORM_HAS(FOO) * typedef void* (*PEGLEXTFNFOO)(void *fooAttr); * #endif * * sitruct EGLExtPlatformExports { * [...] * * #if EGL_EXTERNAL_PLATFORM_HAS(FOO) * PEGLEXTFNFOO foo; * #endif * }; * * In platform's loadEGLExternalPlatform() implementation: * * EGLBoolean loadEGLExternalPlatform(int major, int minor, * const EGLExtDriver *driver, * EGLExtPlatform *platform) * { * if (!EGL_EXTERNAL_PLATFORM_VERSION_CHECK(major, minor)) { * return EGL_FALSE; * } * * [...] * * #if EGL_EXTERNAL_PLATFORM_HAS(FOO) * if (EGL_EXTERNAL_PLATFORM_SUPPORTS(major, minor, FOO)) { * platform->exports.foo = fooImpl; * } * #endif * * [...] * } */ /* * DRIVER_VERSION * * and fields added to EGLExtDriver for drivers to let the * external platform know the supported EGL version */ #define EGL_EXTERNAL_PLATFORM_DRIVER_VERSION_SINCE_MAJOR 1 #define EGL_EXTERNAL_PLATFORM_DRIVER_VERSION_SINCE_MINOR 1 /* * Safer unloading. * * Starting in version 1.2, it's safe to call into the driver from the * unloadEGLExternalPlatform callback. */ #define EGL_EXTERNAL_PLATFORM_DRIVER_SAFE_UNLOAD_SINCE_MAJOR 1 #define EGL_EXTERNAL_PLATFORM_DRIVER_SAFE_UNLOAD_SINCE_MINOR 2 #endif // EGL_EXTERNAL_PLATFORM_VERSION_H eglexternalplatform-1.2/meson.build000066400000000000000000000007611463711162200176040ustar00rootroot00000000000000project('eglexternalplatform', version : '1.2') pkg = import('pkgconfig') pkg.generate(filebase: 'eglexternalplatform', name: 'EGL External Platform interface', description: 'EGL External Platform interface') install_headers( 'interface/eglexternalplatform.h', 'interface/eglexternalplatformversion.h', ) eglexternalplatform_dep = declare_dependency( include_directories: include_directories('interface'), ) meson.override_dependency('eglexternalplatform', eglexternalplatform_dep) eglexternalplatform-1.2/samples/000077500000000000000000000000001463711162200171025ustar00rootroot00000000000000eglexternalplatform-1.2/samples/libsample-egl-platform.c000066400000000000000000000175031463711162200236130ustar00rootroot00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #define SAMPLE_EXTERNAL_VERSION_MAJOR 1 #define SAMPLE_EXTERNAL_VERSION_MINOR 0 #define SAMPLE_EXTERNAL_VERSION_MICRO 123 #define EGL_EXTERNAL_PLATFORM_VERSION_MAJOR SAMPLE_EXTERNAL_VERSION_MAJOR #define EGL_EXTERNAL_PLATFORM_VERSION_MINOR SAMPLE_EXTERNAL_VERSION_MINOR #include typedef const char* (*PSAMPLEEGLFNQUERYSTRINGCOREPROC) (EGLDisplay dpy, EGLint name); typedef EGLBoolean (*PSAMPLEEGLFNINITIALIZECOREPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor); typedef EGLBoolean (*PSAMPLEEGLFNTERMINATECOREPROC) (EGLDisplay dpy); typedef struct SampleDisplay { sample_display *nativeSampleDpy; EGLNativeDisplay nativeEglDpy; /* EGLDevice, GBM device, ... */ EGLDisplay eglDpy; SamplePlatformData *sampleData; } SampleDisplay; typedef struct SampleSurface { sample_window *nativeSampleWin; SampleDisplay *sampleDpy; EGLStreamKHR stream; EGLSurface eglSurf; } SampleSurface; typedef struct SamplePlatformData { /* Application-facing callbacks fetched from the EGL driver */ struct { PSAMPLEEGLFNQUERYSTRINGCOREPROC queryString; PFNEGLGETPLATFORMDISPLAYEXTPROC getPlatformDisplay; PSAMPLEEGLFNINITIALIZECOREPROC initialize; PSAMPLEEGLFNTERMINATECOREPROC terminate; /* Other EGL functions */ [...] } egl; /* Non-application-facing callbacks provided by the EGL driver */ struct { PEGLEXTFNSETERROR setError; } callbacks; } SamplePlatformData; EGLDisplay sampleGetPlatformDisplayExport(void *data, EGLenum platform, Void *nativeDpy, Const EGLAttrib *attribs) { SamplePlatformData *sampleData = (SamplePlatformData *)data; SampleDisplay *sampleDpy = malloc(sizeof(SampleDisplay)); /* Native EGL setup (EGLDevice, GBM device, ...) */ sampleDpy->nativeSampleDpy = nativeDpy; sampleDpy->nativeEglDpy = /* Get native EGL display/device */ /* Get an EGLDisplay supporting EGLStreams */ sampleDpy->eglDpy = sampleData->egl.eglGetPlatformDisplayEXT(EGL_PLATFORM_NATIVE, sampleDpy->nativeEglDpy, NULL); sampleDpy->sampleData = sampleData; /* Rest of the display creation/allocation */ [...] return (EGLDisplay)sampleDpy; } EGLSurface sampleCreatePlatformWindowSurfaceHook(EGLDisplay dpy, EGLConfig config, void *nativeWin, const EGLAttrib *attribs) { SampleDisplay *sampleDpy = (SampleDisplay *)dpy; SamplePlatformData *sampleData = sampleDpy->sampleData; SampleSurface *sampleSurf = malloc(sizeof(SampleSurface)); int fd; /* Create the underlying EGLStream */ sampleSurf->stream = sampleData->egl.eglCreateStreamKHR(sampleDpy->eglDpy, NULL); /* Let the server create its EGLStream consumer endpoint */ fd = sampleData->egl.eglGetStreamFileDescriptorKHR(sampleDpy->eglDpy, sampleSurf->stream); sample_client_connect(sampleDpy->nativeSampleDpy, fd); /* Create a surface producer */ sampleSurf->nativeSampleWin = nativeWin; sampleSurf->eglSurf = sampleData->egl.eglCreateStreamProducerSurfaceKHR(sampleDpy->eglDpy, , sampleSurf->stream, NULL); /* Rest of the surface creation/allocation */ [...] return (EGLSurface)sampleSurf; } EGLSurface sampleCreatePlatformPixmapSurfaceHook(EGLDisplay dpy, EGLConfig config, void *nativePixmap, const EGLAttrib *attribs) { /* Create pixmap surfae if supported */ [...] } EGLSurface sampleCreatePbufferSurfaceHook(EGLDisplay dpy, EGLConfig config, const EGLint *attribs) { /* Create Pbuffer surfae if supported */ [...] } EGLBoolean sampleSwapBuffersHook(EGLDisplay dpy, EGLSurface surface) { SampleDisplay *sampleDpy = (SampleDisplay *)dpy; SamplePlatformData *sampleData = sampleDpy->sampleData; SampleSurface *sampleSurf = (SampleSurface *)surface; if (sampleSurf->sampleDpy != sampleDpy) { sampleData->callbacks.setError(EGL_BAD_SURFACE, EGL_DEBUG_MSG_ERROR_KHR, "Invalid surface"); return EGL_FALSE; } sampleData->egl.eglSwapBuffers(sampleDpy->eglDpy, sampleSurf->eglSurf); /* Let the server know a new frame was generated */ sample_client_repaint(sampleDpy->nativeSampleDpy, sampleSurf->nativeSampleWin->id); /* Rest of the swap buffers handling */ [...] return EGL_TRUE; } static struct { const char name[]; void *func; } __sampleHooks[] = { { "eglCreatePlatformWindowSurface", sampleCreatePlatformWindowSurfaceHook } { "eglCreatePlatformPixmapSurface", sampleCreatePlatformPixmapSurfaceHook } { "eglCreatePbufferSurface", sampleCreatePbufferSurfaceHook } { "eglSwapBuffers", sampleSwapBuffersHook } }; void* sampleGetHookAddressExport(void *data, const char *name) { forall (hook, __sampleHooks) { if (strcmp(hook->name, name) == 0) { return hook->func; } } return NULL; } EGLBoolean loadEGLExternalPlatform(int major, int minor, const EGLExtDriver *driver, EGLExtPlatform *platform) { SamplePlatformData *sampleData = NULL; /* Version checking */ if (!platform || !EGL_EXTERNAL_PLATFORM_VERSION_CHECK(major, minor)) { return EGL_FALSE; } platform->version.major = SAMPLE_EXTERNAL_VERSION_MAJOR; platform->version.minor = SAMPLE_EXTERNAL_VERSION_MINOR; platform->version.micro = SAMPLE_EXTERNAL_VERSION_MICRO; platform->platform = EGL_PLATFORM_SAMPLE; /* Allocate and initialize platform private data */ sampleData = malloc(sizeof(SamplePlatformData)); sampleData->egl.getPlatformDisplay = driver->getProcAddress("eglGetPlatformDisplayEXT") sampleData->egl.initialize = driver->getProcAddress("eglInitialize") sampleData->egl.terminate = driver->getProcAddress("eglTerminate") sampleData->callbacks.setError = driver->setError; /* Rest of imports initialization */ [...] /* Fill with Sample platform data and exports */ platform->data = (void *)sampleData; platform->exports.getHookAddress = sampleGetHookAddressExport; platform->exports.getPlatformDisplay = sampleGetPlatformDisplayExport; /* Rest of exports initialization */ [...] return EGL_TRUE; } eglexternalplatform-1.2/samples/sample-egl-client.c000066400000000000000000000036231463711162200225540ustar00rootroot00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ int main() { /* Window system setup */ __sampleDpy = sample_display_connect("sample-display"); __sampleSurf = sample_create_surface(__sampleDpy); /* Rest of the window system setup */ [...] /* EGL setup */ __eglDpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_SAMPLE, __sampleDpy, NULL); __eglSurf = eglCreatePlatformWindowSurfaceEXT(__eglDpy, , __sampleSurf, NULL); __eglCtx = eglCreateContext(__eglDpy, , EGL_NO_CONTEXT, NULL); eglMakeCurrent(__eglDpy, __eglSurf, __eglSurf, __eglCtx); /* Rest of the EGL and OpenGL setup */ [...] while (1) { sample_dispatch_events(__sampleDpy); /* Do render */ [...] eglSwapBuffers(__eglDpy, __eglSurf); } /* Cleanup */ [...] } eglexternalplatform-1.2/samples/sample-egl-server.c000066400000000000000000000061351463711162200226050ustar00rootroot00000000000000/* * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ void handleClientConn(void *data) { int fd = (int)data; EGLStreamKHR stream; GLuint texId; stream = eglCreateStreamFromFileDescriptorKHR(__eglDpy, fd); glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId); eglStreamConsumerGLTextureExternalKHR(__eglDpy, stream); sampleSurfaceListAppend(__surfaceList, stream, texId); /* Rest of the client connection handling */ [...] } void handleClientRepaint(void *data) { int id = (int)data; forall (surf, __surfaceList) { if (surf->id == id) { eglStreamConsumerAcquireKHR(__eglDpy, surf->stream); break; } } /* Rest of the client repaint handling */ [...] } int main() { /* Window system setup */ __sampleDpy = sample_create_display("sample-display"); sample_listen_to_client_connections(__sampleDpy, handleClientConn); sample_listen_to_client_repaints(__sampleDpy, handleClientRepaint); /* Rest of the window system setup */ [...] /* Native EGL setup (EGLDevice, GBM device, ...) */ __nativeDpy = /* Get native EGL display/device */ /* Get an EGLDisplay supporting EGLStreams that would allow creation of scanout EGLSurfaces */ __eglDpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_NATIVE, __nativeDpy, NULL); eglInitialize(__eglDpy); __eglSurf = /* Create a scanout EGLSurface on __eglDpy */; __eglCtx = eglCreateContext(__eglDpy, , EGL_NO_CONTEXT, NULL); eglMakeCurrent(__eglDpy, __eglSurf, __eglSurf, __eglCtx); /* Rest of the EGL and OpenGL setup */ [...] while (1) { sample_dispatch_events(__sampleDpy); /* Composite, repaint, ... */ [...] forall (surf, __surfaceList) { glBindTexture(GL_TEXTURE_EXTERNAL_OES, surf->texId); /* Draw surface quad */ } /* Rest of the repaint handling */ [...] eglSwapBuffers(__eglDpy, eglSrf); } /* Cleanup */ [...] }