|
@@ -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;
|
|
|
}
|
|
|
|