Compare commits

..

4 Commits

Author SHA1 Message Date
HinTak
4502127c65
Merge 0ff9822c38 into b35641f4a3 2024-06-05 01:51:53 +00:00
Hin-Tak Leung
0ff9822c38 Slightly more readable code; completely equivalent 2024-06-05 02:51:46 +01:00
Hin-Tak Leung
00bc927d47 Merge branch 'context-renderer' of github.com:glfw/glfw into apple-software-renderer-retry 2024-06-05 01:15:48 +01:00
Camilla Löwy
d79056fc27 Add GLFW_CONTEXT_RENDERER
This window hint allows choosing between hardware and software renderers
(where available) for the created OpenGL or OpenGL ES context.

Fixes #589.
2017-12-11 21:14:16 +01:00
10 changed files with 95 additions and 13 deletions

View File

@ -132,6 +132,8 @@ information on what to include when reporting a bug.
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to - [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
`GLFW_NATIVE_CONTEXT_API` (#2518) `GLFW_NATIVE_CONTEXT_API` (#2518)
- Added `GLFW_CONTEXT_RENDERER` window hint and `GLFW_HARDWARE_RENDERER` and
`GLFW_SOFTWARE_RENDERER` hint values (#589)
## Contact ## Contact

View File

@ -375,6 +375,11 @@ does not update the window contents when its buffers are swapped. Use OpenGL
functions or the OSMesa native access functions @ref glfwGetOSMesaColorBuffer functions or the OSMesa native access functions @ref glfwGetOSMesaColorBuffer
and @ref glfwGetOSMesaDepthBuffer to retrieve the framebuffer contents. and @ref glfwGetOSMesaDepthBuffer to retrieve the framebuffer contents.
@anchor GLFW_CONTEXT_RENDERER_hint
__GLFW_CONTEXT_RENDERER__ specifies whether to create the context using
a hardware or software renderer, if that is possible to control on the current
platform.
@anchor GLFW_CONTEXT_VERSION_MAJOR_hint @anchor GLFW_CONTEXT_VERSION_MAJOR_hint
@anchor GLFW_CONTEXT_VERSION_MINOR_hint @anchor GLFW_CONTEXT_VERSION_MINOR_hint
__GLFW_CONTEXT_VERSION_MAJOR__ and __GLFW_CONTEXT_VERSION_MINOR__ specify the __GLFW_CONTEXT_VERSION_MAJOR__ and __GLFW_CONTEXT_VERSION_MINOR__ specify the
@ -566,6 +571,7 @@ GLFW_SRGB_CAPABLE | `GLFW_FALSE` | `GLFW_TRUE` or `GL
GLFW_DOUBLEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_DOUBLEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_CLIENT_API | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API` GLFW_CLIENT_API | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API`
GLFW_CONTEXT_CREATION_API | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API`, `GLFW_EGL_CONTEXT_API` or `GLFW_OSMESA_CONTEXT_API` GLFW_CONTEXT_CREATION_API | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API`, `GLFW_EGL_CONTEXT_API` or `GLFW_OSMESA_CONTEXT_API`
GLFW_CONTEXT_RENDERER | `GLFW_HARDWARE_RENDERER` | `GLFW_HARDWARE_RENDERER` or `GLFW_SOFTWARE_RENDERER`
GLFW_CONTEXT_VERSION_MAJOR | 1 | Any valid major version number of the chosen client API GLFW_CONTEXT_VERSION_MAJOR | 1 | Any valid major version number of the chosen client API
GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor version number of the chosen client API GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor version number of the chosen client API
GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`

View File

@ -1108,6 +1108,8 @@ extern "C" {
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for
* compatibility with earlier versions. * compatibility with earlier versions.
*/ */
#define GLFW_CONTEXT_RENDERER 0x0002200E
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 #define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
/*! @brief macOS specific /*! @brief macOS specific
* [window hint](@ref GLFW_COCOA_FRAME_NAME_hint). * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint).
@ -1180,6 +1182,9 @@ extern "C" {
#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001 #define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002 #define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
#define GLFW_HARDWARE_RENDERER 0x00039001
#define GLFW_SOFTWARE_RENDERER 0x00039002
#define GLFW_ANY_POSITION 0x80000000 #define GLFW_ANY_POSITION 0x80000000
/*! @defgroup shapes Standard cursor shapes /*! @defgroup shapes Standard cursor shapes

View File

@ -56,6 +56,15 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
return GLFW_FALSE; return GLFW_FALSE;
} }
if (ctxconfig->renderer != GLFW_HARDWARE_RENDERER &&
ctxconfig->renderer != GLFW_SOFTWARE_RENDERER)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context renderer 0x%08X",
ctxconfig->renderer);
return GLFW_FALSE;
}
if (ctxconfig->client != GLFW_NO_API && if (ctxconfig->client != GLFW_NO_API &&
ctxconfig->client != GLFW_OPENGL_API && ctxconfig->client != GLFW_OPENGL_API &&
ctxconfig->client != GLFW_OPENGL_ES_API) ctxconfig->client != GLFW_OPENGL_ES_API)

View File

@ -467,6 +467,9 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
if (ctxconfig->renderer == GLFW_SOFTWARE_RENDERER)
setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (ctxconfig->client == GLFW_OPENGL_ES_API)
{ {
if (!_glfw.glx.ARB_create_context || if (!_glfw.glx.ARB_create_context ||

View File

@ -449,6 +449,7 @@ struct _GLFWctxconfig
int profile; int profile;
int robustness; int robustness;
int release; int release;
int renderer;
_GLFWwindow* share; _GLFWwindow* share;
struct { struct {
GLFWbool offline; GLFWbool offline;

View File

@ -31,6 +31,8 @@
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#include <OpenGL/CGLRenderers.h>
static void makeContextCurrentNSGL(_GLFWwindow* window) static void makeContextCurrentNSGL(_GLFWwindow* window)
{ {
@ -228,9 +230,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
NSOpenGLPixelFormatAttribute attribs[40]; NSOpenGLPixelFormatAttribute attribs[40];
int index = 0; int index = 0;
ADD_ATTRIB(NSOpenGLPFAAccelerated);
ADD_ATTRIB(NSOpenGLPFAClosestPolicy); ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
if (ctxconfig->renderer == GLFW_HARDWARE_RENDERER)
{
ADD_ATTRIB(NSOpenGLPFAAccelerated);
}
else if (ctxconfig->renderer == GLFW_SOFTWARE_RENDERER)
{
SET_ATTRIB(NSOpenGLPFARendererID, kCGLRendererGenericFloatID);
}
if (ctxconfig->nsgl.offline) if (ctxconfig->nsgl.offline)
{ {
ADD_ATTRIB(NSOpenGLPFAAllowOfflineRenderers); ADD_ATTRIB(NSOpenGLPFAAllowOfflineRenderers);
@ -334,8 +344,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
// Re-try with Software Renderer // Re-try with Software Renderer
DELETE_ATTRIB(NSOpenGLPFAAccelerated); DELETE_ATTRIB(NSOpenGLPFAAccelerated);
DELETE_TERMINATING_NULL; // Unterminate. DELETE_TERMINATING_NULL; // Unterminate.
ADD_ATTRIB(NSOpenGLPFARendererID); SET_ATTRIB(NSOpenGLPFARendererID, kCGLRendererGenericFloatID);
ADD_ATTRIB(kCGLRendererGenericFloatID);
ADD_ATTRIB(0); // Re-terminate. ADD_ATTRIB(0); // Re-terminate.
window->context.nsgl.pixelFormat = window->context.nsgl.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];

View File

@ -166,8 +166,22 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
continue; continue;
if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) if (ctxconfig->renderer == GLFW_HARDWARE_RENDERER)
{
if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) ==
WGL_NO_ACCELERATION_ARB)
{
continue; continue;
}
}
else if (ctxconfig->renderer == GLFW_SOFTWARE_RENDERER)
{
if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) !=
WGL_NO_ACCELERATION_ARB)
{
continue;
}
}
if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer) if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
continue; continue;
@ -235,11 +249,22 @@ static int choosePixelFormatWGL(_GLFWwindow* window,
continue; continue;
} }
if (ctxconfig->renderer == GLFW_HARDWARE_RENDERER)
{
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
(pfd.dwFlags & PFD_GENERIC_FORMAT)) (pfd.dwFlags & PFD_GENERIC_FORMAT))
{ {
continue; continue;
} }
}
else if (ctxconfig->renderer == GLFW_SOFTWARE_RENDERER)
{
if ((pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
!(pfd.dwFlags & PFD_GENERIC_FORMAT))
{
continue;
}
}
if (pfd.iPixelType != PFD_TYPE_RGBA) if (pfd.iPixelType != PFD_TYPE_RGBA)
continue; continue;

View File

@ -261,6 +261,7 @@ void glfwDefaultWindowHints(void)
memset(&_glfw.hints.context, 0, sizeof(_glfw.hints.context)); memset(&_glfw.hints.context, 0, sizeof(_glfw.hints.context));
_glfw.hints.context.client = GLFW_OPENGL_API; _glfw.hints.context.client = GLFW_OPENGL_API;
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API; _glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
_glfw.hints.context.renderer = GLFW_HARDWARE_RENDERER;
_glfw.hints.context.major = 1; _glfw.hints.context.major = 1;
_glfw.hints.context.minor = 0; _glfw.hints.context.minor = 0;
@ -404,6 +405,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_CONTEXT_CREATION_API: case GLFW_CONTEXT_CREATION_API:
_glfw.hints.context.source = value; _glfw.hints.context.source = value;
return; return;
case GLFW_CONTEXT_RENDERER:
_glfw.hints.context.renderer = value;
return;
case GLFW_CONTEXT_VERSION_MAJOR: case GLFW_CONTEXT_VERSION_MAJOR:
_glfw.hints.context.major = value; _glfw.hints.context.major = value;
return; return;

View File

@ -71,6 +71,9 @@
#define PLATFORM_NAME_X11 "x11" #define PLATFORM_NAME_X11 "x11"
#define PLATFORM_NAME_NULL "null" #define PLATFORM_NAME_NULL "null"
#define RENDERER_NAME_HW "hw"
#define RENDERER_NAME_SW "sw"
static void usage(void) static void usage(void)
{ {
printf("Usage: glfwinfo [OPTION]...\n"); printf("Usage: glfwinfo [OPTION]...\n");
@ -92,6 +95,9 @@ static void usage(void)
API_NAME_NATIVE " or " API_NAME_NATIVE " or "
API_NAME_EGL " or " API_NAME_EGL " or "
API_NAME_OSMESA ")\n"); API_NAME_OSMESA ")\n");
printf(" --renderer=RENDERER the renderer to use ("
RENDERER_NAME_HW " or "
RENDERER_NAME_SW ")\n");
printf(" -d, --debug request a debug context\n"); printf(" -d, --debug request a debug context\n");
printf(" -f, --forward require a forward-compatible context\n"); printf(" -f, --forward require a forward-compatible context\n");
printf(" -h, --help show this help\n"); printf(" -h, --help show this help\n");
@ -384,7 +390,7 @@ int main(int argc, char** argv)
bool cocoa_graphics_switching = false; bool cocoa_graphics_switching = false;
bool disable_xcb_surface = false; bool disable_xcb_surface = false;
enum { PLATFORM, CLIENT, CONTEXT, BEHAVIOR, DEBUG_CONTEXT, FORWARD, HELP, enum { PLATFORM, CLIENT, CONTEXT, RENDERER, BEHAVIOR, DEBUG_CONTEXT, FORWARD, HELP,
EXTENSIONS, LAYERS, EXTENSIONS, LAYERS,
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION, MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS, REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
@ -397,6 +403,7 @@ int main(int argc, char** argv)
{ "behavior", 1, NULL, BEHAVIOR }, { "behavior", 1, NULL, BEHAVIOR },
{ "client-api", 1, NULL, CLIENT }, { "client-api", 1, NULL, CLIENT },
{ "context-api", 1, NULL, CONTEXT }, { "context-api", 1, NULL, CONTEXT },
{ "renderer", 1, NULL, RENDERER },
{ "debug", 0, NULL, DEBUG_CONTEXT }, { "debug", 0, NULL, DEBUG_CONTEXT },
{ "forward", 0, NULL, FORWARD }, { "forward", 0, NULL, FORWARD },
{ "help", 0, NULL, HELP }, { "help", 0, NULL, HELP },
@ -490,6 +497,17 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break; break;
case RENDERER:
if (strcasecmp(optarg, RENDERER_NAME_HW) == 0)
glfwWindowHint(GLFW_CONTEXT_RENDERER, GLFW_HARDWARE_RENDERER);
else if (strcasecmp(optarg, RENDERER_NAME_SW) == 0)
glfwWindowHint(GLFW_CONTEXT_RENDERER, GLFW_SOFTWARE_RENDERER);
else
{
usage();
exit(EXIT_FAILURE);
}
break;
case 'd': case 'd':
case DEBUG_CONTEXT: case DEBUG_CONTEXT:
context_debug = true; context_debug = true;