Skip to content

Commit

Permalink
EGL: Add support for EGL_ANGLE_platform_angle
Browse files Browse the repository at this point in the history
This adds basic support for selecting the platform type (rendering
backend) when running on ANGLE.

Related to #1380.
  • Loading branch information
elmindreda committed Jun 28, 2020
1 parent e6a6a99 commit 0dea8a4
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 16 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -126,6 +126,8 @@ information on what to include when reporting a bug.
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
- Added `GLFW_FEATURE_UNAVAILABLE` error for platform limitations (#1692)
- Added `GLFW_FEATURE_UNIMPLEMENTED` error for incomplete backends (#1692)
- Added `GLFW_ANGLE_PLATFORM_TYPE` init hint and `GLFW_ANGLE_PLATFORM_TYPE_*`
values to select ANGLE backend (#1380)
- Updated the minimum required CMake version to 3.1
- Disabled tests and examples by default when built as a CMake subdirectory
- Bugfix: The CMake config-file package used an absolute path and was not
Expand Down Expand Up @@ -195,6 +197,8 @@ information on what to include when reporting a bug.
macOS versions (#1442)
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
- [EGL] Added platform selection via the `EGL_EXT_platform_base` extension
- [EGL] Added ANGLE backend selection via `EGL_ANGLE_platform_angle` extension
(#1380)


## Contact
Expand Down
23 changes: 18 additions & 5 deletions docs/intro.dox
Expand Up @@ -93,6 +93,18 @@ __GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
buttons, for compatibility with earlier versions of GLFW that did not have @ref
glfwGetJoystickHats. Set this with @ref glfwInitHint.

@anchor GLFW_ANGLE_PLATFORM_TYPE_hint
__GLFW_ANGLE_PLATFORM_TYPE__ specifies the platform type (rendering backend) to
request when using OpenGL ES and EGL via
[ANGLE](https://chromium.googlesource.com/angle/angle/). If the requested
platform type is unavailable, ANGLE will use its default. Set this hint with
@ref glfwInitHint.

@par
The ANGLE platform type is specified via the `EGL_ANGLE_platform_angle`
extension. This extension is not used if this hint is
`GLFW_ANGLE_PLATFORM_TYPE_NONE`, which is the default value.


@subsubsection init_hints_osx macOS specific init hints

Expand All @@ -109,11 +121,12 @@ a nib or manually by GLFW. Set this with @ref glfwInitHint.

@subsubsection init_hints_values Supported and default values

Initialization hint | Default value | Supported values
------------------------------- | ------------- | ----------------
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
Initialization hint | Default value | Supported values
------------------------------- | ------------------------------- | ----------------
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_ANGLE_PLATFORM_TYPE | `GLFW_ANGLE_PLATFORM_TYPE_NONE` | `GLFW_ANGLE_PLATFORM_TYPE_NONE`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGL`, `GLFW_ANGLE_PLATFORM_TYPE_OPENGLES`, `GLFW_ANGLE_PLATFORM_TYPE_D3D9`, `GLFW_ANGLE_PLATFORM_TYPE_D3D11`, `GLFW_ANGLE_PLATFORM_TYPE_VULKAN` or `GLFW_ANGLE_PLATFORM_TYPE_METAL`
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`


@subsection intro_init_terminate Terminating GLFW
Expand Down
17 changes: 17 additions & 0 deletions docs/news.dox
Expand Up @@ -27,6 +27,15 @@ are still available.
For more information see @ref cursor_standard.


@subsubsection features_34_angle_backend Support for ANGLE rendering backend selection

GLFW now provides the
[GLFW_ANGLE_PLATFORM_TYPE](@ref GLFW_ANGLE_PLATFORM_TYPE_hint) init hint for
requesting a specific rendering backend when using
[ANGLE](https://chromium.googlesource.com/angle/angle/) to create OpenGL ES
contexts.


@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu

GLFW now provides the
Expand Down Expand Up @@ -94,6 +103,14 @@ then GLFW will fail to initialize.
- @ref GLFW_CONTEXT_DEBUG
- @ref GLFW_FEATURE_UNAVAILABLE
- @ref GLFW_FEATURE_UNIMPLEMENTED
- @ref GLFW_ANGLE_PLATFORM_TYPE
- @ref GLFW_ANGLE_PLATFORM_TYPE_NONE
- @ref GLFW_ANGLE_PLATFORM_TYPE_OPENGL
- @ref GLFW_ANGLE_PLATFORM_TYPE_OPENGLES
- @ref GLFW_ANGLE_PLATFORM_TYPE_D3D9
- @ref GLFW_ANGLE_PLATFORM_TYPE_D3D11
- @ref GLFW_ANGLE_PLATFORM_TYPE_VULKAN
- @ref GLFW_ANGLE_PLATFORM_TYPE_METAL


@section news_archive Release notes for earlier versions
Expand Down
13 changes: 13 additions & 0 deletions include/GLFW/glfw3.h
Expand Up @@ -1104,6 +1104,14 @@ extern "C" {
#define GLFW_EGL_CONTEXT_API 0x00036002
#define GLFW_OSMESA_CONTEXT_API 0x00036003

#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003
#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004
#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008

/*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes.
*
Expand Down Expand Up @@ -1220,6 +1228,11 @@ extern "C" {
* Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS).
*/
#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
/*! @brief ANGLE rendering backend init hint.
*
* ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint).
*/
#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002
/*! @brief macOS specific init hint.
*
* macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).
Expand Down
28 changes: 27 additions & 1 deletion src/cocoa_window.m
Expand Up @@ -1721,8 +1721,34 @@ void _glfwPlatformSetClipboardString(const char* string)
} // autoreleasepool
}

EGLenum _glfwPlatformGetEGLPlatform(void)
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
{
if (_glfw.egl.ANGLE_platform_angle)
{
int type = 0;

if (_glfw.egl.ANGLE_platform_angle_opengl)
{
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL)
type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
}

if (_glfw.egl.ANGLE_platform_angle_metal)
{
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_METAL)
type = EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
}

if (type)
{
*attribs = calloc(3, sizeof(EGLint));
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
(*attribs)[1] = type;
(*attribs)[2] = EGL_NONE;
return EGL_PLATFORM_ANGLE_ANGLE;
}
}

return 0;
}

Expand Down
21 changes: 18 additions & 3 deletions src/egl_context.c
Expand Up @@ -303,6 +303,7 @@ static void destroyContextEGL(_GLFWwindow* window)
GLFWbool _glfwInitEGL(void)
{
int i;
EGLint* attribs = NULL;
const char* extensions;
const char* sonames[] =
{
Expand Down Expand Up @@ -408,6 +409,16 @@ GLFWbool _glfwInitEGL(void)
_glfwStringInExtensionString("EGL_EXT_platform_x11", extensions);
_glfw.egl.EXT_platform_wayland =
_glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions);
_glfw.egl.ANGLE_platform_angle =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle", extensions);
_glfw.egl.ANGLE_platform_angle_opengl =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_opengl", extensions);
_glfw.egl.ANGLE_platform_angle_d3d =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_d3d", extensions);
_glfw.egl.ANGLE_platform_angle_vulkan =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
_glfw.egl.ANGLE_platform_angle_metal =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
}

if (_glfw.egl.EXT_platform_base)
Expand All @@ -418,17 +429,19 @@ GLFWbool _glfwInitEGL(void)
eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
}

_glfw.egl.platform = _glfwPlatformGetEGLPlatform();
_glfw.egl.platform = _glfwPlatformGetEGLPlatform(&attribs);
if (_glfw.egl.platform)
{
_glfw.egl.display =
eglGetPlatformDisplayEXT(_glfw.egl.platform,
_glfwPlatformGetEGLNativeDisplay(),
NULL);
attribs);
}
else
_glfw.egl.display = eglGetDisplay(_glfwPlatformGetEGLNativeDisplay());

free(attribs);

if (_glfw.egl.display == EGL_NO_DISPLAY)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
Expand Down Expand Up @@ -633,7 +646,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
setAttrib(EGL_NONE, EGL_NONE);

native = _glfwPlatformGetEGLNativeWindow(window);
if (_glfw.egl.platform)
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
// despite reporting EGL_EXT_platform_base
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
{
window->context.egl.surface =
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
Expand Down
14 changes: 14 additions & 0 deletions src/egl_context.h
Expand Up @@ -92,6 +92,15 @@
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
#define EGL_PLATFORM_X11_EXT 0x31d5
#define EGL_PLATFORM_WAYLAND_EXT 0x31d8
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320e
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f

typedef int EGLint;
typedef unsigned int EGLBoolean;
Expand Down Expand Up @@ -173,6 +182,11 @@ typedef struct _GLFWlibraryEGL
GLFWbool EXT_platform_base;
GLFWbool EXT_platform_x11;
GLFWbool EXT_platform_wayland;
GLFWbool ANGLE_platform_angle;
GLFWbool ANGLE_platform_angle_opengl;
GLFWbool ANGLE_platform_angle_d3d;
GLFWbool ANGLE_platform_angle_vulkan;
GLFWbool ANGLE_platform_angle_metal;

void* handle;

Expand Down
4 changes: 4 additions & 0 deletions src/init.c
Expand Up @@ -53,6 +53,7 @@ static GLFWerrorfun _glfwErrorCallback;
static _GLFWinitconfig _glfwInitHints =
{
GLFW_TRUE, // hat buttons
GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
{
GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir
Expand Down Expand Up @@ -287,6 +288,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
case GLFW_JOYSTICK_HAT_BUTTONS:
_glfwInitHints.hatButtons = value;
return;
case GLFW_ANGLE_PLATFORM_TYPE:
_glfwInitHints.angleType = value;
return;
case GLFW_COCOA_CHDIR_RESOURCES:
_glfwInitHints.ns.chdir = value;
return;
Expand Down
3 changes: 2 additions & 1 deletion src/internal.h
Expand Up @@ -243,6 +243,7 @@ struct _GLFWerror
struct _GLFWinitconfig
{
GLFWbool hatButtons;
int angleType;
struct {
GLFWbool menubar;
GLFWbool chdir;
Expand Down Expand Up @@ -684,7 +685,7 @@ void _glfwPlatformWaitEvents(void);
void _glfwPlatformWaitEventsTimeout(double timeout);
void _glfwPlatformPostEmptyEvent(void);

EGLenum _glfwPlatformGetEGLPlatform(void);
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs);
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void);
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window);

Expand Down
38 changes: 37 additions & 1 deletion src/win32_window.c
Expand Up @@ -2186,8 +2186,44 @@ const char* _glfwPlatformGetClipboardString(void)
return _glfw.win32.clipboardString;
}

EGLenum _glfwPlatformGetEGLPlatform(void)
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
{
if (_glfw.egl.ANGLE_platform_angle)
{
int type = 0;

if (_glfw.egl.ANGLE_platform_angle_opengl)
{
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL)
type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGLES)
type = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
}

if (_glfw.egl.ANGLE_platform_angle_d3d)
{
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D9)
type = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
else if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_D3D11)
type = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
}

if (_glfw.egl.ANGLE_platform_angle_vulkan)
{
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_VULKAN)
type = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
}

if (type)
{
*attribs = calloc(3, sizeof(EGLint));
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
(*attribs)[1] = type;
(*attribs)[2] = EGL_NONE;
return EGL_PLATFORM_ANGLE_ANGLE;
}
}

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/wl_window.c
Expand Up @@ -1684,7 +1684,7 @@ const char* _glfwPlatformGetClipboardString(void)
return _glfw.wl.clipboardString;
}

EGLenum _glfwPlatformGetEGLPlatform(void)
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
{
if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland)
return EGL_PLATFORM_WAYLAND_EXT;
Expand Down
34 changes: 31 additions & 3 deletions src/x11_window.c
Expand Up @@ -3048,12 +3048,40 @@ const char* _glfwPlatformGetClipboardString(void)
return getSelectionString(_glfw.x11.CLIPBOARD);
}

EGLenum _glfwPlatformGetEGLPlatform(void)
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
{
if (_glfw.egl.ANGLE_platform_angle)
{
int type = 0;

if (_glfw.egl.ANGLE_platform_angle_opengl)
{
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL)
type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
}

if (_glfw.egl.ANGLE_platform_angle_vulkan)
{
if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_VULKAN)
type = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
}

if (type)
{
*attribs = calloc(5, sizeof(EGLint));
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
(*attribs)[1] = type;
(*attribs)[2] = EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE;
(*attribs)[3] = EGL_PLATFORM_X11_EXT;
(*attribs)[4] = EGL_NONE;
return EGL_PLATFORM_ANGLE_ANGLE;
}
}

if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_x11)
return EGL_PLATFORM_X11_EXT;
else
return 0;

return 0;
}

EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void)
Expand Down

0 comments on commit 0dea8a4

Please sign in to comment.