SFML community forums

Help => General => Topic started by: Mörkö on March 09, 2016, 01:12:06 am

Title: Initial draw call slow
Post by: Mörkö on March 09, 2016, 01:12:06 am
Why does the first call to draw with some vertices cause a huge lag?

Example:
int main() {
    sf::RenderWindow window{sf::VideoMode{640, 480}, "SFML"};
    for (auto n : {1, 2, 3}) {
        Timer p{"Draw"};
        if (n > 1)  window.draw(sf::RectangleShape{});
        else        window.draw(sf::VertexArray{sf::Triangles});
    }
}

Typical output:
Draw 0.031ms
Draw 167.891ms
Draw 0.006ms
Title: Re: Initial draw call slow
Post by: Hapax on March 09, 2016, 04:18:33 am
Why does the first call to draw with some vertices cause a huge lag?
Isn't the vertex array being drawn before both of the rectangle shapes?
It actually seems to delay on the first rectangle shape drawn.
Title: Re: Initial draw call slow
Post by: Mörkö on March 09, 2016, 05:18:01 am
Yes that's what I was trying to show, that it doesn't lag on the empty draw call, then it does lag on the first, and only on the first rectangleshape draw call. More generally, the first call to draw some vertices.

I haven't looked into the source to see what happens when drawing a default rectangleshape, but I conjecture it draws some vertices because that would be consistent with how the lag appears in all other circumstances, I discovered it not by using rectangleshape but by using vertexarray.

Other example:
int main() {
    sf::RenderWindow window{sf::VideoMode{640, 480}, "SFML"};
    sf::VertexArray vs{sf::Points};
    vs.append(sf::Vertex{sf::Vector2f{0, 0}});
    for (auto n : {1, 2, 3}) {
        Timer p{"Draw"};
        if (n > 1)  window.draw(vs); // lag once on first call
        else        window.draw(sf::VertexArray{sf::Points}); // no lag
    }
}
Title: Re: Initial draw call slow
Post by: Laurent on March 09, 2016, 08:00:43 am
Many OpenGL states are configured at the first draw call (and often just reused for other calls), but the whole process is totally skipped if there's nothing to draw.

I haven't checked the code so I can't tell you exactly what happens, but you get the idea. If you're really interested, you can have a look at RenderTarget::draw(const Vertex*, ...).
Title: Re: Initial draw call slow
Post by: Mr_Blame on March 12, 2016, 02:54:39 pm
to start up with: sfml is using opengl 1.2 for rendering. On big aomunt of gpus this version is not implemented: instead it is emulated with opengl 3.3 functionality.
Because of that, every call of glVetexPointer(which sfml does) causes upload of certex data to gpu memory or vram and I can say to you that this operation is not the fastest. SFML escapes this problem by using rendertarget cache, which helps it to not do unneeded openGL state changes.
To sum up with: if you had old gpu with opengl 1.1 implemented than there will be probably no lag.
Title: AW: Initial draw call slow
Post by: eXpl0it3r on March 12, 2016, 03:16:14 pm
OpenGL 2.1*
Title: Re: AW: Initial draw call slow
Post by: Mr_Blame on March 12, 2016, 03:21:54 pm
OpenGL 2.1*
Okay but still glVertexPointer.