mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 06:04:34 +00:00
Null: Add limited EGL context creation on Mesa
This provides very limited support for context creation via EGL on the Null platform. It supports Unix-like systems with a version of Mesa that provides EGL_MESA_platform_surfaceless. Even then, the actual framebuffer provided is not resized along with the 'window'. That will hopefully change once context and framebuffer creation are separated, but this commit should at least allow more applications than before to run on the Null platform.
This commit is contained in:
parent
860c8ef38f
commit
738dd6ff1d
@ -125,6 +125,7 @@ information on what to include when reporting a bug.
|
|||||||
the limit of the mouse button tokens to be reported (#2423)
|
the limit of the mouse button tokens to be reported (#2423)
|
||||||
- [Wayland] Bugfix: The fractional scaling related objects were not destroyed
|
- [Wayland] Bugfix: The fractional scaling related objects were not destroyed
|
||||||
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
|
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
|
||||||
|
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
@ -92,7 +92,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
EGLConfig* nativeConfigs;
|
EGLConfig* nativeConfigs;
|
||||||
_GLFWfbconfig* usableConfigs;
|
_GLFWfbconfig* usableConfigs;
|
||||||
const _GLFWfbconfig* closest;
|
const _GLFWfbconfig* closest;
|
||||||
int i, nativeCount, usableCount, apiBit;
|
int i, nativeCount, usableCount, apiBit, surfaceTypeBit;
|
||||||
GLFWbool wrongApiAvailable = GLFW_FALSE;
|
GLFWbool wrongApiAvailable = GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
@ -105,6 +105,11 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
else
|
else
|
||||||
apiBit = EGL_OPENGL_BIT;
|
apiBit = EGL_OPENGL_BIT;
|
||||||
|
|
||||||
|
if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
|
||||||
|
surfaceTypeBit = EGL_PBUFFER_BIT;
|
||||||
|
else
|
||||||
|
surfaceTypeBit = EGL_WINDOW_BIT;
|
||||||
|
|
||||||
if (fbconfig->stereo)
|
if (fbconfig->stereo)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
|
||||||
@ -133,8 +138,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
|
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Only consider window EGLConfigs
|
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & surfaceTypeBit))
|
||||||
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
@ -420,6 +424,8 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
|
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
|
||||||
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
|
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
|
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
|
||||||
|
_glfw.egl.CreatePbufferSurface = (PFN_eglCreatePbufferSurface)
|
||||||
|
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreatePbufferSurface");
|
||||||
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
|
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
|
||||||
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
|
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
|
||||||
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
|
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
|
||||||
@ -442,6 +448,7 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
!_glfw.egl.DestroySurface ||
|
!_glfw.egl.DestroySurface ||
|
||||||
!_glfw.egl.DestroyContext ||
|
!_glfw.egl.DestroyContext ||
|
||||||
!_glfw.egl.CreateWindowSurface ||
|
!_glfw.egl.CreateWindowSurface ||
|
||||||
|
!_glfw.egl.CreatePbufferSurface ||
|
||||||
!_glfw.egl.MakeCurrent ||
|
!_glfw.egl.MakeCurrent ||
|
||||||
!_glfw.egl.SwapBuffers ||
|
!_glfw.egl.SwapBuffers ||
|
||||||
!_glfw.egl.SwapInterval ||
|
!_glfw.egl.SwapInterval ||
|
||||||
@ -477,6 +484,8 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
|
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
|
||||||
_glfw.egl.ANGLE_platform_angle_metal =
|
_glfw.egl.ANGLE_platform_angle_metal =
|
||||||
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
|
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
|
||||||
|
_glfw.egl.MESA_platform_surfaceless =
|
||||||
|
_glfwStringInExtensionString("EGL_MESA_platform_surfaceless", extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.egl.EXT_platform_base)
|
if (_glfw.egl.EXT_platform_base)
|
||||||
@ -708,20 +717,36 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
_glfw.platform.getFramebufferSize(window, &width, &height);
|
||||||
|
|
||||||
|
SET_ATTRIB(EGL_WIDTH, width);
|
||||||
|
SET_ATTRIB(EGL_HEIGHT, height);
|
||||||
|
}
|
||||||
|
|
||||||
SET_ATTRIB(EGL_NONE, EGL_NONE);
|
SET_ATTRIB(EGL_NONE, EGL_NONE);
|
||||||
|
|
||||||
native = _glfw.platform.getEGLNativeWindow(window);
|
native = _glfw.platform.getEGLNativeWindow(window);
|
||||||
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
|
if (!_glfw.egl.platform || _glfw.egl.platform == EGL_PLATFORM_ANGLE_ANGLE)
|
||||||
// despite reporting EGL_EXT_platform_base
|
|
||||||
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
|
|
||||||
{
|
{
|
||||||
|
// HACK: Also use non-platform function for ANGLE, as it does not
|
||||||
|
// implement eglCreatePlatformWindowSurfaceEXT despite reporting
|
||||||
|
// support for EGL_EXT_platform_base
|
||||||
window->context.egl.surface =
|
window->context.egl.surface =
|
||||||
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
|
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
|
||||||
|
}
|
||||||
|
else if (_glfw.egl.platform == EGL_PLATFORM_SURFACELESS_MESA)
|
||||||
|
{
|
||||||
|
// HACK: Use a pbuffer surface as the default framebuffer
|
||||||
|
window->context.egl.surface =
|
||||||
|
eglCreatePbufferSurface(_glfw.egl.display, config, attribs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
window->context.egl.surface =
|
window->context.egl.surface =
|
||||||
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
|
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->context.egl.surface == EGL_NO_SURFACE)
|
if (window->context.egl.surface == EGL_NO_SURFACE)
|
||||||
|
@ -150,6 +150,9 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
|||||||
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
|
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
|
||||||
#define EGL_NO_CONTEXT ((EGLContext) 0)
|
#define EGL_NO_CONTEXT ((EGLContext) 0)
|
||||||
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
|
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
|
||||||
|
#define EGL_PBUFFER_BIT 0x0001
|
||||||
|
#define EGL_WIDTH 0x3057
|
||||||
|
#define EGL_HEIGHT 0x3056
|
||||||
|
|
||||||
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
|
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
|
||||||
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
|
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
|
||||||
@ -181,6 +184,7 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
|
|||||||
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
|
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
|
||||||
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
|
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
|
||||||
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
|
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
|
||||||
|
#define EGL_PLATFORM_SURFACELESS_MESA 0x31dd
|
||||||
|
|
||||||
typedef int EGLint;
|
typedef int EGLint;
|
||||||
typedef unsigned int EGLBoolean;
|
typedef unsigned int EGLBoolean;
|
||||||
@ -205,6 +209,7 @@ typedef EGLContext (APIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLCon
|
|||||||
typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
|
typedef EGLBoolean (APIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
|
||||||
typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
|
typedef EGLBoolean (APIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
|
||||||
typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
|
typedef EGLSurface (APIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
|
||||||
|
typedef EGLSurface (APIENTRY * PFN_eglCreatePbufferSurface)(EGLDisplay,EGLContext,const EGLint*);
|
||||||
typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
|
typedef EGLBoolean (APIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
|
||||||
typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
|
typedef EGLBoolean (APIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
|
||||||
typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
|
typedef EGLBoolean (APIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
|
||||||
@ -221,6 +226,7 @@ typedef GLFWglproc (APIENTRY * PFN_eglGetProcAddress)(const char*);
|
|||||||
#define eglDestroySurface _glfw.egl.DestroySurface
|
#define eglDestroySurface _glfw.egl.DestroySurface
|
||||||
#define eglDestroyContext _glfw.egl.DestroyContext
|
#define eglDestroyContext _glfw.egl.DestroyContext
|
||||||
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
|
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
|
||||||
|
#define eglCreatePbufferSurface _glfw.egl.CreatePbufferSurface
|
||||||
#define eglMakeCurrent _glfw.egl.MakeCurrent
|
#define eglMakeCurrent _glfw.egl.MakeCurrent
|
||||||
#define eglSwapBuffers _glfw.egl.SwapBuffers
|
#define eglSwapBuffers _glfw.egl.SwapBuffers
|
||||||
#define eglSwapInterval _glfw.egl.SwapInterval
|
#define eglSwapInterval _glfw.egl.SwapInterval
|
||||||
@ -813,6 +819,7 @@ struct _GLFWlibrary
|
|||||||
GLFWbool ANGLE_platform_angle_d3d;
|
GLFWbool ANGLE_platform_angle_d3d;
|
||||||
GLFWbool ANGLE_platform_angle_vulkan;
|
GLFWbool ANGLE_platform_angle_vulkan;
|
||||||
GLFWbool ANGLE_platform_angle_metal;
|
GLFWbool ANGLE_platform_angle_metal;
|
||||||
|
GLFWbool MESA_platform_surfaceless;
|
||||||
|
|
||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
@ -827,6 +834,7 @@ struct _GLFWlibrary
|
|||||||
PFN_eglDestroySurface DestroySurface;
|
PFN_eglDestroySurface DestroySurface;
|
||||||
PFN_eglDestroyContext DestroyContext;
|
PFN_eglDestroyContext DestroyContext;
|
||||||
PFN_eglCreateWindowSurface CreateWindowSurface;
|
PFN_eglCreateWindowSurface CreateWindowSurface;
|
||||||
|
PFN_eglCreatePbufferSurface CreatePbufferSurface;
|
||||||
PFN_eglMakeCurrent MakeCurrent;
|
PFN_eglMakeCurrent MakeCurrent;
|
||||||
PFN_eglSwapBuffers SwapBuffers;
|
PFN_eglSwapBuffers SwapBuffers;
|
||||||
PFN_eglSwapInterval SwapInterval;
|
PFN_eglSwapInterval SwapInterval;
|
||||||
|
@ -553,12 +553,15 @@ const char* _glfwGetClipboardStringNull(void)
|
|||||||
|
|
||||||
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
|
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
|
||||||
{
|
{
|
||||||
return 0;
|
if (_glfw.egl.EXT_platform_base && _glfw.egl.MESA_platform_surfaceless)
|
||||||
|
return EGL_PLATFORM_SURFACELESS_MESA;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
|
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return EGL_DEFAULT_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
|
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
|
||||||
|
Loading…
Reference in New Issue
Block a user