diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 26a2936a..506448cb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -291,6 +291,7 @@ video tutorials. - Jonas Ådahl - Lasse Öörni - Leonard König + - Tianlan Zhou - All the unmentioned and anonymous contributors in the GLFW community, for bug reports, patches, feedback, testing and encouragement diff --git a/README.md b/README.md index 787560a6..636ddedb 100644 --- a/README.md +++ b/README.md @@ -205,6 +205,7 @@ information on what to include when reporting a bug. (#442) - [EGL] Added ANGLE backend selection via `EGL_ANGLE_platform_angle` extension (#1380) + - Added `GLFW_ACCELERATION` window hint for hardware acceleration (#TODO) ## Changelog since 3.3 diff --git a/docs/news.md b/docs/news.md index 2eefc1b9..db3b3928 100644 --- a/docs/news.md +++ b/docs/news.md @@ -141,6 +141,16 @@ contexts. [ANGLE]: https://chromium.googlesource.com/angle/angle/ +#### Window hint for hardware acceleration {#acceleration_34} + +You can use window hint [GLFW_ACCELERATION](@ref GLFW_ACCELERATION_hint) to +specify whether hardware acceleration is preferred or not. The default value +is to prefer hardware acceleration. You can get whether hardware acceleration +is enabled with the window attribute +[GLFW_ACCELERATION](@ref GLFW_ACCELERATION_attrib). This feature is only +available on WGL currently. + + ### Caveats for version 3.4 {#caveats} #### Multiple sets of native access functions {#native_34} @@ -227,6 +237,13 @@ Events posted with @ref glfwPostEmptyEvent now use a separate unnamed pipe instead of sending an X11 client event to the helper window. +#### Microsoft GDI software OpenGL ICD support {#gdi_opengl_icd_34} + +GLFW now supports creating window when the Microsoft GDI software OpenGL ICD is +the only available implementation. +See [GLFW_ACCELERATION](@ref GLFW_ACCELERATION_hint) for more details. + + ### Deprecations in version 3.4 {#deprecations_34} ### Removals in 3.4 {#removals_34} @@ -322,6 +339,7 @@ then GLFW will fail to initialize. - @ref GLFW_WAYLAND_PREFER_LIBDECOR - @ref GLFW_WAYLAND_DISABLE_LIBDECOR - @ref GLFW_SCALE_FRAMEBUFFER + - @ref GLFW_ACCELERATION ## Release notes for earlier versions {#news_archive} diff --git a/docs/window.md b/docs/window.md index 371baa56..45601a67 100644 --- a/docs/window.md +++ b/docs/window.md @@ -336,6 +336,15 @@ __GLFW_DOUBLEBUFFER__ specifies whether the framebuffer should be double buffered. You nearly always want to use double buffering. This is a hard constraint. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. +@anchor GLFW_ACCELERATION +@anchor GLFW_ACCELERATION_hint +__GLFW_ACCELERATION__ specifies whether the hardware acceleration should be +preferred. By default, hardware acceleration is preferred, and will fallback +to no acceleration if hardware acceleration is unavailable. Possible values +are `GLFW_TRUE` and `GLFW_FALSE`. + +This hint only has an effect on WGL. + #### Monitor related hints {#window_hints_mtr} @@ -1487,6 +1496,11 @@ __GLFW_DOUBLEBUFFER__ indicates whether the specified window is double-buffered when rendering with OpenGL or OpenGL ES. This can be set before creation with the [GLFW_DOUBLEBUFFER](@ref GLFW_DOUBLEBUFFER_hint) window hint. +@anchor GLFW_ACCELERATION_attrib +__GLFW_ACCELERATION__ indicates whether the specified window is hardware +accelerated when rendering with OpenGL or OpenGL ES. This can be set before +creation with the [GLFW_ACCELERATION](@ref GLFW_ACCELERATION_hint) window hint. + ## Buffer swapping {#buffer_swap} diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 9c55ac9d..f1dc891c 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1022,6 +1022,14 @@ extern "C" { * [attribute](@ref GLFW_DOUBLEBUFFER_attrib). */ #define GLFW_DOUBLEBUFFER 0x00021010 +/*! @brief Hardware acceleration hint. + * + * Hardware acceleration [hint](@ref GLFW_ACCELERATION_hint) and + * [attribute](@ref GLFW_ACCELERATION_attrib). + * + * @since Added in version 3.4. + */ +#define GLFW_ACCELERATION 0x00021011 /*! @brief Context client API hint and attribute. * @@ -3158,9 +3166,6 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * - * @remark @win32 Window creation will fail if the Microsoft GDI software - * OpenGL implementation is the only one available. - * * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it * will be set as the initial icon for the window. If no such icon is present, * the `IDI_APPLICATION` icon will be used instead. To set a different icon, diff --git a/src/context.c b/src/context.c index cc1fac4f..dc69796d 100644 --- a/src/context.c +++ b/src/context.c @@ -312,6 +312,9 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, if (desired->sRGB && !current->sRGB) extraDiff++; + + if (desired->acceleration && !current->acceleration) + extraDiff++; } // Figure out if the current one is better than the best one found so far diff --git a/src/internal.h b/src/internal.h index 24750adc..1b04c617 100644 --- a/src/internal.h +++ b/src/internal.h @@ -469,6 +469,7 @@ struct _GLFWfbconfig GLFWbool sRGB; GLFWbool doublebuffer; GLFWbool transparent; + GLFWbool acceleration; uintptr_t handle; }; @@ -529,6 +530,7 @@ struct _GLFWwindow GLFWbool shouldClose; void* userPointer; GLFWbool doublebuffer; + GLFWbool acceleration; GLFWvidmode videoMode; _GLFWmonitor* monitor; _GLFWcursor* cursor; diff --git a/src/wgl_context.c b/src/wgl_context.c index 8a23ffc4..24013d30 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -145,6 +145,8 @@ static int choosePixelFormatWGL(_GLFWwindow* window, { // Get pixel format attributes through "modern" extension + int acceleration; + if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc, pixelFormat, 0, attribCount, @@ -166,8 +168,7 @@ static int choosePixelFormatWGL(_GLFWwindow* window, if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) continue; - if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) - continue; + acceleration = FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB); if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer) continue; @@ -210,6 +211,10 @@ static int choosePixelFormatWGL(_GLFWwindow* window, u->sRGB = GLFW_TRUE; } } + + u->acceleration = + acceleration == WGL_GENERIC_ACCELERATION_ARB || + acceleration == WGL_FULL_ACCELERATION_ARB; } else { @@ -235,12 +240,6 @@ static int choosePixelFormatWGL(_GLFWwindow* window, continue; } - if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && - (pfd.dwFlags & PFD_GENERIC_FORMAT)) - { - continue; - } - if (pfd.iPixelType != PFD_TYPE_RGBA) continue; @@ -264,6 +263,10 @@ static int choosePixelFormatWGL(_GLFWwindow* window, if (pfd.dwFlags & PFD_STEREO) u->stereo = GLFW_TRUE; + + u->acceleration = + (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || + !(pfd.dwFlags & PFD_GENERIC_FORMAT); } u->handle = pixelFormat; @@ -437,8 +440,6 @@ GLFWbool _glfwInitWGL(void) // NOTE: A dummy context has to be created for opengl32.dll to load the // OpenGL ICD, from which we can then query WGL extensions - // NOTE: This code will accept the Microsoft GDI ICD; accelerated context - // creation failure occurs during manual pixel format enumeration dc = GetDC(_glfw.win32.helperWindowHandle); diff --git a/src/window.c b/src/window.c index 1463d169..31753297 100644 --- a/src/window.c +++ b/src/window.c @@ -235,6 +235,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->cursorMode = GLFW_CURSOR_NORMAL; window->doublebuffer = fbconfig.doublebuffer; + window->acceleration = fbconfig.acceleration; window->minwidth = GLFW_DONT_CARE; window->minheight = GLFW_DONT_CARE; @@ -287,6 +288,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.framebuffer.depthBits = 24; _glfw.hints.framebuffer.stencilBits = 8; _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE; + _glfw.hints.framebuffer.acceleration = GLFW_TRUE; // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; @@ -346,6 +348,9 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_SRGB_CAPABLE: _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_ACCELERATION: + _glfw.hints.framebuffer.acceleration = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_RESIZABLE: _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE; return; @@ -897,6 +902,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) return window->autoIconify; case GLFW_DOUBLEBUFFER: return window->doublebuffer; + case GLFW_ACCELERATION: + return window->acceleration; case GLFW_CLIENT_API: return window->context.client; case GLFW_CONTEXT_CREATION_API: