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.
This commit is contained in:
parent
682f1cf203
commit
d79056fc27
@ -160,6 +160,8 @@ information on what to include when reporting a bug.
|
||||
(#749,#842)
|
||||
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
|
||||
- Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946)
|
||||
- Added `GLFW_CONTEXT_RENDERER` window hint and `GLFW_HARDWARE_RENDERER` and
|
||||
`GLFW_SOFTWARE_RENDERER` hint values (#589)
|
||||
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
|
||||
- Added macOS specific `GLFW_COCOA_FRAME_AUTOSAVE` window hint (#195)
|
||||
- Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935)
|
||||
|
@ -339,6 +339,11 @@ the selected API.
|
||||
in a single process will cause the application to segfault. Stick to one API or
|
||||
the other on Linux for now.
|
||||
|
||||
@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_MINOR_hint
|
||||
__GLFW_CONTEXT_VERSION_MAJOR__ and __GLFW_CONTEXT_VERSION_MINOR__ specify the
|
||||
@ -496,6 +501,7 @@ GLFW_SRGB_CAPABLE | `GLFW_FALSE` | `GLFW_TRUE` or `GL
|
||||
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_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_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`
|
||||
|
@ -962,6 +962,7 @@ extern "C" {
|
||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||
*/
|
||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||
#define GLFW_CONTEXT_RENDERER 0x0002200C
|
||||
|
||||
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
||||
#define GLFW_COCOA_FRAME_AUTOSAVE 0x00023002
|
||||
@ -997,6 +998,9 @@ extern "C" {
|
||||
#define GLFW_EGL_CONTEXT_API 0x00036002
|
||||
#define GLFW_OSMESA_CONTEXT_API 0x00036003
|
||||
|
||||
#define GLFW_HARDWARE_RENDERER 0x00037001
|
||||
#define GLFW_SOFTWARE_RENDERER 0x00037002
|
||||
|
||||
/*! @defgroup shapes Standard cursor shapes
|
||||
* @brief Standard system cursor shapes.
|
||||
*
|
||||
|
@ -50,6 +50,15 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
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 &&
|
||||
ctxconfig->client != GLFW_OPENGL_API &&
|
||||
ctxconfig->client != GLFW_OPENGL_ES_API)
|
||||
|
@ -460,6 +460,9 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->renderer == GLFW_SOFTWARE_RENDERER)
|
||||
setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (!_glfw.glx.ARB_create_context ||
|
||||
|
@ -330,6 +330,7 @@ struct _GLFWctxconfig
|
||||
int profile;
|
||||
int robustness;
|
||||
int release;
|
||||
int renderer;
|
||||
_GLFWwindow* share;
|
||||
struct {
|
||||
GLFWbool offline;
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <OpenGL/CGLRenderers.h>
|
||||
|
||||
|
||||
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
||||
{
|
||||
@ -165,9 +167,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
NSOpenGLPixelFormatAttribute attribs[40];
|
||||
int index = 0;
|
||||
|
||||
addAttrib(NSOpenGLPFAAccelerated);
|
||||
addAttrib(NSOpenGLPFAClosestPolicy);
|
||||
|
||||
if (ctxconfig->renderer == GLFW_HARDWARE_RENDERER)
|
||||
{
|
||||
addAttrib(NSOpenGLPFAAccelerated);
|
||||
}
|
||||
else if (ctxconfig->renderer == GLFW_SOFTWARE_RENDERER)
|
||||
{
|
||||
setAttrib(NSOpenGLPFARendererID, kCGLRendererGenericFloatID);
|
||||
}
|
||||
|
||||
if (ctxconfig->nsgl.offline)
|
||||
{
|
||||
addAttrib(NSOpenGLPFAAllowOfflineRenderers);
|
||||
|
@ -100,10 +100,21 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) ==
|
||||
WGL_NO_ACCELERATION_ARB)
|
||||
if (ctxconfig->renderer == GLFW_HARDWARE_RENDERER)
|
||||
{
|
||||
continue;
|
||||
if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) ==
|
||||
WGL_NO_ACCELERATION_ARB)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (ctxconfig->renderer == GLFW_SOFTWARE_RENDERER)
|
||||
{
|
||||
if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) !=
|
||||
WGL_NO_ACCELERATION_ARB)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB);
|
||||
@ -170,10 +181,21 @@ static int choosePixelFormat(_GLFWwindow* window,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
|
||||
(pfd.dwFlags & PFD_GENERIC_FORMAT))
|
||||
if (ctxconfig->renderer == GLFW_HARDWARE_RENDERER)
|
||||
{
|
||||
continue;
|
||||
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
|
||||
(pfd.dwFlags & PFD_GENERIC_FORMAT))
|
||||
{
|
||||
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)
|
||||
|
12
src/window.c
12
src/window.c
@ -239,10 +239,11 @@ void glfwDefaultWindowHints(void)
|
||||
|
||||
// The default is OpenGL with minimum version 1.0
|
||||
memset(&_glfw.hints.context, 0, sizeof(_glfw.hints.context));
|
||||
_glfw.hints.context.client = GLFW_OPENGL_API;
|
||||
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
|
||||
_glfw.hints.context.major = 1;
|
||||
_glfw.hints.context.minor = 0;
|
||||
_glfw.hints.context.client = GLFW_OPENGL_API;
|
||||
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
|
||||
_glfw.hints.context.renderer = GLFW_HARDWARE_RENDERER;
|
||||
_glfw.hints.context.major = 1;
|
||||
_glfw.hints.context.minor = 0;
|
||||
|
||||
// The default is a focused, visible, resizable window with decorations
|
||||
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
|
||||
@ -364,6 +365,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
case GLFW_CONTEXT_CREATION_API:
|
||||
_glfw.hints.context.source = value;
|
||||
return;
|
||||
case GLFW_CONTEXT_RENDERER:
|
||||
_glfw.hints.context.renderer = value;
|
||||
return;
|
||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||
_glfw.hints.context.major = value;
|
||||
return;
|
||||
|
@ -54,6 +54,9 @@
|
||||
#define BEHAVIOR_NAME_NONE "none"
|
||||
#define BEHAVIOR_NAME_FLUSH "flush"
|
||||
|
||||
#define RENDERER_NAME_HW "hw"
|
||||
#define RENDERER_NAME_SW "sw"
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
printf("Usage: glfwinfo [OPTION]...\n");
|
||||
@ -68,6 +71,9 @@ static void usage(void)
|
||||
API_NAME_NATIVE " or "
|
||||
API_NAME_EGL " or "
|
||||
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(" -f, --forward require a forward-compatible context\n");
|
||||
printf(" -h, --help show this help\n");
|
||||
@ -365,7 +371,8 @@ int main(int argc, char** argv)
|
||||
GLenum error;
|
||||
GLFWwindow* window;
|
||||
|
||||
enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
|
||||
enum { CLIENT, CONTEXT, RENDERER, BEHAVIOR, DEBUG, FORWARD,
|
||||
HELP, EXTENSIONS, LAYERS,
|
||||
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
||||
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
||||
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
||||
@ -375,6 +382,7 @@ int main(int argc, char** argv)
|
||||
{ "behavior", 1, NULL, BEHAVIOR },
|
||||
{ "client-api", 1, NULL, CLIENT },
|
||||
{ "context-api", 1, NULL, CONTEXT },
|
||||
{ "renderer", 1, NULL, RENDERER },
|
||||
{ "debug", 0, NULL, DEBUG },
|
||||
{ "forward", 0, NULL, FORWARD },
|
||||
{ "help", 0, NULL, HELP },
|
||||
@ -464,6 +472,17 @@ int main(int argc, char** argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
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 DEBUG:
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||
|
Loading…
Reference in New Issue
Block a user