Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Severe unregular "lagging" when drawing a given number of shapes  (Read 2186 times)

0 Members and 1 Guest are viewing this topic.

AndiNo

  • Newbie
  • *
  • Posts: 3
    • View Profile
Severe unregular "lagging" when drawing a given number of shapes
« on: September 16, 2012, 11:50:27 pm »
Hi! I'm using the current precompiled SFML 2 RC (SJLJ) from the SFML website. I'm on a Win7 notebook with a AMD Radeon HD 6970M graphics card. Compiler is TDM-GCC 4.6.1.

In the following code I have a shape that gets drawn 'numDrawTiles' times per frame. I have VSync turned on.
The number of times the shape is drawn per frame increases every frame by one.
When the counter reaches about 987 draws per frame the framerate drops to 1FPS or lower instantly. When the counter reaches 1020 suddenly the program runs at 60FPS again. The next drop appears at about 2200 draws, this time however the "recovery time" is longer. After that it's back to normal ~60FPS again.

If I use setFramerateLimit(60) or disable VSync and do not limit the framerate the FPS drop is much less noticeable but still there.

My first assumption was that it might have to do with VSync, however this is not the case as stated above. For the record: I was able to draw about 8000 shapes per frame with approximately 30FPS so this is no usual FPS drop due to too many draw calls. I do also know that this is not the optimal way to draw many similar objects.

Code is below. Any ideas where this is coming from?


#include <SFML/Graphics.hpp>

// main rendering window
sf::RenderWindow mainWindow;

int main() {
        mainWindow.create(sf::VideoMode(640, 480), "Test");
//      mainWindow.setFramerateLimit(60);
        mainWindow.setVerticalSyncEnabled(true);

        sf::RectangleShape shape( sf::Vector2f(40, 40) );
        shape.setFillColor(sf::Color::Green);

        sf::Text counter;
        counter.setColor(sf::Color::Red);
        counter.setScale(3,3);

        unsigned long int tileCounter = 0;
        unsigned long int numDrawTiles = 1;

        while ( mainWindow.isOpen() == true )
        {
                sf::Event event;
                while (mainWindow.pollEvent(event))
                {
                        switch (event.type)
                        {
                                // window closed
                                case sf::Event::Closed:
                                        mainWindow.close();
                                        break;

                                // we don't process other types of events
                                default:
                                        break;
                        }
                }

                mainWindow.clear();

                tileCounter = 0;
                for(unsigned int i=0; i<numDrawTiles; ++i) {
                        shape.setPosition( 320, 240 );
                        mainWindow.draw(shape);
                        ++tileCounter;
                }
                ++numDrawTiles;

                char buffer[12];
                itoa(tileCounter, buffer, 10);
                counter.setString(buffer);
                mainWindow.draw(counter);

                mainWindow.display();
        }

        return 0;
}
 
« Last Edit: September 17, 2012, 12:01:51 am by AndiNo »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10911
    • View Profile
    • development blog
    • Email
Re: Severe unregular "lagging" when drawing a given number of shapes
« Reply #1 on: September 17, 2012, 12:43:15 am »
I can not reproduce such a problem with MinGW 4.7...

You're talking about FPS but you don't actually measure it with SFML, how else do you measure it? Could that timer get influenced by something else?

