Request involving ANGLE support and questions about the Hints system

I see that SDL2 currently supports using ANGLE for OpenGL ES, which is great for what I want to do. One thing I’d like to do with ANGLE is be able to specify which backend to use (D3D, OpenGL, Vulkan, etc.). ANGLE provides a way of specifying it via an EGL extension for eglGetPlatformDisplay(EXT), but it’s currently not used for ANGLE support in SDL2.

I already wrote a change for SDL2 that implements this control via an SDL Hint. The hint is set to the number of the EGL_PLATFORM_ANGLE_TYPE_ANGLE attribute value (eg. "0x3208" for D3D11, "0x3450" for Vulkan, etc.) to avoid having to hardcode all the possible attribute values, which also makes it forwards-compatible to any new backends that get added to ANGLE. However, my current implementation is a bit messy currently, and doesn’t have any real error handling. Before I clean it up and submit the patch (somehow), I had some questions about how implementing Hints should work.

The hint for specifying an ANGLE backend is highly correlated with SDL_HINT_OPENGL_ES_DRIVER, as specifying that you want a specific backend implies that you want to use ANGLE, and therefore SDL_HINT_OPENGL_ES_DRIVER should be "true" / "1". Because of the valid possible values for the ANGLE attribute, it’s possible to extend the existing hint to also handle specifying the ANGLE backend, but I get the feeling that is not something that the SDL developers / maintainers want. The other option is to keep them separate, but then the question is whether to have the new hint also imply the old hint (i.e. any check for the SDL_HINT_OPENGL_ES_DRIVER Hint will also check the new hint). What is the best way to go about this?

I’m also not sure how the Hints system should handle failures. Checking whether the hint can be applied is simple, as it’s just a matter of checking if the EGL implementation has the extension EGL_ANGLE_platform_angle. However, I’m not sure what should be done if the Hint is set, but the extension isn’t available. Should it be a hard failure (i.e. return that a context could not be created) or should it ignore the Hint if it’s not applicable (i.e. continue creating the context as if the Hint was never set)? A soft failure could create confusion, as it wouldn’t be able to indicate if the Hint is actually doing anything, but a hard failure could also be “wrong” for a Hint.

What do you all think about this?

1 Like

ANGLE_DEFAULT_PLATFORM?

ANGLE_DEFAULT_PLATFORM unfortunately does not support every backend (currently).

@LRFLEW I really like this idea, and have been looking for something like this.

As a note: It’s possible this could also work as a new SDL_GLattr.

While you can set most OpenGL attributes normally, the attributes listed above must be known before SDL creates the window that will be used with the OpenGL context. These attributes are set and read with SDL_GL_SetAttribute() and SDL_GL_GetAttribute().

So something like:

SDL_GL_SetAttribute(SDL_GL_ANGLE_PLATFORM_TYPE, < the actual EGL_PLATFORM_ANGLE_TYPE_ANGLE value, ex: 0x3208 >);

But I’m not averse to it being a Hint. I’m just eager to see the functionality!

From a use-case point of view, I would like the ability for it to “hard-fail” though. Thus letting a game try again with a different setting.

@Charles_Huber ANGLE_DEFAULT_PLATFORM, even if it wasn’t lacking backends, is a pretty poor solution to the problem. Environment variables are fine for something where the user specifies it on the command line when launching something, but a really messy option for an in-game drop-down setting. It’s also a soft-fail, both for when ANGLE isn’t being used and when the backend isn’t supported, which isn’t the best option.

@pastdue An SDL_GLattr sounds like a really good solution, honestly. I noticed that SDL_HINT_OPENGL_ES_DRIVER was a hint, so I had defaulted to that. An SDL_GLattr could work around the hard-fail semantics issue with hints, but it seems like there might be more scrutiny to adding one. If it is an SDL_GLattr, then it would still raise the question of whether setting the attr implies the hint, and the attr should have distinct values for “default OpenGL ES implementation” and “default backend for ANGLE implementation.”

@LRFLEW

Some thoughts on implementation:

  • A new SDL_GLattr: SDL_GL_PLATFORM_ANGLE_TYPE - specifies the desired libANGLE backend platform to use if the libANGLE library is loaded / used
  • Options would be:
/**
Any appropriate EGL_PLATFORM_ANGLE_TYPE_ANGLE defined by libANGLE (see: `angle/include/EGL/eglext_angle.h`)
Examples:
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
**/
  • Behavior: SDL attempts to use the specified EGL_PLATFORM_ANGLE_TYPE, falls back to whatever is available / the default. (Soft-fail)
  • SDL_GL_GetAttribute(SDL_GL_PLATFORM_ANGLE_TYPE,...) can be used to retrieve the actual / resulting EGL_PLATFORM_ANGLE_TYPE value, and thus can be used by SDL consumers to implement hard-fail behavior (if desired), as is currently the case with other SDL_GLattr options.
  • If libANGLE is not being used, SDL_GL_GetAttribute(SDL_GL_PLATFORM_ANGLE_TYPE,...) returns an appropriate negative error code.
  • The SDL_GLattr does not imply the SDL_HINT_OPENGL_ES_DRIVER hint.

To expand on the last bit:

  • To enable the option where a developer wishes to specify an Angle backend only if SDL decides to load libANGLE, it is necessary to not automatically set SDL_HINT_OPENGL_ES_DRIVER. (I’m not aware of any way to query in advance what SDL’s behavior is going to be when SDL_HINT_OPENGL_ES_DRIVER is the default 0 value.)
  • It can simply be documented that if you want to guarantee an OpenGL ES library is loaded, you should also set SDL_HINT_OPENGL_ES_DRIVER.