* Add NativeObject.dispose() which deletes the object from GL driver, and if UNSAFE=true, also native buffers.
* Rename NativeObjectManager.registerForCleanup() -> registerObject() so that its not confused with enqueueUnusedObject() git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10618 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
bf2a663022
commit
d6fbd97482
@ -296,7 +296,7 @@ public class AndroidOpenALSoftAudioRenderer implements AndroidAudioRenderer, Run
|
|||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
f.setId(id);
|
f.setId(id);
|
||||||
|
|
||||||
objManager.registerForCleanup(f);
|
objManager.registerObject(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f instanceof LowPassFilter) {
|
if (f instanceof LowPassFilter) {
|
||||||
@ -1212,7 +1212,7 @@ public class AndroidOpenALSoftAudioRenderer implements AndroidAudioRenderer, Run
|
|||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
ab.setId(id);
|
ab.setId(id);
|
||||||
|
|
||||||
objManager.registerForCleanup(ab);
|
objManager.registerObject(ab);
|
||||||
}
|
}
|
||||||
|
|
||||||
ab.getData().clear();
|
ab.getData().clear();
|
||||||
|
@ -942,7 +942,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
shader.clearUpdateNeeded();
|
shader.clearUpdateNeeded();
|
||||||
if (needRegister) {
|
if (needRegister) {
|
||||||
// Register shader for clean up if it was created in this method.
|
// Register shader for clean up if it was created in this method.
|
||||||
objManager.registerForCleanup(shader);
|
objManager.registerObject(shader);
|
||||||
statistics.onNewShader();
|
statistics.onNewShader();
|
||||||
} else {
|
} else {
|
||||||
// OpenGL spec: uniform locations may change after re-link
|
// OpenGL spec: uniform locations may change after re-link
|
||||||
@ -1318,7 +1318,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
id = intBuf1.get(0);
|
id = intBuf1.get(0);
|
||||||
fb.setId(id);
|
fb.setId(id);
|
||||||
objManager.registerForCleanup(fb);
|
objManager.registerObject(fb);
|
||||||
|
|
||||||
statistics.onNewFrameBuffer();
|
statistics.onNewFrameBuffer();
|
||||||
}
|
}
|
||||||
@ -1673,7 +1673,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
texId = intBuf1.get(0);
|
texId = intBuf1.get(0);
|
||||||
img.setId(texId);
|
img.setId(texId);
|
||||||
objManager.registerForCleanup(img);
|
objManager.registerObject(img);
|
||||||
|
|
||||||
statistics.onNewTexture();
|
statistics.onNewTexture();
|
||||||
}
|
}
|
||||||
@ -1880,7 +1880,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
bufId = intBuf1.get(0);
|
bufId = intBuf1.get(0);
|
||||||
vb.setId(bufId);
|
vb.setId(bufId);
|
||||||
objManager.registerForCleanup(vb);
|
objManager.registerObject(vb);
|
||||||
|
|
||||||
created = true;
|
created = true;
|
||||||
}
|
}
|
||||||
@ -2252,14 +2252,9 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* renderMeshVertexArray renders a mesh using vertex arrays
|
* renderMeshVertexArray renders a mesh using vertex arrays
|
||||||
* @param mesh
|
|
||||||
* @param lod
|
|
||||||
* @param count
|
|
||||||
*/
|
*/
|
||||||
private void renderMeshVertexArray(Mesh mesh, int lod, int count) {
|
private void renderMeshVertexArray(Mesh mesh, int lod, int count) {
|
||||||
// IntMap<VertexBuffer> buffers = mesh.getBuffers();
|
for (VertexBuffer vb : mesh.getBufferList().getArray()) {
|
||||||
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
|
||||||
|
|
||||||
if (vb.getBufferType() == Type.InterleavedData
|
if (vb.getBufferType() == Type.InterleavedData
|
||||||
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
||||||
|| vb.getBufferType() == Type.Index) {
|
|| vb.getBufferType() == Type.Index) {
|
||||||
@ -2306,7 +2301,6 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal());
|
indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal());
|
||||||
}
|
}
|
||||||
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
||||||
|
|
||||||
if (vb.getBufferType() == Type.InterleavedData
|
if (vb.getBufferType() == Type.InterleavedData
|
||||||
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
||||||
|| vb.getBufferType() == Type.Index) {
|
|| vb.getBufferType() == Type.Index) {
|
||||||
|
@ -45,6 +45,11 @@ public abstract class NativeObject implements Cloneable {
|
|||||||
|
|
||||||
public static final int INVALID_ID = -1;
|
public static final int INVALID_ID = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object manager to which this NativeObject is registered to.
|
||||||
|
*/
|
||||||
|
protected NativeObjectManager objectManager = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ID of the object, usually depends on its type.
|
* The ID of the object, usually depends on its type.
|
||||||
* Typically returned from calls like glGenTextures, glGenBuffers, etc.
|
* Typically returned from calls like glGenTextures, glGenBuffers, etc.
|
||||||
@ -82,9 +87,14 @@ public abstract class NativeObject implements Cloneable {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setNativeObjectManager(NativeObjectManager objectManager) {
|
||||||
|
this.objectManager = objectManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the ID of the GLObject. This method is used in Renderer and must
|
* Sets the ID of the NativeObject. This method is used in Renderer and must
|
||||||
* not be called by the user.
|
* not be called by the user.
|
||||||
|
*
|
||||||
* @param id The ID to set
|
* @param id The ID to set
|
||||||
*/
|
*/
|
||||||
public void setId(int id){
|
public void setId(int id){
|
||||||
@ -138,6 +148,7 @@ public abstract class NativeObject implements Cloneable {
|
|||||||
try {
|
try {
|
||||||
NativeObject obj = (NativeObject) super.clone();
|
NativeObject obj = (NativeObject) super.clone();
|
||||||
obj.handleRef = new Object();
|
obj.handleRef = new Object();
|
||||||
|
obj.objectManager = null;
|
||||||
obj.id = INVALID_ID;
|
obj.id = INVALID_ID;
|
||||||
obj.updateNeeded = true;
|
obj.updateNeeded = true;
|
||||||
return obj;
|
return obj;
|
||||||
@ -187,4 +198,17 @@ public abstract class NativeObject implements Cloneable {
|
|||||||
* should be functional for this object.
|
* should be functional for this object.
|
||||||
*/
|
*/
|
||||||
public abstract NativeObject createDestructableClone();
|
public abstract NativeObject createDestructableClone();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reclaims native resources used by this NativeObject.
|
||||||
|
* It should be safe to call this method or even use the object
|
||||||
|
* after it has been reclaimed, unless {@link NativeObjectManager#UNSAFE} is
|
||||||
|
* set to true, in that case native buffers are also reclaimed which may
|
||||||
|
* introduce instability.
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
if (objectManager != null) {
|
||||||
|
objectManager.markUnusedObject(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,11 +31,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.util;
|
package com.jme3.util;
|
||||||
|
|
||||||
import com.jme3.scene.VertexBuffer;
|
import com.jme3.renderer.Renderer;
|
||||||
import java.lang.ref.PhantomReference;
|
import java.lang.ref.PhantomReference;
|
||||||
import java.lang.ref.ReferenceQueue;
|
import java.lang.ref.ReferenceQueue;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.HashSet;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -51,6 +53,13 @@ public class NativeObjectManager {
|
|||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(NativeObjectManager.class.getName());
|
private static final Logger logger = Logger.getLogger(NativeObjectManager.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to <code>true</code> to enable deletion of native buffers together with GL objects
|
||||||
|
* when requested. Note that usage of object after deletion could cause undefined results
|
||||||
|
* or native crashes, therefore by default this is set to <code>false</code>.
|
||||||
|
*/
|
||||||
|
public static boolean UNSAFE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of objects that should be removed per frame.
|
* The maximum number of objects that should be removed per frame.
|
||||||
* If the limit is reached, no more objects will be removed for that frame.
|
* If the limit is reached, no more objects will be removed for that frame.
|
||||||
@ -58,23 +67,26 @@ public class NativeObjectManager {
|
|||||||
private static final int MAX_REMOVES_PER_FRAME = 100;
|
private static final int MAX_REMOVES_PER_FRAME = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The queue will receive notifications of {@link NativeObject}s which
|
* Reference queue for {@link NativeObjectRef native object references}.
|
||||||
* are no longer referenced.
|
|
||||||
*/
|
*/
|
||||||
private ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
|
private ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of currently active GLObjects.
|
* List of currently active GLObjects.
|
||||||
*/
|
*/
|
||||||
private HashSet<NativeObjectRef> refList
|
private IntMap<NativeObjectRef> refMap = new IntMap<NativeObjectRef>();
|
||||||
= new HashSet<NativeObjectRef>();
|
|
||||||
|
|
||||||
private class NativeObjectRef extends PhantomReference<Object>{
|
/**
|
||||||
|
* List of real objects requested by user for deletion.
|
||||||
|
*/
|
||||||
|
private ArrayDeque<NativeObject> userDeletionQueue = new ArrayDeque<NativeObject>();
|
||||||
|
|
||||||
|
private static class NativeObjectRef extends PhantomReference<Object> {
|
||||||
|
|
||||||
private NativeObject objClone;
|
private NativeObject objClone;
|
||||||
private WeakReference<NativeObject> realObj;
|
private WeakReference<NativeObject> realObj;
|
||||||
|
|
||||||
public NativeObjectRef(NativeObject obj){
|
public NativeObjectRef(ReferenceQueue<Object> refQueue, NativeObject obj){
|
||||||
super(obj.handleRef, refQueue);
|
super(obj.handleRef, refQueue);
|
||||||
assert obj.handleRef != null;
|
assert obj.handleRef != null;
|
||||||
|
|
||||||
@ -84,18 +96,68 @@ public class NativeObjectManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a GLObject with the manager.
|
* (Internal use only) Register a <code>NativeObject</code> with the manager.
|
||||||
*/
|
*/
|
||||||
public void registerForCleanup(NativeObject obj){
|
public void registerObject(NativeObject obj) {
|
||||||
NativeObjectRef ref = new NativeObjectRef(obj);
|
if (obj.getId() <= 0) {
|
||||||
refList.add(ref);
|
throw new IllegalArgumentException("object id must be greater than zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeObjectRef ref = new NativeObjectRef(refQueue, obj);
|
||||||
|
refMap.put(obj.getId(), ref);
|
||||||
|
|
||||||
|
obj.setNativeObjectManager(this);
|
||||||
|
|
||||||
if (logger.isLoggable(Level.FINEST)) {
|
if (logger.isLoggable(Level.FINEST)) {
|
||||||
logger.log(Level.FINEST, "Registered: {0}", new String[]{obj.toString()});
|
logger.log(Level.FINEST, "Registered: {0}", new String[]{obj.toString()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void deleteNativeObject(Object rendererObject, NativeObject obj, NativeObjectRef ref,
|
||||||
|
boolean deleteGL, boolean deleteBufs) {
|
||||||
|
assert rendererObject != null;
|
||||||
|
|
||||||
|
// "obj" is considered the real object (with buffers and everything else)
|
||||||
|
// if "ref" is null.
|
||||||
|
NativeObject realObj = ref != null ?
|
||||||
|
ref.realObj.get() :
|
||||||
|
obj;
|
||||||
|
|
||||||
|
assert realObj == null || obj.getId() == realObj.getId();
|
||||||
|
|
||||||
|
if (deleteGL && obj.getId() > 0) {
|
||||||
|
// Unregister it from cleanup list.
|
||||||
|
NativeObjectRef ref2 = refMap.remove(obj.getId());
|
||||||
|
if (ref2 == null) {
|
||||||
|
throw new IllegalArgumentException("This NativeObject is not " +
|
||||||
|
"registered in this NativeObjectManager");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert ref == null || ref == ref2;
|
||||||
|
|
||||||
|
// Delete object from the GL driver
|
||||||
|
obj.deleteObject(rendererObject);
|
||||||
|
assert obj.getId() == NativeObject.INVALID_ID;
|
||||||
|
|
||||||
|
if (logger.isLoggable(Level.FINEST)) {
|
||||||
|
logger.log(Level.FINEST, "Deleted: {0}", obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (realObj != null){
|
||||||
|
// Note: make sure to reset them as well
|
||||||
|
// They may get used in a new renderer in the future
|
||||||
|
realObj.resetObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deleteBufs && UNSAFE && realObj != null) {
|
||||||
|
// Only the real object has native buffers.
|
||||||
|
// The destructable clone has nothing and cannot be used in this case.
|
||||||
|
realObj.deleteNativeBuffersInternal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes unused NativeObjects.
|
* (Internal use only) Deletes unused NativeObjects.
|
||||||
* Will delete at most {@link #MAX_REMOVES_PER_FRAME} objects.
|
* Will delete at most {@link #MAX_REMOVES_PER_FRAME} objects.
|
||||||
*
|
*
|
||||||
* @param rendererObject The renderer object.
|
* @param rendererObject The renderer object.
|
||||||
@ -103,14 +165,20 @@ public class NativeObjectManager {
|
|||||||
*/
|
*/
|
||||||
public void deleteUnused(Object rendererObject){
|
public void deleteUnused(Object rendererObject){
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
|
while (removed < MAX_REMOVES_PER_FRAME && !userDeletionQueue.isEmpty()) {
|
||||||
|
// Remove user requested objects.
|
||||||
|
NativeObject obj = userDeletionQueue.pop();
|
||||||
|
deleteNativeObject(rendererObject, obj, null, true, true);
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
while (removed < MAX_REMOVES_PER_FRAME) {
|
while (removed < MAX_REMOVES_PER_FRAME) {
|
||||||
|
// Remove objects reclaimed by GC.
|
||||||
NativeObjectRef ref = (NativeObjectRef) refQueue.poll();
|
NativeObjectRef ref = (NativeObjectRef) refQueue.poll();
|
||||||
if (ref == null) {
|
if (ref == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
refList.remove(ref);
|
deleteNativeObject(rendererObject, ref.objClone, ref, true, false);
|
||||||
ref.objClone.deleteObject(rendererObject);
|
|
||||||
removed++;
|
removed++;
|
||||||
}
|
}
|
||||||
if (removed >= 1) {
|
if (removed >= 1) {
|
||||||
@ -119,38 +187,49 @@ public class NativeObjectManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all objects. Must only be called when display is destroyed.
|
* (Internal use only) Deletes all objects.
|
||||||
|
* Must only be called when display is destroyed.
|
||||||
*/
|
*/
|
||||||
public void deleteAllObjects(Object rendererObject){
|
public void deleteAllObjects(Object rendererObject){
|
||||||
deleteUnused(rendererObject);
|
deleteUnused(rendererObject);
|
||||||
for (NativeObjectRef ref : refList){
|
for (IntMap.Entry<NativeObjectRef> entry : refMap) {
|
||||||
ref.objClone.deleteObject(rendererObject);
|
NativeObjectRef ref = entry.getValue();
|
||||||
NativeObject realObj = ref.realObj.get();
|
deleteNativeObject(rendererObject, ref.objClone, ref, true, false);
|
||||||
if (realObj != null){
|
|
||||||
// Note: make sure to reset them as well
|
|
||||||
// They may get used in a new renderer in the future
|
|
||||||
realObj.resetObject();
|
|
||||||
}
|
}
|
||||||
}
|
assert refMap.size() == 0;
|
||||||
refList.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets all {@link NativeObject}s.
|
* Marks the given <code>NativeObject</code> as unused,
|
||||||
|
* to be deleted on the next frame.
|
||||||
|
* Usage of this object after deletion will cause an exception.
|
||||||
|
* Note that native buffers are only reclaimed if
|
||||||
|
* {@link #UNSAFE} is set to <code>true</code>.
|
||||||
|
*
|
||||||
|
* @param obj The object to mark as unused.
|
||||||
|
*/
|
||||||
|
void enqueueUnusedObject(NativeObject obj) {
|
||||||
|
userDeletionQueue.push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Internal use only) Resets all {@link NativeObject}s.
|
||||||
|
* This is typically called when the context is restarted.
|
||||||
*/
|
*/
|
||||||
public void resetObjects(){
|
public void resetObjects(){
|
||||||
for (NativeObjectRef ref : refList){
|
for (IntMap.Entry<NativeObjectRef> entry : refMap) {
|
||||||
// here we use the actual obj not the clone,
|
// Must use the real object here, for this to be effective.
|
||||||
// otherwise its useless
|
NativeObject realObj = entry.getValue().realObj.get();
|
||||||
NativeObject realObj = ref.realObj.get();
|
if (realObj == null) {
|
||||||
if (realObj == null)
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
realObj.resetObject();
|
realObj.resetObject();
|
||||||
if (logger.isLoggable(Level.FINEST))
|
if (logger.isLoggable(Level.FINEST)) {
|
||||||
logger.log(Level.FINEST, "Reset: {0}", realObj);
|
logger.log(Level.FINEST, "Reset: {0}", realObj);
|
||||||
}
|
}
|
||||||
refList.clear();
|
}
|
||||||
|
refMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void printObjects(){
|
// public void printObjects(){
|
||||||
|
@ -294,7 +294,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
f.setId(id);
|
f.setId(id);
|
||||||
|
|
||||||
objManager.registerForCleanup(f);
|
objManager.registerObject(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f instanceof LowPassFilter) {
|
if (f instanceof LowPassFilter) {
|
||||||
@ -1033,7 +1033,7 @@ public class JoalAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
ab.setId(id);
|
ab.setId(id);
|
||||||
|
|
||||||
objManager.registerForCleanup(ab);
|
objManager.registerObject(ab);
|
||||||
}
|
}
|
||||||
|
|
||||||
ab.getData().clear();
|
ab.getData().clear();
|
||||||
|
@ -782,7 +782,7 @@ public class JoglGL1Renderer implements GL1Renderer {
|
|||||||
gl.glGenTextures(1, ib1);
|
gl.glGenTextures(1, ib1);
|
||||||
texId = ib1.get(0);
|
texId = ib1.get(0);
|
||||||
img.setId(texId);
|
img.setId(texId);
|
||||||
objManager.registerForCleanup(img);
|
objManager.registerObject(img);
|
||||||
|
|
||||||
statistics.onNewTexture();
|
statistics.onNewTexture();
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1143,7 @@ public class JoglRenderer implements Renderer {
|
|||||||
shader.clearUpdateNeeded();
|
shader.clearUpdateNeeded();
|
||||||
if (needRegister) {
|
if (needRegister) {
|
||||||
// Register shader for clean up if it was created in this method.
|
// Register shader for clean up if it was created in this method.
|
||||||
objManager.registerForCleanup(shader);
|
objManager.registerObject(shader);
|
||||||
statistics.onNewShader();
|
statistics.onNewShader();
|
||||||
} else {
|
} else {
|
||||||
// OpenGL spec: uniform locations may change after re-link
|
// OpenGL spec: uniform locations may change after re-link
|
||||||
@ -1506,7 +1506,7 @@ public class JoglRenderer implements Renderer {
|
|||||||
gl.glGenFramebuffers(1, intBuf1);
|
gl.glGenFramebuffers(1, intBuf1);
|
||||||
id = intBuf1.get(0);
|
id = intBuf1.get(0);
|
||||||
fb.setId(id);
|
fb.setId(id);
|
||||||
objManager.registerForCleanup(fb);
|
objManager.registerObject(fb);
|
||||||
|
|
||||||
statistics.onNewFrameBuffer();
|
statistics.onNewFrameBuffer();
|
||||||
}
|
}
|
||||||
@ -1899,7 +1899,7 @@ public class JoglRenderer implements Renderer {
|
|||||||
gl.glGenTextures(1, intBuf1);
|
gl.glGenTextures(1, intBuf1);
|
||||||
texId = intBuf1.get(0);
|
texId = intBuf1.get(0);
|
||||||
img.setId(texId);
|
img.setId(texId);
|
||||||
objManager.registerForCleanup(img);
|
objManager.registerObject(img);
|
||||||
|
|
||||||
statistics.onNewTexture();
|
statistics.onNewTexture();
|
||||||
}
|
}
|
||||||
@ -2141,7 +2141,7 @@ public class JoglRenderer implements Renderer {
|
|||||||
gl.glGenBuffers(1, intBuf1);
|
gl.glGenBuffers(1, intBuf1);
|
||||||
bufId = intBuf1.get(0);
|
bufId = intBuf1.get(0);
|
||||||
vb.setId(bufId);
|
vb.setId(bufId);
|
||||||
objManager.registerForCleanup(vb);
|
objManager.registerObject(vb);
|
||||||
|
|
||||||
//statistics.onNewVertexBuffer();
|
//statistics.onNewVertexBuffer();
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
f.setId(id);
|
f.setId(id);
|
||||||
|
|
||||||
objManager.registerForCleanup(f);
|
objManager.registerObject(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f instanceof LowPassFilter) {
|
if (f instanceof LowPassFilter) {
|
||||||
@ -1002,7 +1002,7 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable {
|
|||||||
id = ib.get(0);
|
id = ib.get(0);
|
||||||
ab.setId(id);
|
ab.setId(id);
|
||||||
|
|
||||||
objManager.registerForCleanup(ab);
|
objManager.registerObject(ab);
|
||||||
}
|
}
|
||||||
|
|
||||||
ab.getData().clear();
|
ab.getData().clear();
|
||||||
|
@ -729,7 +729,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
glGenTextures(ib1);
|
glGenTextures(ib1);
|
||||||
texId = ib1.get(0);
|
texId = ib1.get(0);
|
||||||
img.setId(texId);
|
img.setId(texId);
|
||||||
objManager.registerForCleanup(img);
|
objManager.registerObject(img);
|
||||||
|
|
||||||
statistics.onNewTexture();
|
statistics.onNewTexture();
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ import com.jme3.texture.Texture;
|
|||||||
import com.jme3.texture.Texture.WrapAxis;
|
import com.jme3.texture.Texture.WrapAxis;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
import com.jme3.util.ListMap;
|
import com.jme3.util.ListMap;
|
||||||
|
import com.jme3.util.NativeObject;
|
||||||
import com.jme3.util.NativeObjectManager;
|
import com.jme3.util.NativeObjectManager;
|
||||||
import com.jme3.util.SafeArrayList;
|
import com.jme3.util.SafeArrayList;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
@ -129,10 +130,12 @@ public class LwjglRenderer implements Renderer {
|
|||||||
nameBuf.rewind();
|
nameBuf.rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Statistics getStatistics() {
|
public Statistics getStatistics() {
|
||||||
return statistics;
|
return statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public EnumSet<Caps> getCaps() {
|
public EnumSet<Caps> getCaps() {
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
@ -1081,7 +1084,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
shader.clearUpdateNeeded();
|
shader.clearUpdateNeeded();
|
||||||
if (needRegister) {
|
if (needRegister) {
|
||||||
// Register shader for clean up if it was created in this method.
|
// Register shader for clean up if it was created in this method.
|
||||||
objManager.registerForCleanup(shader);
|
objManager.registerObject(shader);
|
||||||
statistics.onNewShader();
|
statistics.onNewShader();
|
||||||
} else {
|
} else {
|
||||||
// OpenGL spec: uniform locations may change after re-link
|
// OpenGL spec: uniform locations may change after re-link
|
||||||
@ -1431,7 +1434,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
glGenFramebuffersEXT(intBuf1);
|
glGenFramebuffersEXT(intBuf1);
|
||||||
id = intBuf1.get(0);
|
id = intBuf1.get(0);
|
||||||
fb.setId(id);
|
fb.setId(id);
|
||||||
objManager.registerForCleanup(fb);
|
objManager.registerObject(fb);
|
||||||
|
|
||||||
statistics.onNewFrameBuffer();
|
statistics.onNewFrameBuffer();
|
||||||
}
|
}
|
||||||
@ -1802,7 +1805,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
glGenTextures(intBuf1);
|
glGenTextures(intBuf1);
|
||||||
texId = intBuf1.get(0);
|
texId = intBuf1.get(0);
|
||||||
img.setId(texId);
|
img.setId(texId);
|
||||||
objManager.registerForCleanup(img);
|
objManager.registerObject(img);
|
||||||
|
|
||||||
statistics.onNewTexture();
|
statistics.onNewTexture();
|
||||||
}
|
}
|
||||||
@ -2041,7 +2044,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
glGenBuffers(intBuf1);
|
glGenBuffers(intBuf1);
|
||||||
bufId = intBuf1.get(0);
|
bufId = intBuf1.get(0);
|
||||||
vb.setId(bufId);
|
vb.setId(bufId);
|
||||||
objManager.registerForCleanup(vb);
|
objManager.registerObject(vb);
|
||||||
|
|
||||||
//statistics.onNewVertexBuffer();
|
//statistics.onNewVertexBuffer();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user