|
@@ -87,13 +87,21 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
|
|
//
|
|
|
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|
|
const _GLFWfbconfig* desired,
|
|
|
- EGLConfig* result)
|
|
|
+ EGLConfig* result,
|
|
|
+ GLFWbool findTransparent)
|
|
|
{
|
|
|
EGLConfig* nativeConfigs;
|
|
|
_GLFWfbconfig* usableConfigs;
|
|
|
const _GLFWfbconfig* closest;
|
|
|
int i, nativeCount, usableCount;
|
|
|
|
|
|
+#if defined(_GLFW_X11)
|
|
|
+ XVisualInfo visualTemplate = {0};
|
|
|
+ if ( !(_glfw.xrender.major || _glfw.xrender.minor) ) {
|
|
|
+ findTransparent = GLFW_FALSE;
|
|
|
+ }
|
|
|
+#endif // _GLFW_X11
|
|
|
+
|
|
|
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
|
|
|
if (!nativeCount)
|
|
|
{
|
|
@@ -107,6 +115,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|
|
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
|
|
usableCount = 0;
|
|
|
|
|
|
+selectionloop:
|
|
|
for (i = 0; i < nativeCount; i++)
|
|
|
{
|
|
|
const EGLConfig n = nativeConfigs[i];
|
|
@@ -122,8 +131,31 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|
|
|
|
|
#if defined(_GLFW_X11)
|
|
|
// Only consider EGLConfigs with associated Visuals
|
|
|
- if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
|
|
|
+ visualTemplate.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
|
|
|
+ if (!visualTemplate.visualid)
|
|
|
continue;
|
|
|
+
|
|
|
+ if( findTransparent ) {
|
|
|
+ int n_vi;
|
|
|
+ XVisualInfo *visualinfo;
|
|
|
+ XRenderPictFormat *pictFormat;
|
|
|
+
|
|
|
+ visualinfo = XGetVisualInfo(_glfw.x11.display, VisualIDMask, &visualTemplate, &n_vi);
|
|
|
+ if (!visualinfo)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual);
|
|
|
+ if( !pictFormat ) {
|
|
|
+ XFree( visualinfo );
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if( !pictFormat->direct.alphaMask ) {
|
|
|
+ XFree( visualinfo );
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ XFree( visualinfo );
|
|
|
+ }
|
|
|
#endif // _GLFW_X11
|
|
|
|
|
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
|
@@ -159,6 +191,12 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|
|
u->handle = (uintptr_t) n;
|
|
|
usableCount++;
|
|
|
}
|
|
|
+ // reiterate the selection loop without looking for transparency supporting
|
|
|
+ // formats if no matchig FB configs for a transparent window were found.
|
|
|
+ if( findTransparent && !usableCount ) {
|
|
|
+ findTransparent = GLFW_FALSE;
|
|
|
+ goto selectionloop;
|
|
|
+ }
|
|
|
|
|
|
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
|
|
if (closest)
|
|
@@ -455,7 +493,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|
|
if (ctxconfig->share)
|
|
|
share = ctxconfig->share->context.egl.handle;
|
|
|
|
|
|
- if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
|
|
|
+ if (!chooseEGLConfig(ctxconfig, fbconfig, &config, window->transparent))
|
|
|
{
|
|
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
|
|
"EGL: Failed to find a suitable EGLConfig");
|
|
@@ -689,7 +727,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|
|
// Returns the Visual and depth of the chosen EGLConfig
|
|
|
//
|
|
|
#if defined(_GLFW_X11)
|
|
|
-GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
|
|
+GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
|
|
+ const _GLFWctxconfig* ctxconfig,
|
|
|
const _GLFWfbconfig* fbconfig,
|
|
|
Visual** visual, int* depth)
|
|
|
{
|
|
@@ -699,7 +738,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
|
|
EGLint visualID = 0, count = 0;
|
|
|
const long vimask = VisualScreenMask | VisualIDMask;
|
|
|
|
|
|
- if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
|
|
|
+ if (!chooseEGLConfig(ctxconfig, fbconfig, &native, wndconfig->transparent))
|
|
|
{
|
|
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
|
|
"EGL: Failed to find a suitable EGLConfig");
|