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

Author Topic: Memory usage increasing when drawing a sprite?  (Read 2487 times)

0 Members and 1 Guest are viewing this topic.

dorcsyful

  • Newbie
  • *
  • Posts: 4
    • View Profile
Memory usage increasing when drawing a sprite?
« on: October 17, 2024, 03:34:08 pm »
So I have a fairly simple game. Most of the sprites used are created at startup and stored in shared pointers. According to the VS profiler, the memory usage is around 147MB. At this point there are several sprites and textures created and loaded, but only a few of them drawn. Upon a button press some extra sprites are now drawn. This causes the memory to go up to about 149-150 and it continues to grow by 1MB as new sprites get added (no new textures are loaded after the startup).

This is the constructor of the wrapper class for animating the sprites, which inherits from sf::Drawable (the overriden draw function just draws the sprite). The texture and the sprite are stored as shared pointers.

Code: [Select]
AnimatedSprite::AnimatedSprite(const std::shared_ptr<sf::Texture>& a_Texture, const float a_TotalTime, const int a_FrameCount):
m_Texture(a_Texture),
m_FrameTime(a_TotalTime),
m_CurrentFrame(0),
m_FrameCount(a_FrameCount)
{
m_Sprite = std::make_shared<sf::Sprite>(*m_Texture);
sf::Vector2i size = static_cast<sf::Vector2i>(m_Texture->getSize());
size.x /= m_FrameCount;
m_Sprite->setTextureRect(sf::IntRect(0, 0, size.x, size.y));
}

And this is the function that creates the sprite:
Code: [Select]
void Rendering::CreateSprite(const EBUBBLE_TYPE a_Type, const sf::Vector2f& a_Position, const float a_Rotation, std::shared_ptr<AnimatedSprite>& a_NewSprite)
{
a_NewSprite = std::make_shared<AnimatedSprite>(m_BubbleTextures.at(a_Type),BUBBLE_FRAME_TIME,4);

sf::Vector2f size = BubbleMath::ToVector2f(m_BubbleTextures.at(a_Type)->getSize());
size.x /= 4;
a_NewSprite->GetSprite()->setScale(bubble_sizes.at(a_Type) * PIXEL_TO_METER * 2 / size.x, bubble_sizes.at(a_Type) * PIXEL_TO_METER * 2 / size.y);

float x = bubble_sizes.at(a_Type) * PIXEL_TO_METER / a_NewSprite->GetSprite()->getScale().x;
float y = bubble_sizes.at(a_Type) * PIXEL_TO_METER / a_NewSprite->GetSprite()->getScale().y;
a_NewSprite->GetSprite()->setOrigin(x, y);

a_NewSprite->SetPosition(a_Position);
a_NewSprite->SetRotation(a_Rotation);
}

The sprites that need to be drawn are just looped through like this:
Code: [Select]
void Rendering::PlayDraw() const
{
for (const auto& element : m_Container)
{
m_Window->draw(*element);
}

m_Window->draw(*m_Line);
m_Window->draw(*m_PreviewBubbles.at(m_ActiveBubble));
for (auto& element : m_BubbleSprites)
{
m_Window->draw(*element);
}
m_Window->draw(*m_ScoreBackground);
m_Window->draw(*m_ScoreText);
}

Am I missing something here that could cause the extra memory usage or is it just the profiler detecting things wrong?

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: Memory usage increasing when drawing a sprite?
« Reply #1 on: October 17, 2024, 04:06:41 pm »
Not sure if this counts as a bug with Visual Studio but I have noticed that the profiler, when running the debugger, seems to include Visual Studio's memory usage on top of whatever is being debugged. If you launch the Task Manager while you're debugging the game compare the memory usage reported there and you'll probably find that the game itself is using a very small amount of RAM and Visual Studio is using most of it. Add the values together and you'll get something close to what's being reported in the profiler.

HTH

dorcsyful

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Memory usage increasing when drawing a sprite?
« Reply #2 on: October 17, 2024, 07:32:49 pm »
It's not really the amount of ram used is what I'm wondering about. I'm more concerned about the fact that the ram usage grows according to the draw calls by a lot. I thought that's only supposed to affect the CPU

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Memory usage increasing when drawing a sprite?
« Reply #3 on: October 19, 2024, 10:14:51 pm »
Since we don't really see the declaration, we need to guess what types you're using.

If for example m_Texture in AnimatedSprite isn't a reference, you'll make a copy of the texture, every time your create a new AnimatedSprite. Given the -> access afterwards, I assume it's actually a shared_ptr, correct?

There's also a lot of bad practice in that code.
Yes, shared_ptr will "solve" your life-time issues, but that's more of a hack than an actual solution.
You need to make sure, that your life-time is handled correctly in the code, then the need to heap allocated objects and shared_ptr become unnecessary.
Why does a sf::Sprite owned by AnimatedSprite need to be a shared_ptr? With whom are you sharing that member variable?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

dorcsyful

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Memory usage increasing when drawing a sprite?
« Reply #4 on: October 21, 2024, 10:32:46 am »
So you you're saying I can just store all textures on the stack and AnimatedSprite can just store a reference to it? I thought they would be too big for the stack.

Thanks for reminding me about the sf::Sprite though, I needed it as a shared_ptr before I did some refactoring and forgot to change it.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: Memory usage increasing when drawing a sprite?
« Reply #5 on: October 21, 2024, 01:47:37 pm »
You need to consider that shared_ptr isn't just about memory management, but it's first about ownership. Using a shared_ptr signals, that the resource is owned by many parties, which isn't really correct, since say AnimatedSprite just uses the texture, but it doesn't really "own" it.

If you store textures in a container like std::unordered_map they'll still be allocated on the heap, but you don't need to deal with smart pointers. If you want to use std::vector, you'll still have to use smart pointers in SFML 2, because copying texture's is quite expensive and move semantics hasn't been implemented, but then I suggest to use a unique_ptr, as there should be a single owner of the texture: std::vector<std::unique_ptr<sf::Texture>>
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

dorcsyful

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Memory usage increasing when drawing a sprite?
« Reply #6 on: October 23, 2024, 05:33:20 pm »
Okay so I sorted out my data types and the textures are now stored as unique pointers. However, the memory usage is still increasing depending on whether or not a sprite is drawn, both in debug and release mode.