LibGDX - How many references counted in AssetManager of my case?

757 Views Asked by At

I created an AssetManger Class called AssetsTest.

    package com.program.mydemo;

    import com.badlogic.gdx.assets.AssetManager;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.TextureAtlas;


    public class AssetsTest {

        public static AssetManager manager = new AssetManager();

        public static void load() {     
            manager.load("bgscreen.png", Texture.class);
            manager.load("menu.pack", TextureAtlas.class);      
        }

        public static void unload() {
            manager.unload("bgscreen.png");
            manager.unload("menu.pack");        
        }

        public static boolean update(){     
            return manager.update();
        }

        public static void dispose() {
            manager.dispose();      
        }   

    }

I also created another Class called MyDemo

public class MyDemo extends Game {

    private SpriteBatch batch;
    private Sprite spriteStart1, spriteStart2;
    private Texture texture1, texture2;
    private TextureAtlas atlas1, atlas2;
    private TextureRegion startRegion1, startRegion2;
    private Camera camera;
    private int refCount;

    public void create () {

        batch=new SpriteBatch(); 
        camera = new OrthographicCamera(500,700);

        AssetsTest.load();
        AssetsTest.manager.finishLoading();

        texture1 = AssetsTest.manager.get("bgscreen.png",Texture.class);
        atlas1 = AssetsTest.manager.get("menu.pack", TextureAtlas.class);
        startRegion1 = atlas1.findRegion("startbutton");
        spriteStart1 = new Sprite(startRegion1);
        spriteStart1.setPosition(-210/2,-150);      

        texture2 = AssetsTest.manager.get("bgscreen.png",Texture.class);
        atlas2 = AssetsTest.manager.get("menu.pack", TextureAtlas.class);
        startRegion2 = atlas2.findRegion("startbutton");
        spriteStart2 = new Sprite(startRegion2);
        spriteStart2.setPosition(-210/2,-150);      

        refCount = AssetsTest.manager.getReferenceCount("bgscreen.png");
        System.out.println(refCount);

//      AssetsTest.unload();    

//      AssetsTest.load();
//      AssetsTest.manager.finishLoading();         


    public void render () {
        Gdx.gl.glClearColor(0,0,0,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(camera.combined);

        batch.begin();
        batch.draw(texture2, -500/2,-700/2);
        spriteStart2.draw(batch);
        batch.end();
    }   

    @Override
    public void dispose () {
        super.dispose();
        batch.dispose();
        texture1.dispose();
        AssetsTest.dispose();
    }
}

Then, I created two Texture References (texture1 & texture2) reference to AssetsTest.manager.get(...);

The refCount is 1. Why?

It should be "2" because I have two references (texture1 & texture2).

If I try to call AssetsTest.load(); twice, I will get refCount is 2. Calling twice of AssetsTest.load(); should create two objects and stored in different memory address. Is my concept correct?

1

There are 1 best solutions below

3
On BEST ANSWER

Directly from the libgdx documentation:

Assets are reference counted. If two assets A and B both depend on another  
asset C, C won't be disposed until A and B have been disposed. 

This also means that if you load an asset multiple times, it will actually be shared and only take up memory once!

you load

texture1 = AssetsTest.manager.get("bgscreen.png",Texture.class);

and then

texture2 = AssetsTest.manager.get("bgscreen.png",Texture.class);

both texture1 and texture2 point to the same texture which is shared and takes memory only once. That's why you get ref count 1.

Update

Yes, texture1 and texture2 point to the same object ("bgscreen") which is shared. So in a sense they are reference variables pointing to the same memory address. Once an item is loaded in the asset manager it could be reused/shared in this way. In your case this means that no new object will be created each time you reference "bgscreen.png". So you will always get ref count 1.

As regards to the the 2nd part of your question. To clarify some things: Assetmanager.load in its way doesn't load any assets. The method just enqueues the assets. Once you call manager.update() or manager.isFinished only then the assets which you've enqueued with the load method will be loaded into memory. So if you call load twice of the same texture then when you call manager.update() you will end up with two references of the same object ("bgscreen.png") which is unnecessary because what you usually want is have only one shared reference of the same object for efficiency. If this answers your question please don't forget to accept the response.