Browse Source

added frame delay to prevent buffer reuse on same frame (close #925)

Nicolas Cannasse 4 years ago
parent
commit
c6f5de8dfe
1 changed files with 37 additions and 5 deletions
  1. 37 5
      hxd/impl/CacheAllocator.hx

+ 37 - 5
hxd/impl/CacheAllocator.hx

@@ -2,22 +2,35 @@ package hxd.impl;
 import hxd.impl.Allocator;
 
 private class Cache<T> {
-	public var content : Array<T> = [];
+	public var available : Array<T> = [];
+	public var disposed : Array<T> = [];
 	public var lastUse : Float = haxe.Timer.stamp();
 	public var onDispose : T -> Void;
+
 	public function new( ?dispose ) {
 		onDispose = dispose;
 	}
 	public inline function get() {
-		var b = content.pop();
-		if( content.length == 0 ) lastUse = haxe.Timer.stamp();
+		var b = available.pop();
+		if( available.length == 0 ) lastUse = haxe.Timer.stamp();
 		return b;
 	}
+
 	public inline function put(v) {
-		content.push(v);
+		disposed.push(v);
 	}
+
+	public function nextFrame() {
+		while( available.length > 0 )
+			disposed.push(available.pop());
+		var tmp = available;
+		available = disposed;
+		disposed = tmp;
+	}
+
 	public function gc() {
-		var b = content.pop();
+		var b = available.pop();
+		if( b == null ) b = disposed.pop();
 		if( b == null ) return false;
 		if( onDispose != null ) onDispose(b);
 		lastUse += 1;
@@ -27,8 +40,10 @@ private class Cache<T> {
 
 class CacheAllocator extends Allocator {
 
+	public var currentFrame = -1;
 	var buffers = new Map<Int,Cache<h3d.Buffer>>();
 	var indexBuffers = new Map<Int,Cache<h3d.Indexes>>();
+
 	var lastGC = haxe.Timer.stamp();
 	/**
 	 * How long do we keep some buffer than hasn't been used in memory (in seconds, default 60)
@@ -37,6 +52,7 @@ class CacheAllocator extends Allocator {
 
 	override function allocBuffer(vertices:Int, stride:Int, flags:BufferFlags):h3d.Buffer {
 		if( vertices >= 65536 ) throw "assert";
+		checkFrame();
 		var id = flags.toInt() | (stride << 3) | (vertices << 16);
 		var c = buffers.get(id);
 		if( c != null ) {
@@ -62,6 +78,7 @@ class CacheAllocator extends Allocator {
 
 	override function allocIndexBuffer( count : Int ) {
 		var id = count;
+		checkFrame();
 		var c = indexBuffers.get(id);
 		if( c != null ) {
 			var i = c.get();
@@ -87,6 +104,16 @@ class CacheAllocator extends Allocator {
 		indexBuffers = new Map();
 	}
 
+	public function checkFrame() {
+		if( currentFrame == hxd.Timer.frameCount )
+			return;
+		currentFrame = hxd.Timer.frameCount;
+		for( b in buffers )
+			b.nextFrame();
+		for( b in indexBuffers )
+			b.nextFrame();
+	}
+
 	public function checkGC() {
 		var t = haxe.Timer.stamp();
 		if( t - lastGC > maxKeepTime * 0.1 ) gc();
@@ -99,6 +126,11 @@ class CacheAllocator extends Allocator {
 			if( now - c.lastUse > maxKeepTime && !c.gc() )
 				buffers.remove(b);
 		}
+		for( b in indexBuffers.keys() ) {
+			var c = indexBuffers.get(b);
+			if( now - c.lastUse > maxKeepTime && !c.gc() )
+				indexBuffers.remove(b);
+		}
 		lastGC = now;
 	}