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

Author Topic: Drawing to a sf::RenderTexture causing memory leak.  (Read 6110 times)

0 Members and 1 Guest are viewing this topic.

Iggy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Drawing to a sf::RenderTexture causing memory leak.
« on: May 23, 2015, 12:14:50 am »
Hi there, I'm using a render texture to draw a tilemap everything works perfect except for the fact there is a memory leak caused when i draw a sprite to it.

I left my game engine running overnight and when i checked in the morning i had "program stopped working" messagebox. So i started the engine again and watched the task manager.  I found that memory just keeps building up without being released. I narrowed it down to a single line - drawing a sprite to a local render texture.

Here's the code:

//local variable too
sf::RenderTexture RenderTexture;

RenderTexture.create(RenderTarget.getSize().x + m_TileSize.first * 2, RenderTarget.getSize().y + m_TileSize.second * 2);

for (auto Tile : m_Tiles)//std::vector<sf::Sprite> m_Tiles;
{
        if (ScreenSpace.intersects(Tile.getGlobalBounds()))//check if tile is onscreen
        {
                //get current world co-ordinates
                SpriteWorldPos = Tile.getPosition();

                //set sprites position to converted pixel co-ordinates
                Tile.setPosition(sf::Vector2f{ RenderTarget.mapCoordsToPixel(Tile.getPosition()) });

                //draw tile at pixel position
                RenderTexture.draw(Tile);//this line causes memory to leak, no problem when this single line is commented
                //^^^ problem line ^^^

                //set position back at world co-ordinates
                Tile.setPosition(SpriteWorldPos);
        }
}

EDIT: I was originally using SFML 2.2 when i noticed this, i upgraded to 2.3 but same problem.
« Last Edit: May 23, 2015, 12:19:14 am by Iggy »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Drawing to a sf::RenderTexture causing memory leak.
« Reply #1 on: May 23, 2015, 02:30:58 am »
As always you need to provide a complete and minimal example that we can all test.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Drawing to a sf::RenderTexture causing memory leak.
« Reply #2 on: May 23, 2015, 09:42:56 am »
This is probably due to a driver leak. Creating and destroying an sf::RenderTexture every frame is very expensive both performance and memory-wise, an OpenGL context will be created and destroyed along with it. If you do this often enough, your graphics driver will start to leak.

Instead of declaring your sf::RenderTexture as a local variable, try to reuse the same one as you did in the previous frame. Judging by the code you posted, I'm sure this is doable and will even decrease your frame time.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Iggy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Drawing to a sf::RenderTexture causing memory leak.
« Reply #3 on: May 23, 2015, 10:16:04 am »
As always you need to provide a complete and minimal example that we can all test.

Can you not test the draw function of the render texture? I posted the other code to show im not using pointers. As i said it's that single line (sf::RenderTexture::Draw) thats causing the problem. Not hard to reproduce - I'm just drawing 32x32 sprites to it.

This is probably due to a driver leak. Creating and destroying an sf::RenderTexture every frame is very expensive both performance and memory-wise, an OpenGL context will be created and destroyed along with it. If you do this often enough, your graphics driver will start to leak.

Instead of declaring your sf::RenderTexture as a local variable, try to reuse the same one as you did in the previous frame. Judging by the code you posted, I'm sure this is doable and will even decrease your frame time.

Thanks, but originally the RenderTexture was a member of the class (none local) when i noticed the mem leak, that's when i switched to local variable thinking that the destructor would clean up any memory.

So should i not be using a RenderTexture to draw an entire scene? Works perfect except for the leak.
« Last Edit: May 23, 2015, 10:28:56 am by Iggy »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Drawing to a sf::RenderTexture causing memory leak.
« Reply #4 on: May 23, 2015, 10:27:01 am »
What you should take away from my post is that you are probably creating/destroying too many sf::RenderTextures. How you do it is irrelevant. If you create/destroy the object which contains the sf::RenderTexture every frame, it is not much different to what you are doing now. If you are sure that you aren't creating/destroying a lot of sf::RenderTextures repeatedly and are still experiencing a memory leak, then like zsbzsb said, you will need to post a complete and minimal example for us to test.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Iggy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Drawing to a sf::RenderTexture causing memory leak.
« Reply #5 on: May 23, 2015, 10:42:11 am »
What you should take away from my post is that you are probably creating/destroying too many sf::RenderTextures. How you do it is irrelevant. If you create/destroy the object which contains the sf::RenderTexture every frame, it is not much different to what you are doing now. If you are sure that you aren't creating/destroying a lot of sf::RenderTextures repeatedly and are still experiencing a memory leak, then like zsbzsb said, you will need to post a complete and minimal example for us to test.

Thank you, i thought i had to call sf::RenderTexture::create every frame in case window is resized. Now i just call it once each time the window is resized. Memory is stable once again. But i suspect it will leak small amounts each time the window is resized.

PS. You was also right performance has increased lots. Drawing up to 2025 (1920*1080 screen 32px tiles) sprites to the texture and drawing that to the window now takes 1-4ms when it used to take 30-40ms which is amazing.

Thanks again.
« Last Edit: May 23, 2015, 10:59:18 am by Iggy »