Last active
April 10, 2022 13:59
-
-
Save doriancransac/e69728fe68dfb8542d67aa688b1405d8 to your computer and use it in GitHub Desktop.
A quick client implementation loading a sprite sheet 500 times and checking the global memory usage on the host after loading and drawing the textures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.badlogic.gdx.Game; | |
import com.badlogic.gdx.Gdx; | |
import com.badlogic.gdx.backends.lwjgl.LwjglApplication; | |
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; | |
import com.badlogic.gdx.files.FileHandle; | |
import com.badlogic.gdx.graphics.GL20; | |
import com.badlogic.gdx.graphics.Texture; | |
import com.badlogic.gdx.graphics.g2d.Animation; | |
import com.badlogic.gdx.graphics.g2d.BitmapFont; | |
import com.badlogic.gdx.graphics.g2d.SpriteBatch; | |
import com.badlogic.gdx.graphics.g2d.TextureRegion; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.lang.management.ManagementFactory; | |
import java.util.*; | |
import java.util.concurrent.atomic.AtomicInteger; | |
import java.util.stream.IntStream; | |
public class MemoryUsageDebuggingClient { | |
private static final Logger logger = LoggerFactory.getLogger(MemoryUsageDebuggingClient.class); | |
public static void main(String... args){ | |
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); | |
config.width = 1900; | |
config.height = 1280; | |
final int[] renderingCounter = {0}; | |
new LwjglApplication(new Game() { | |
private static final int nbAnimations = 500; | |
private static final int nbDistinctSheets = 500; | |
private BitmapFont font; | |
private SpriteBatch batch; | |
private Map<AbstractMap.SimpleEntry, Animation<TextureRegion>> testAnimations; | |
private List<TextureRegion[][]> spriteSheets; | |
private double stateTime; | |
@Override | |
public void create() { | |
System.out.println("Starting to create!"); | |
//Explicit full gc calls not really necessary here, but just in case | |
System.gc(); | |
System.out.println("Getting ready to load textures, memory = " + (getTotalMemory() - getFreeMemory()) / 1024 / 1024 + " MB"); | |
initSpriteSheets(); | |
System.gc(); | |
System.out.println("Finished loading textures, memory = " + (getTotalMemory() - getFreeMemory()) / 1024 / 1024 + " MB"); | |
System.gc(); | |
System.out.println("Getting ready to initialize animations, memory = " + (getTotalMemory() - getFreeMemory()) / 1024 / 1024 + " MB"); | |
initAnimations(); | |
System.gc(); | |
System.out.println("Finished creating animations, memory = " + (getTotalMemory() - getFreeMemory()) / 1024 / 1024 + " MB"); | |
this.batch = new SpriteBatch(); | |
this.font = new BitmapFont(); | |
this.stateTime = 0; | |
System.out.println("App created, now rendering."); | |
} | |
private void initSpriteSheets() { | |
this.spriteSheets = new ArrayList<>(); | |
IntStream.iterate(0, n -> n+1).limit(nbDistinctSheets).forEach(n -> { | |
System.out.println("Loading sheet #" + n + "..."); | |
Texture texture = new Texture(new FileHandle("./pv-client/src/test/resources/ant_running_17frames.png")); | |
TextureRegion[][] singleDimensionalArray = TextureRegion.split(texture, 384, 384); | |
this.spriteSheets.add(singleDimensionalArray); | |
}); | |
} | |
private void initAnimations() { | |
this.testAnimations = new HashMap<>(); | |
IntStream.iterate(0, n -> n+1).limit(nbAnimations).forEach(n -> { | |
int electedIdx = n % nbDistinctSheets; | |
System.out.println("Elected sheet #" + electedIdx + " creating animation #" + n + "..."); | |
TextureRegion[][] electedSheet = spriteSheets.get(electedIdx); | |
Animation<TextureRegion> animation = new Animation<>(18, electedSheet[0]); | |
animation.setPlayMode(Animation.PlayMode.LOOP); | |
int spreadFactor = 1000 / nbAnimations; | |
int x = (int)Math.round(Math.random()*(nbAnimations/2) * spreadFactor); | |
int y = (int)Math.round(Math.random()*(nbAnimations/2) * spreadFactor); | |
testAnimations.put(new AbstractMap.SimpleEntry(x, y), animation); | |
System.out.println("Added sheet #" + electedIdx + " for animation #" +n + "."); | |
}); | |
} | |
@Override | |
public void render() { | |
renderingCounter[0]++; | |
if(renderingCounter[0] % 100 == 0) { | |
System.out.println("Main render loop, memory = " + (getTotalMemory() - getFreeMemory()) / 1024 / 1024 + " MB"); | |
} | |
actuallyRender(); | |
} | |
private void actuallyRender() { | |
Gdx.gl20.glClearColor(0f / 255f, 0f / 255f, 0f / 255f, 1f); | |
//Gdx.gl20.glClearColor(255f / 255f, 255f / 255f, 255f / 255f, 1f); | |
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT); | |
this.stateTime+=Gdx.graphics.getDeltaTime()*1024; | |
batch.begin(); | |
AtomicInteger currentIdx = new AtomicInteger(); | |
testAnimations.entrySet().forEach(e -> { | |
currentIdx.getAndIncrement(); | |
float floatStateTime = (float) (stateTime + currentIdx.get() * 1024); | |
//System.out.println("Drawing from sheet #"); | |
TextureRegion keyFrame = e.getValue().getKeyFrame(floatStateTime); | |
//System.out.println("time=" + floatStateTime + "; idx=" + testAnimation.getKeyFrameIndex(floatStateTime) + " -> u=" + keyFrame.getU() + "; v=" + keyFrame.getV() + "; u2=" + keyFrame.getU2() + "; v2=" + keyFrame.getV2() + "; "); | |
batch.draw(keyFrame, (Integer)e.getKey().getKey(), (Integer)e.getKey().getValue()); | |
}); | |
batch.end(); | |
drawFps(); | |
} | |
private void drawFps() { | |
int width = Gdx.graphics.getWidth(); | |
int height = Gdx.graphics.getHeight(); | |
batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height); | |
batch.begin(); | |
font.draw(batch, "FPS: " + Gdx.graphics.getFramesPerSecond(), 50, height - 50); | |
batch.end(); | |
} | |
private long getFreeMemory() { | |
return ((com.sun.management.OperatingSystemMXBean) | |
ManagementFactory.getOperatingSystemMXBean()).getFreePhysicalMemorySize(); | |
} | |
private long getTotalMemory() { | |
return ((com.sun.management.OperatingSystemMXBean) | |
ManagementFactory.getOperatingSystemMXBean()).getTotalMemorySize(); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment