Hi Everybody,
I’ve noticed an interesting behavior of swap interval and glGerError. If the swap interval is set to N then the frame rate drops to around 1/N fps. Except if glGetError is invoked in the rendering loop because then everything works as it supposed to, frame rate is MonitorRefreshRate/N fps.
Here is a scoped down example, repetitively fade the background color to white and to black in 1-1 seconds.
- If swap interval is 0 (or not set at all) then runs at very high fps as expected regardless if errors are checked or not.
- If swap interval is N and errors are checked then runs at MonitorRefreshRate/N fps.
- If swap interval is N and errors are NOT checked then runs at 1/N fps. Why?
Example:
#include <GLFW/glfw3.h>
#include <iostream>
int main()
{
// GLFW: initialize and configure
if (!glfwInit()) {
std::cerr << "ERROR: Failed to initialize GLFW" << std::endl;
return -1;
}
// Create OpenGL context and window
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // version is not particularly important
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // same with e.g. 3.3
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif // __APPLE__
// GLFW window creation
GLFWwindow* window = glfwCreateWindow(400, 400, "GLFW window", NULL, NULL);
if (!window) {
std::cerr << "ERROR: Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Enable V-Sync on every Nth refresh (Hz/N fps, 0=no synchronization)
glfwSwapInterval(1);
// render loop
int frameIdx = 0;
while (!glfwWindowShouldClose(window))
{
std::cout << "Frame " << frameIdx++ << std::endl;
float BW = abs(fmod((float)glfwGetTime(), 2.0f) - 1.0f);
// render
glClearColor(BW, BW, BW, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
glfwSwapBuffers(window);
glfwPollEvents();
// Why glGetError eliminate jittering when swap interval is set to non-zero?
// Fraps (www.fraps.com) application also eliminate it without glGetError.
int err = glGetError();
if (err)
std::cerr << "GL error " << err << std::endl;
}
// terminate, clearing all previously allocated GLFW resources.
glfwTerminate();
return 0;
}
I suspect a driver error since this issue is present on a HP Elitebook 850 G5, Intel Core i5 8350U, Intel HD Graphics 620 (driver 24.20.100.6226, newer is available but I’m not allowed update it), up-to-date Windows 10 x64, built in screen only with display scaling 125%.
The issue is not present on another HP Probook 4330s, Intel Core i5 2450M, AMD Radeon 7470M (driver 15.7.1, latest supported), up-to-date Windows 7 x64, built in screen only without display scaling, Aero.
I use latest Visual Studio 2017 (15.9.9), GLFW 3.2.1 on both systems and have tried x86/x64, debug/release versions too.
Interestingly if Fraps (www.fraps.com) is running then the issue doesn’t appear.
Did anybody see this before? Is there any explanation or solution for it?