Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to free textures without unsafe code? #1107

Closed
jsihvola opened this issue May 3, 2021 · 5 comments
Closed

Is it possible to free textures without unsafe code? #1107

jsihvola opened this issue May 3, 2021 · 5 comments

Comments

@jsihvola
Copy link

jsihvola commented May 3, 2021

I find the documentation highly vague on this crucial issue. So I ask about it explicitly:

Is it possible to free textures (so that memory gets instantly freed) during the course of the program without using unsafe code?

I made a test where I filled a vector with elements that contain an SDL_Texture. This consumed process's memory. Then I popped the same amount of elements from the vector but this did not free any process's memory. If this was a wrong way to do it, what is the right way?

@Cobrand
Copy link
Member

Cobrand commented May 3, 2021

Which features are you using?

Normally, a Texture gets its memory freed when the texture is dropped. However I find your behavior odd, generally a Texture represents a texture on the hardware and takes almost no size in the RAM at all. It depends if your rendered is software-accelerated or hardware-accelerated.

If you confirm that it's coming from Texture allocation, and without features, then there is a bug.

There is the feature unsafe_textures that allows you to have textures without lifetimes, where the destroy method is unsafe and the Drop doesn't do anything. From the doc with this feature (use cargo doc --open to see documentation with your features):

Without the unsafe_textures, a texture is owned by a TextureCreator and a Texture cannot outlive its parent TextureCreator thanks to lifetimes. A texture is destroyed via its Drop implementation. While this is the most "Rust"-y way of doing things currently, it is pretty cumbersome to use in some cases.

That is why the feature unsafe_textures was brought to life: the lifetimes are gone, meaning that Textures can outlive their parents. That means that the Textures are not destroyed on Drop, but destroyed when their parents are. That means if you create 10 000 textures with this feature, they will only be destroyed after you drop the Canvas and every TextureCreator linked to it. While this feature is enabled, this is the safest way to free the memory taken by the Textures, but there is still another, unsafe way to destroy the Texture before its Canvas: the method destroy. This method is unsafe because you have to make sure the parent Canvas or TextureCreator is still alive while calling this method.

So if you use this feature, this behavior is expected, and already documented.

@jsihvola
Copy link
Author

jsihvola commented May 3, 2021

Thanks for the answer

If you want to inspect my test code, it is here: https://pastebin.com/raw/7iHX6QaY

My hardware is Raspberry Pi 4 and OS is machine's official os (RPi OS, formely Raspbian, based on Debian)

For watching process's memory I used the following command ("editor" is process's name):
ps -o pid,user,%mem,command ax | sort -b -k3 -r | grep editor

@Cobrand
Copy link
Member

Cobrand commented May 3, 2021

You skipped the most important part: which features are you using? If you are new to Rust, they are shown in your Cargo.toml.

Looking at your pastbin, your Texture has no lifetimes, so you are probably using unsafe_textures, and then that is expected behavior according to the docs. If you want memory to be freed on drop, don't use the unsafe_textures feature.

Also, you can use test_vec.clear() instead of calling test_vec.pop() 1000 times, it will drop them all in a single call, and empty your vec at the same time.

@jsihvola
Copy link
Author

jsihvola commented May 3, 2021

I had written that test code on the top of my program code which uses unsafe textures without understanding that it changes the way how textures (created with ordinary calls) behave. This must explain it. Sorry to waste your time.

(I still recommend being more explicit on this project's documentation page (here: https://github.com/Rust-SDL2/rust-sdl2/) that without unsafe textures feature texture memory will be freed when variables are dropped)

@Cobrand
Copy link
Member

Cobrand commented May 3, 2021

There is a mention in the readme if you want to know more about unsafe_textures:

There is no online documentation for this feature, however you can build it yourself in your project by enabling the feature in your Cargo.toml, running cargo doc and accessing target/doc/sdl2/index.html via a browser.

We can't state everything in the readme, that is why the docs are here and we direct to it both times it is mentioned.

@Cobrand Cobrand closed this as completed May 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants