How textures manager works? (SOLVED)

On android it should be enough to set android:debuggable="true" in the manifest file.

2 Likes

Is it possible to use something like this on ios? (xcode tools?)

How are you checking what resources are loaded and how much memory is used by the application? Through the built-in profiler or the web profiler?

In Situation 2, something certainly seems to be referencing the atlas. There should not be any difference between the two Situations.
What objects does the collection proxy’s collection contain. Have you double checked there is no possible reference to the atlas in any objects there, or by creating a gameobject or collection through factories (in scripts).

1 Like

I’m absolutely sure that loaded collection do not use this atlas.
I check memory using profiler.get_memory_usage()
in situation one right after remove GO I see memory use is reduce
In situation two - a memory using is the same like before removing.

Now I try to check it using GAPID.

UPD:
ok, the memory reducing after remove GO do not related with texture. Texture still in memory. I think this is because of removing last GUI component.

It’s worth noting again that this is information that is reported from the OS, nothing the engine keeps track of. It should be taken as an estimate, since the OS could still keep stuff in memory even if it is released by the app, depending on the access pattern etc.

4 Likes

Thank you @sven, You right, this is bad idea to draw conclusions using this function.
I was wrong, and in both situation this atlas still in memory.

But question still open, how to a counter works (it depend of (linked to) collection, GO, factory or something else?).

I tried to make collection factory and exploit this bug, but texture still in memory after removing spawned GO. That one of the reason why I want to know how it works. (it is easier to use something when you know how it works)

1 Like

When are you calling profiler.get_memory_usage?
The process of deleting GPU related resources is deferred to make sure they aren’t used by the GPU when being deleted. Are you checking memory usage in the same frame as the go is being deleted? If so, wait a few frames before checking / comparing the value.

You can’t remove an atlas resource. It will be removed when no resources other are referencing it anymore.
When a component (for example a sprite or a gui) is removed, it will dereference all it’s referenced resources, for example an atlas and when there are no more components referencing a resource (counter is zero) it will be deleted, or in the case of GPU resources, marked for delete (deferred).
This is common for all engine resources, so if deleting the one gameobject who’s components is referring the atlas isn’t releasing the atlas it might be a bug.

5 Likes

in update method

I checked it twice using GAPID.
New situations (all information from GAPID trace):

Situation 3:
one collection, GO with gui component

  1. Load game and show gui
  2. Waiting 5 seconds
  3. Remove GO with gui.
    waiting 3-5 seconds
    Checking the GAPID trace in last frame : atlas still in memory.

Situation 4:
Collection with one collection proxy with many big atlases(ust for test) and one collelction factory with my GUI

  1. Load game
    (GUI atlas isn’t load to memory)
  2. Waiting 5 seconds
  3. Load collelction factory
    (now GUI atlas in memory)
  4. Waiting 5 seconds
  5. Delete GO from p.3 (with GUI)
  6. Waiting 5 seconds
    (atlas still in memory)
  7. Load collection proxy with many big atlases
    checking and my GUI atlas still in memory.

I don’t know how it works in Defold.
You tell me that it depend of direct link of some component (component referenced to atlas)

From @britzl post I understand that it’s depend of collection, not a component How textures manager works? (SOLVED) (collection referenced to atlas)

Here is information from @Ragnar_Svensson where he told that it have to depend of collection (also collection referenced to atlas) , but Defold have bug where you can load atlas using factory. But I do not understand how to unload this atlas . @sicher told that it’s impossible - that mean atlases referenced with collection or something else, but not with components.

I have to understand how it works in engine. Too many controversial information from different people.

Yes, it easily gets confused when several people are expressing the same thing.
Bottom line is that when a resource, in this case your gui is referencing some other resource, in this case an atlas, the reference counter is decreased when the gui is destroyed (that is, when the gameobject containing it is deleted).
When you are destroying the gameobject containing the gui you say that the texture is still in memory. This shouldn’t be when the gui is the only resource referencing the atlas. In this case the gui component is responsible for dereferencing the atlas. If it doesn’t it’s a bug and would explain your problem.
I will look into this asap since it’s certainly not a good thing if gui’s aren’t releasing it’s textures.

4 Likes

I take a break (I’m afraid my brain can explode), I’ll try to create clean/new project with example today later and recheck it one more time for GUI, GO in collection and using collection factory.

My current conclusion:
only components (not collection and so on) should referenced to the atlases. When last component (GO who contain this component) will be removed, atlas should be removed too. Right?

1 Like

That is correct.

The profiler.get_memory_usage will report memory resident set size allocated by the OS for the application (https://en.wikipedia.org/wiki/Resident_set_size) on OSX.
See the documentation for profiler.get_memory_usage for more info and how it works on different platforms.

This needs to be elaborated in the documentation, we’ll look into this!

If you check the ‘Memory’ stats column in Activity Monitor (You mentioned you use OSX) you will see that memory consumption goes up and down when creating and destroying resources (loading/unloading).
If you add the ‘Real Mem’ tab you will see the same figures reported by profiler.get_memory_usage.

We do have an ongoing task/ticket to improve memory stats and other profiling related items, so we will likely re-iterate what memory consumption is reported and how. Until then, you will have to suffice with improved documentation.

3 Likes

ok, thank you.

btw, In situation 3 and 4 I’m using GAPID for checking that texture is still in memory.

You mark theme like solved, but I want to make new example and recheck all test. I’ll give you know about results. As I understand from your words it is a bug that texture do not removed from the memory.

I considered the main question to be the memory reported by profiler.get_memory_usage, and we sorted that out. If the engine wasn’t releasing the memory referenced by the gameobject, it would show up quite imminently.

I did overlook your question regarding your GAPID findings, so I’ll try to elaborate that.
If you run XCode Graphics Tools -> OpenGL Profiler, you’ll (likely) see that the texture is released from memory.
Using GAPID on Android, you’ll see that the textures are replaced by the same id (or likely so anyway).
This is because some drivers keeps the storage allocated so they can reuse it for future allocations instead of having to allocate new storage.
So, checking what is currently in driver memory can easily be mistaken for a memory leak. Drivers will handle this automatically and is nothing the application can control. Driver writers base their solution on what they consider is best for the hardware.

I verified this both on Mac and on Android, loading and unloading 16 unique collections sequentially each containing a 16MB RGBA textures, and in a loop.

5 Likes

Collection proxy? - yes, it’s ok.
But I tell you about GO in main collection, or spawned using collection factory.

I was using collection factories to spawn and delete from the main collection.
No proxy loading. Loading/Unloading as in I made sure the texture was loaded and unloaded.

2 Likes

With GUI component too?

Yes, I’ve tested with GUI component too.
It all works as expected.

As a side-note, the engine is continuously built and tested with extensive unit-tests for all platforms. It is also tested through valgrind on the Linux builder. No tests are 100% of course, but we do our best to be thorough. It’s a proven point the time spent writing thorough tests pays back in the long run.
In any case we can’t test what is happening within the Open GL driver itself.
You can rest assured the texture(s) are getting correctly deleted in the engine.
What the Open GL driver does under the hood is nothing we can or should control.

4 Likes

Thank you for your explanations!
Now everything is clearer! :+1:

Unfortunately I tried to use OpenGL Profiler but it’s show nothing in “Resources” window. But if you told that everything works fine - ok. It’s sad that engine has no simple possibility to check which and how many textures in memory now.

2 Likes

We have a ticket for improving the engine profiler to report those kind of stats too, but I can’t tell you at this time when you can expect this implemented.

I will do a writeup on the forum on how to install and quickly get going with GPU profiling on Android, iOS, Mac and Windows as soon as possible.

For your more imminent problem with OpenGL Profiler though. For 8.x version of the XCode Graphics tools:

  • Make sure you got “Status: Running…” when you have launched or attached to an application. If not, you need to enable remote profiling in the OpenGL Profiler preferences. Then choose “Connect to” in the File menu and connect to your machine. This is an issue with Mac OS Sierra and the Profiler tool. They seem to have sorted this in 9.x beta tools which I am running though. It should look like this

  • You then need to set a breakpoint. Bring up the break point window from the “Views” menu and set a breakpoint like this. It takes some getting your head around how these works…

  • Then, when you the program stops, you can bring up the resources window which should look like this

More info on how to use the tool here: https://developer.apple.com/library/content/technotes/tn2178/_index.html#//apple_ref/doc/uid/DTS40007990-CH1-SECTION1

Let me know if you can’t get this to work and I’ll try to help out.

7 Likes

Super useful, thank you! (I forgot about the breakpoint ( )

3 Likes