1) I can create texture from nothing using TextureRenderer. However to get rid of them I need a GL object (Texture.destroy). Am I supposed to perform memory management at the end of a rendering cycle (which's not the same as a processing cycle) because rendering is the only time a GL object is provided?
2) Is it safe to just manage normal RAM (and never get Out of VRAM)? From what I gather JOGL manage VRAM automatically and swap textures out as needed. |
Administrator
|
Hi
Release the OpenGL resources of a texture on a thread on which the OpenGL context is current. Reminder: Texture.destroy() just calls glDeleteTextures and sets its id to 0. You can do it as the end of a rendering cycle, preferably when you have a nice opportunity of not bothering the end user (during a pause or a transition typically in games). If you use a direct NIO buffer (for example when creating a TextureData), as it's allocated on the native heap, the garbage collector won't be called if you run out of native memory, it's up to you to use non public APIs (sun.misc.Cleaner) to release the native resources of a direct NIO buffer.
Julien Gouesse | Personal blog | Website
|
This post was updated on .
Urgh your answers was rather round-about. I hope I managed to read them right.
Lots of explaination. I hope it means calling Texture.destroy() at the end of a rendering cycle is still the recommended method? It's a 2D game, I use OpenGL mostly to speed up drawing. I use AWTTextureIO to import sprites and very seldomly TextureRenderer if I need to do some drawing in java itself. I use the textures produced by these classes as-is. I'm only concerned with texture performance. No poking into texture data, no pixel bit flipping, nothing brainy. Your explanation, while very insightful, regrettably didnt hit the mark :| |
Administrator
|
Calling Texture.destroy() directly in GLEventListener.display() or using GLAutoDrawable.invoke() at the end of a rendering cycle is ok. I tried to be very accurate in my explanation. You can't use JOGL without understanding the basic concepts of OpenGL.
At first, you shouldn't use AWT for games. I removed it from TUER mainly because a bug in full screen support under GNU Linux and I have a more steady frame rate now. Secondly, JOGL is open source, just look at its source code when you create a texture with AWTTextureIO: https://github.com/sgothel/jogl/blob/master/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureIO.java#L115 As you can see, AWTTextureIO creates a TextureData internally, an AWTTextureData with no flusher, then flush() does nothing. At the first sight, no direct NIO buffer is created as you can see here: https://github.com/sgothel/jogl/blob/master/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java#L479 It creates an undirect NIO buffer, whose memory is allocated on the Java heap. If you didn't look further, you could conclude that the garbage collector will take care of it and it's true. However, I'm almost sure that JOGL is forced to create a direct NIO buffer under the hood when using this call: https://github.com/sgothel/jogl/blob/master/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java#L1091 That's why I told you to take care of direct NIO buffers. AWTTextureData.getBuffer() returns the wrapped buffer, not this durect NIO buffer. If you used TextureIO instead of AWTTextureIO, the texture provider would return (probably) a TextureData using a direct NIO buffer and then you could get it with TextureData.getBuffer() in order to release its native memory with sun.misc.Cleaner... @Sven Why not adding a method TextureData.setFlusher()? Sorry for the very long explanation.
Julien Gouesse | Personal blog | Website
|
Sorry, "do X, get Y" is about as far as I will get with OpenGL at the moment. I'm not a book learner. "How does it work" never come before "How do I use it". Right now I'm not even yet comfortable with the syntax. I will get OpenGL working first before looking into it (Priority: nice to have. Reason: Linux). And please name an alternative. Now you're just admitting that Jogl is badly documented ;p And you're very round-about. At least I'm not getting the precise "do X, get Y" that I look for. I'm scared shitless whenever I hear "maybe", "perharp", "probably" and stuff along the line in a technical answer. "Dont use AWT, it has bugs under Linux" is a sound answer. "I'm almost sure it'd leak memory." isnt. I know that you're trying to help and I'm very thankful but sometimes your answer cause even more uncertainty. Anyway, heeding your warning concerning ByteBuffer, I have run some test: Test 1: create lots of textures with AWTTextureIO and doesnt destroy them. Result: Caused memory leaks that's not observed by the JVM until physical memory has run out, then some magic happened, keeping it in check. http://i.imgur.com/n95tV06.png Test 2: create lots of textures (100 times as big as in test 1, in fact) and use Texture.destroy(GL gl) to get rid of them. Result: Doesnt cause memory leak. Memory usage fluctuate stably between 200 and 300 MB. http://i.imgur.com/xZ9Ly2u.png Conclusion: Texture.destroy(GL gl) solves memory leak, walks the dog, sends flowers to the chick, keeps investors happy and puts food on the table. Disclaimer: FPS is not recorded. |
Administrator
|
Hi
I'm not a book learned neither. Don't be sorry but at a certain moment you won't be able to go further without a real understanding of the concepts. You can use NEWT. If you realize that you still need to use AWT, SWT or Swing, you'll still be able to use a NEWT canvas that can be integrated in interfaces based on those toolkits anyway (NewtCanvasAWT, NewtCanvasSWT). I just admit that I have spent a lot of my spare time in answering questions and contributing since 2006 and some aspects are really difficult to encapsulate in less low level APIs. Feel free to contribute. JogAmp is a community project after all. Moreover, yes JogAmp APIs are open source, it doesn't mean that they should be "badly" documented but it allows anybody to study their source code to understand how they work, it's a nice complement. On my view, being allowed to see both the documentation and the source code is really nice. Sometimes, there is no better explanation than the code itself. Your conclusion is wrong because of your lack of knowledge about how the JVM works. There is nothing magic. What happened is that by chance the JVM lacked of memory on the Java heap before lacking of memory on the native heap, a garbage collection was performed which avoided you to run out of memory. If the JVM lacked of memory on the native heap first, no garbage collection would have been performed. That's why I suggest you to go on using AWT until you find enough time to switch to NEWT but rather use Texture &TextureData with TextureIO, call TextureData.getBuffer() and use this example to really release its native memory: http://stackoverflow.com/a/8462733 I'm here to help people on the long term, that's why I explain everything in details so that you have a chance to become more autonomous and to understand the "solutions" I suggest. I don't want to tell you "do X, then do Y" without telling you why it works because I want to share this knowledge so that you can share it with someone else too, etc...
Julien Gouesse | Personal blog | Website
|
Free forum by Nabble | Edit this page |