SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/utils/GLStamper.java

98 lines
2.7 KiB
Java

package speiger.src.coreengine.rendering.utils;
import java.util.Iterator;
import java.util.Set;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL33;
import speiger.src.collections.ints.collections.IntStack;
import speiger.src.collections.ints.lists.IntArrayList;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
import speiger.src.collections.objects.sets.ObjectLinkedOpenHashSet;
import speiger.src.collections.utils.Stack;
public class GLStamper {
public static GLStamper INSTANCE = new GLStamper();
Object2ObjectMap<String, Set<GLStamp>> stamps = Object2ObjectMap.builder().linkedMap();
Stack<GLStamp> unusedStamps = new ObjectArrayList<>();
IntStack queryIDs = new IntArrayList();
public GLStamp createStamp(String ownerID) {
Set<GLStamp> list = stamps.supplyIfAbsent(ownerID, ObjectLinkedOpenHashSet::new);
GLStamp stamp = unusedStamps.isEmpty() ? new GLStamp(this) : unusedStamps.pop();
stamp.setOwner(ownerID);
list.add(stamp);
return stamp;
}
public void removeOwner(String ownerID) {
Set<GLStamp> set = stamps.remove(ownerID);
if(set == null) return;
set.forEach(GLStamp::release);
}
public void cleanup() {
if(!stamps.isEmpty()) {
for(Iterator<Set<GLStamp>> iter = stamps.values().iterator();iter.hasNext();iter.remove()) {
iter.next().forEach(GLStamp::release);
}
}
if(queryIDs.isEmpty()) return;
GL15.glDeleteQueries(queryIDs.toIntArray());
queryIDs.clear();
}
protected void release(GLStamp stamp) {
Set<GLStamp> set = stamps.get(stamp.getOwner());
if(set != null) set.remove(stamp);
unusedStamps.push(stamp);
}
protected int getQueryID() {
int id = queryIDs.isEmpty() ? GL15.glGenQueries() : queryIDs.pop();
GL33.glQueryCounter(id, GL33.GL_TIMESTAMP);
return id;
}
protected void releaseQueryID(int id) {
if(id != -1) queryIDs.push(id);
}
public static class GLStamp {
GLStamper stamp;
String owner;
int startID = -1;
int endID = -1;
private GLStamp(GLStamper owner) {
stamp = owner;
}
void setOwner(String owner) { this.owner = owner; }
String getOwner() { return owner; }
public GLStamp start() {
if(startID == -1) startID = stamp.getQueryID();
return this;
}
public GLStamp stop() {
if(endID == -1) endID = stamp.getQueryID();
return this;
}
public void release() {
stamp.releaseQueryID(startID);
stamp.releaseQueryID(endID);
stamp.release(this);
startID = -1;
endID = -1;
}
public boolean isFinished() { return GL15.glGetQueryObjectui(endID, GL15.GL_QUERY_RESULT_AVAILABLE) == 1; }
public long getResult() { return GL33.glGetQueryObjectui64(endID, GL15.GL_QUERY_RESULT) - GL33.glGetQueryObjectui64(startID, GL15.GL_QUERY_RESULT); }
}
}