In my search for narrowing down occasional stuttering/lag when moving a sprite and have some questions about RenderWindow::display. I have logged how long it takes to make that call when just drawing some circles and this is what I have found:
Starting dump...
Duration: 0ms. Nr of occurrences: 8237
Duration: 1ms. Nr of occurrences: 1722
Duration: 2ms. Nr of occurrences: 19
Duration: 3ms. Nr of occurrences: 2
Duration: 4ms. Nr of occurrences: 1
Duration: 7ms. Nr of occurrences: 3
Duration: 8ms. Nr of occurrences: 3
Duration: 9ms. Nr of occurrences: 5
Duration: 10ms. Nr of occurrences: 1
Duration: 14ms. Nr of occurrences: 1
Duration: 15ms. Nr of occurrences: 2
Duration: 17ms. Nr of occurrences: 1
Duration: 20ms. Nr of occurrences: 1
Duration: 25ms. Nr of occurrences: 1
Duration: 27ms. Nr of occurrences: 1
Done.
What we see is that the vast majority of calls to RenderWindow::display takes 0 to 1 millisecond. That's great. But there are 19 frames that takes longer than 5ms (sum occurrences taking 7-27ms). Those are what's bothering me when trying to scroll things smoothly over the screen. It just isn't smooth. I get the occational "jump" or lag when these slower frames occur. It's definitely noticeable.
Are these occational slow calls to RenderWindow::display expected behaviour? Is there any way I can prevent it? Please note that I have only measured the time it takes to call RenderWindow::display. I.e. after all the circles have been drawn to the window.
Here's the program that produces the above output. It draws 100 circles 5000 times and records how long it takes to make the RenderWindow::display call.
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;
#define ITERATIONS (10000)
int main()
{
srand (time(NULL));
sf::RenderWindow window(sf::VideoMode(1024, 768), "SFML works!");
sf::Clock clock;
vector<sf::CircleShape*> shapes;
for (int i = 0; i < 100; i++)
{
sf::CircleShape* pShape = new sf::CircleShape(50.f);
pShape->setFillColor(sf::Color::Green);
shapes.push_back(pShape);
}
map<int, int> map;
int iBefore;
int iAfter;
for (int i=0;i<ITERATIONS;i++)
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
break;
}
}
window.clear();
for(auto iter = shapes.begin(); iter != shapes.end(); ++iter)
{
sf::CircleShape* pCircle = *iter;
pCircle->setPosition((float)(rand() % 1000), (float)(rand() % 1000));
window.draw(*pCircle);
}
iBefore = clock.getElapsedTime().asMilliseconds();
window.display();
iAfter = clock.getElapsedTime().asMilliseconds();
int iDuration = iAfter - iBefore;
if (map.find(iDuration) == map.end())
{
map[iDuration] = 1;
}
else
{
map[iDuration] = map[iDuration]+1;
}
}
cout << "Starting dump..." << endl;
for (auto iter = map.begin(); iter != map.end(); iter++)
{
cout << "Duration: " << iter->first << "ms.\tNr of occurrences: " << iter->second << endl;
}
cout << "Done." << endl;
return 0;
}
I'm running Windows 7. Quad core cpu. 8GB ram. AMD Radeon 7770. SFML 2.1. Dynamic linking of the DLLs.