4

In this simple triangle drawing application made with opengl3.3 and sdl2, the cpu's usage shoots up to 50+% with vsync enabled. The vsync is enabled using SDL_GL_SetSwapInterval( 1 ). When i remove the vsync by setting the previous function to 0 and capped the fps to 60 manually in the main loop the cpu usage sits at around 5% average. What is the problem here? Am i misunderstanding something fundamental here? below is my code. (The vsync function is in the initialize() loop provided below).

Main file:

unsigned int triangle_Gen()
{
    float vertices[] = {
    -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
     0.0f,  0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
     0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)0); 
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float)));
    glEnableVertexAttribArray(1);

    return VAO;

}

int main(int argc, char* args[])
{
    float StartTicks = 0;
    float EndTicks = 0;
    float timeStep = 0;
    int fps = 0;
    float frameStartTime = 0;
    float frameEndTime = 0;
    float onesectime = 0;

    bool enableEditor = false;

    int editor_keyCount = 0;

    if(!initialize())
    {
        std::cout<<"Failed to initiate instance!!!"<<std::endl;
    }
    else
    {
        std::cout << glGetString(GL_VERSION) <<std::endl;
        int color_shaderProgram = Shaders("ShaderFiles/color_shader.vs","ShaderFiles/color_shader.fs"); 

        unsigned int triangle = triangle_Gen();

        glUseProgram(color_shaderProgram);
        glBindVertexArray(triangle);

    while(isRunning)
    {   
        SDL_GetWindowSize(window, &SCREEN_WIDTH, &SCREEN_HEIGHT);
        glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

        if(!enableEditor)
        {  SDL_SetRelativeMouseMode(SDL_TRUE); } //disable cursor
        else
        {  SDL_SetRelativeMouseMode(SDL_FALSE); } //enable cursor

        Uint32 time = 0;
        time = SDL_GetTicks() - StartTicks;  
        timeStep = time/1000.f;
        StartTicks = SDL_GetTicks(); 
        fps++; //fps counter
        onesectime += timeStep; //1 sec counter
        frameStartTime = SDL_GetTicks();  

        //=========================================input handle sector =========================================//
        while (SDL_PollEvent(&e) != 0)
        {
            if (e.type == SDL_QUIT)
            isRunning = false;

            if( e.type == SDL_KEYDOWN && e.key.repeat == 0 )
            {
                switch(e.key.keysym.sym)
                {
                    case SDLK_e: editor_keyCount++; break;
                }

                if(editor_keyCount == 1)
                { enableEditor = !enableEditor; }

            }
            if( e.type == SDL_KEYUP && e.key.repeat == 0 )
            {
                switch(e.key.keysym.sym)
                {
                    case SDLK_e: editor_keyCount--; break;
                }
            }
        }

        //=========================================render sector=========================================//
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        //--------------------------------------fps stuff --------------------------------------------------------------//  

            frameEndTime = SDL_GetTicks();

            /*if((frameEndTime - frameStartTime) < 16.67) //60fps manual cap
            {
                SDL_Delay(16.67-(frameEndTime-frameStartTime)); 
            }*/

            if(onesectime >= 1) //print fps 
            {
                std::cout<<fps<<std::endl;
                onesectime = 0;
                fps  = 0;
            }           

            SDL_GL_SwapWindow( window );

        }
    }

    close();
    return 0;
}

initialize() function:

bool initialize()
{
Uint32 flags = SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS;
//initializing
if(SDL_Init(flags) < 0)
{
    std::cout<<"SDL could not initialize! SDL Error: " << SDL_GetError() << std::endl;
    isRunning = false;
}
else
{
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );

    flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;//SDL_WINDOW_INPUT_GRABBED;
    window = SDL_CreateWindow("Test Application", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, flags);
    if( window == NULL )
    {
        std::cout<<"Window could not be created! SDL Error:" << SDL_GetError() << std::endl;
        isRunning = false;
    }
    else
    {
        openGL_Context = SDL_GL_CreateContext( window );
        if(openGL_Context == NULL)
        {
            std::cout<<"OpenGL context could not be created! SDL Error: %s\n" << SDL_GetError() <<std::endl;
            isRunning = false;
        }
        else
        {
            //enable(1)or disable(0) vsync
            if(SDL_GL_SetSwapInterval( 1 ) < 0)
            {
                std::cout<<"Warning, vsync disabled!"<<std::endl;
            }

            glewExperimental = GL_TRUE;
            if( glewInit() != GLEW_OK)
            {
                std::cout<<"Unable to initialize glew!"<<std::endl;

                isRunning = false;
            }
            else
            {           
                SDL_WarpMouseInWindow(window, (SCREEN_WIDTH/2), (SCREEN_HEIGHT/2)); 
            }
        }
    }
  }

  return isRunning;
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
Ash
  • 131
  • 1
  • 7
  • 1
    Please post a minimal, reproducible example. – Acorn Jun 14 '20 at 14:19
  • 2
    Happens to me to. Something tells me `SDL_GL_SwapWindow` uses a busy loop to wait for the right moment to swap. You can predict how long `SDL_GL_SwapWindow` is going to wait, then sleep that amount of time (minus 1-2 ms) before calling it. – HolyBlackCat Jun 14 '20 at 14:21
  • @HolyBlackCat, so basically the main loop runs everything perfectly untill sdl_gl_swap which then gets stuck in a busy loop waiting for the right moment to swap. So i have to prevent the busy loop running that long with my own delay function and then run sdl_gl_swapwindow? – Ash Jun 14 '20 at 14:37
  • 1
    Yep. I'm not 100% certain about this, but it should work. – HolyBlackCat Jun 14 '20 at 14:41
  • @HolyBlackCat, Thanks for your answer, I tried it out and it worked. – Ash Jun 14 '20 at 14:55
  • 1
    Reported it as bug: https://bugzilla.libsdl.org/show_bug.cgi?id=5189 – Andreas Jun 14 '20 at 19:29
  • 1
    @HolyBlackCat, SDL maintainers statement: "If I had to guess, I'd say you're on Linux using the NVIDIA proprietary drivers, and that your problem is that you should try setting __GL_YIELD to USLEEP." – Andreas Jun 14 '20 at 20:42
  • @Andreas thanks for reporting this, ill get back to your post on libsdl in a few hours – Ash Jun 15 '20 at 04:42

0 Answers0