Pārlūkot izejas kodu

use CacheAllocator on Graphics and TileGroup

trethaller 5 gadi atpakaļ
vecāks
revīzija
a9686c3bab
4 mainītis faili ar 83 papildinājumiem un 16 dzēšanām
  1. 24 11
      h2d/Graphics.hx
  2. 11 3
      h2d/TileGroup.hx
  3. 23 1
      hxd/impl/Allocator.hx
  4. 25 1
      hxd/impl/CacheAllocator.hx

+ 24 - 11
h2d/Graphics.hx

@@ -1,5 +1,6 @@
 package h2d;
 import hxd.Math;
+import hxd.impl.Allocator;
 
 private typedef GraphicsPoint = hxd.poly2tri.Point;
 
@@ -73,14 +74,15 @@ private class GraphicsContent extends h3d.prim.Primitive {
 
 	override function alloc( engine : h3d.Engine ) {
 		if (index.length <= 0) return ;
-		buffer = h3d.Buffer.ofFloats(tmp, 8, [RawFormat]);
+		var alloc = Allocator.get();
+		buffer = alloc.ofFloats(tmp, 8, RawFormat);
 		#if track_alloc
 		@:privateAccess buffer.allocPos = allocPos;
 		#end
-		indexes = h3d.Indexes.alloc(index);
+		indexes = alloc.ofIndexes(index);
 		for( b in buffers ) {
-			if( b.vbuf == null || b.vbuf.isDisposed() ) b.vbuf = h3d.Buffer.ofFloats(b.buf, 8, [RawFormat]);
-			if( b.ibuf == null || b.ibuf.isDisposed() ) b.ibuf = h3d.Indexes.alloc(b.idx);
+			if( b.vbuf == null || b.vbuf.isDisposed() ) b.vbuf = alloc.ofFloats(b.buf, 8, RawFormat);
+			if( b.ibuf == null || b.ibuf.isDisposed() ) b.ibuf = alloc.ofIndexes(b.idx);
 		}
 		bufferDirty = false;
 		indexDirty = false;
@@ -94,18 +96,19 @@ private class GraphicsContent extends h3d.prim.Primitive {
 		super.render(engine);
 	}
 
-	public inline function flush() {
+	public function flush() {
 		if( buffer == null || buffer.isDisposed() ) {
 			alloc(h3d.Engine.getCurrent());
 		} else {
+			var allocator = Allocator.get();
 			if ( bufferDirty ) {
-				buffer.dispose();
-				buffer = h3d.Buffer.ofFloats(tmp, 8, [RawFormat]);
+				allocator.disposeBuffer(buffer);
+				buffer = allocator.ofFloats(tmp, 8, RawFormat);
 				bufferDirty = false;
 			}
 			if ( indexDirty ) {
-				indexes.dispose();
-				indexes = h3d.Indexes.alloc(index);
+				allocator.disposeIndexBuffer(indexes);
+				indexes = allocator.ofIndexes(index);
 				indexDirty = false;
 			}
 		}
@@ -113,11 +116,21 @@ private class GraphicsContent extends h3d.prim.Primitive {
 
 	override function dispose() {
 		for( b in buffers ) {
-			if( b.vbuf != null ) b.vbuf.dispose();
-			if( b.ibuf != null ) b.ibuf.dispose();
+			if( b.vbuf != null ) Allocator.get().disposeBuffer(b.vbuf);
+			if( b.ibuf != null ) Allocator.get().disposeIndexBuffer(b.ibuf);
 			b.vbuf = null;
 			b.ibuf = null;
 		}
+
+		if( buffer != null ) {
+			Allocator.get().disposeBuffer(buffer);
+			buffer = null;
+		}
+		if( indexes != null ) {
+			Allocator.get().disposeIndexBuffer(indexes);
+			indexes = null;
+		}
+		
 		super.dispose();
 	}
 

+ 11 - 3
h2d/TileGroup.hx

@@ -20,7 +20,7 @@ class TileLayerContent extends h3d.prim.Primitive {
 
 	public function clear() {
 		tmp = new hxd.FloatBuffer();
-		if( buffer != null ) buffer.dispose();
+		if( buffer != null ) hxd.impl.Allocator.get().disposeBuffer(buffer);
 		buffer = null;
 		xMin = hxd.Math.POSITIVE_INFINITY;
 		yMin = hxd.Math.POSITIVE_INFINITY;
@@ -244,7 +244,7 @@ class TileLayerContent extends h3d.prim.Primitive {
 		y += h;
 		if( x > xMax ) xMax = x;
 		if( y > yMax ) yMax = y;
-		
+
 		state.add(4);
 	}
 
@@ -402,8 +402,16 @@ class TileLayerContent extends h3d.prim.Primitive {
 	override public function alloc(engine:h3d.Engine) {
 		if( tmp == null ) clear();
 		if( tmp.length > 0 ) {
-			buffer = h3d.Buffer.ofFloats(tmp, 8, [Quads, RawFormat]);
+			buffer = hxd.impl.Allocator.get().ofFloats(tmp, 8, RawQuads);
+		}
+	}
+
+	override function dispose() {
+		if( buffer != null ) {
+			hxd.impl.Allocator.get().disposeBuffer(buffer);
+			buffer = null;
 		}
+		super.dispose();
 	}
 
 	public inline function flush() {

+ 23 - 1
hxd/impl/Allocator.hx

@@ -3,6 +3,8 @@ package hxd.impl;
 @:enum abstract BufferFlags(Int) {
 	public var Dynamic = 0;
 	public var UniformDynamic = 1;
+	public var RawFormat = 2;
+	public var RawQuads = 3;
 	public inline function toInt() : Int {
 		return this;
 	}
@@ -16,7 +18,20 @@ class Allocator {
 	// GPU
 
 	public function allocBuffer( vertices : Int, stride : Int, flags : BufferFlags ) : h3d.Buffer {
-		return new h3d.Buffer(vertices, stride, switch( flags ) { case Dynamic: [Dynamic]; case UniformDynamic: [UniformBuffer,Dynamic]; });
+		return new h3d.Buffer(vertices, stride,
+			switch( flags ) {
+				case Dynamic: [Dynamic];
+				case UniformDynamic: [UniformBuffer,Dynamic];
+				case RawFormat: [RawFormat];
+				case RawQuads: [Quads, RawFormat];
+			});
+	}
+
+	public function ofFloats( v : hxd.FloatBuffer, stride : Int, flags : BufferFlags ) {
+		var nvert = Std.int(v.length / stride);
+		var b = allocBuffer(nvert, stride, flags);
+		b.uploadVector(v, 0, nvert);
+		return b;
 	}
 
 	public function disposeBuffer( b : h3d.Buffer ) {
@@ -27,6 +42,13 @@ class Allocator {
 		return new h3d.Indexes(count);
 	}
 
+	public function ofIndexes( ib: hxd.IndexBuffer, length = -1) {
+		if( length < 0 && ib != null ) length = ib.length;
+		var idx = allocIndexBuffer( length );
+		idx.upload(ib, 0, length);
+		return idx;
+	}
+
 	public function disposeIndexBuffer( i : h3d.Indexes ) {
 		i.dispose();
 	}

+ 25 - 1
hxd/impl/CacheAllocator.hx

@@ -28,6 +28,7 @@ private class Cache<T> {
 class CacheAllocator extends Allocator {
 
 	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)
@@ -47,7 +48,8 @@ class CacheAllocator extends Allocator {
 	}
 
 	override function disposeBuffer(b:h3d.Buffer) {
-		var flags = b.flags.has(UniformBuffer) ? UniformDynamic : Dynamic;
+		var f = b.flags;
+		var flags = f.has(RawFormat) ? (f.has(Quads) ? RawQuads : RawFormat) : (f.has(UniformBuffer) ? UniformDynamic : Dynamic);
 		var id = flags.toInt() | (b.buffer.stride << 3) | (b.vertices << 16);
 		var c = buffers.get(id);
 		if( c == null ) {
@@ -58,6 +60,28 @@ class CacheAllocator extends Allocator {
 		checkGC();
 	}
 
+	override function allocIndexBuffer( count : Int ) {
+		var id = count;
+		var c = indexBuffers.get(id);
+		if( c != null ) {
+			var i = c.get();
+			if( i != null ) return i;
+		}
+		checkGC();
+		return super.allocIndexBuffer(count);
+	}
+
+	override function disposeIndexBuffer( i : h3d.Indexes ) {
+		var id = i.count;
+		var c = indexBuffers.get(id);
+		if( c == null ) {
+			c = new Cache(function(i:h3d.Indexes) i.dispose());
+			indexBuffers.set(id, c);
+		}
+		c.put(i);
+		checkGC();
+	}
+
 	override function onContextLost() {
 		buffers = new Map();
 	}