There are quite a few things that you shouldn't do in your code:
  • Global instances of sf::RenderWindow isn't advised at all, e.g. on MSVC that application crashes instantly in debug mode...
  • If a function returns a Boolean never check against true or false, it's just not a good practice. For example would you write if(true == true)? ;D
  • The function atoi is depreciated in C++ and you should use stringstreams or similar (see example below).
  • There's no need to have default case that calls break; because that's the expected behavior anyways, i.e. if the it runs through all the cases without invoking one, it leave the switch body.
  • Keep in mind that in the future, if you'd ever get a newer version of SFML 2, you'll have to use a specific font. (The example below uses the OS font, which is not advised to do in most cases!

Here's the modified code:
#include <SFML/Graphics.hpp>

#include <sstream>

int main() {
    // main rendering window
    sf::RenderWindow mainWindow;
    mainWindow.create(sf::VideoMode(640, 480), "Test");
    // mainWindow.setFramerateLimit(60);
    mainWindow.setVerticalSyncEnabled(true);

    sf::RectangleShape shape( sf::Vector2f(40, 40) );
    shape.setFillColor(sf::Color::Green);

    sf::Font arial;
    arial.loadFromFile("C:/Windows/Fonts/Arial.ttf");
    sf::Text counter("0", arial);
    counter.setColor(sf::Color::Red);
    sf::Text fps("60", arial);
    fps.setColor(sf::Color::Green);
    fps.setPosition(400, 0);
    sf::Clock clock;
    float dt = 1.f;
    std::stringstream ss;

    unsigned long int tileCounter = 0;
    unsigned long int numDrawTiles = 1;

    while ( mainWindow.isOpen() )
    {
        dt = clock.restart().asSeconds();

        sf::Event event;
        while (mainWindow.pollEvent(event))
        {
            switch (event.type)
            {
                // window closed
                case sf::Event::Closed:
                        mainWindow.close();
                        break;
            }
        }

        mainWindow.clear();

        tileCounter = 0;
        for(unsigned int i=0; i<numDrawTiles; ++i) {
            shape.setPosition( 320, 240 );
            mainWindow.draw(shape);
            ++tileCounter;
        }
        ++numDrawTiles;

        ss.str("");
        ss << tileCounter;
        counter.setString(ss.str());
        mainWindow.draw(counter);

        ss.str("");
        ss << (1.f/dt);
        fps.setString(ss.str());
        mainWindow.draw(fps);

        mainWindow.display();
    }
}
 
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

AndiNo

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Severe unregular "lagging" when drawing a given number of shapes
« Reply #2 on: September 17, 2012, 10:37:44 am »
Thanks for your answer.
You're right, I do not measure FPS in any way other than looking at the screen and seeing that the counter should go up about 60 times per second, but doesn't do it when reaching the given amount of draw calls.

I tried your code but the "freezes" are still there. At about 988 draw calls the screen doesn't get updated anymore for about 10-20 seconds, then drawing goes on as usual. Sometimes during these freezes I can see that the FPS are below 1.

In the future I will probably use a different approach for drawing many objects, but it would be nice if anyone could figure out whether this is a bug in the code or if it's some unfortunate combination of software/hardware.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10911
    • View Profile
    • development blog
    • Email
Re: Severe unregular "lagging" when drawing a given number of shapes
« Reply #3 on: September 17, 2012, 11:50:37 am »
I guess it's hard to figure out for other where the problem could be since it can probably only be reproduced on your PC...
Have looked at other processes running in the background and how they use your PC? Could one of them interfere somehow with your application?
You could also run Process Explorer and look at the GPU usage of the application and what happens near 988 draw calls...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

AndiNo

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Severe unregular "lagging" when drawing a given number of shapes
« Reply #4 on: September 21, 2012, 10:34:49 pm »
Sorry for the late reply. I've been very busy during the last few days.

ProcessExplorer was a good idea. I've attached an image of the CPU usage while the program runs. I did not include the GPU graph, as it looked nearly identical to the CPU graph. At 60 fps the gaps are all 30 seconds long while the actual working time is about 20 seconds. Again I noticed that the gaps are a lot shorter if I use setFrameLimit instead of VSync.
However I could not obtain any new information about the topic. I guess it might have to do with my graphics card driver which I can not easily update because I'm using a laptop graphics card.
I will probably just ignore this behaviour and hope that it only appears on my computer. Maybe I'll test this again if a newer version of SFML becomes available.
Thanks for your effort :)

[attachment deleted by admin]

 

anything