Browse Source

optimized VertexBuffer to use native Float32Array (huge speedup on Chrome)

Nicolas Cannasse 8 years ago
parent
commit
8d5d6d76c6
2 changed files with 45 additions and 7 deletions
  1. 2 2
      h3d/impl/GlDriver.hx
  2. 43 5
      hxd/FloatBuffer.hx

+ 2 - 2
h3d/impl/GlDriver.hx

@@ -867,7 +867,7 @@ class GlDriver extends Driver {
 		var data = #if hl hl.Bytes.getArray(buf.getNative()) #else buf.getNative() #end;
 		var data = #if hl hl.Bytes.getArray(buf.getNative()) #else buf.getNative() #end;
 		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, streamData(data,bufPos * 4,vertexCount * stride * 4), bufPos * 4 * STREAM_POS, vertexCount * stride * 4);
 		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, streamData(data,bufPos * 4,vertexCount * stride * 4), bufPos * 4 * STREAM_POS, vertexCount * stride * 4);
 		#else
 		#else
-		var buf = new Float32Array(buf.getNative());
+		var buf : Float32Array = buf.getNative();
 		var sub = new Float32Array(buf.buffer, bufPos * 4, vertexCount * stride);
 		var sub = new Float32Array(buf.buffer, bufPos * 4, vertexCount * stride);
 		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, sub);
 		gl.bufferSubData(GL.ARRAY_BUFFER, startVertex * stride * 4, sub);
 		#end
 		#end
@@ -1076,7 +1076,7 @@ class GlDriver extends Driver {
 		// wait until all assets have properly load
 		// wait until all assets have properly load
 		if( js.Browser.document.readyState == 'complete' )
 		if( js.Browser.document.readyState == 'complete' )
 			haxe.Timer.delay(onCreate.bind(false), 1);
 			haxe.Timer.delay(onCreate.bind(false), 1);
-		else		
+		else
 			js.Browser.window.addEventListener("load", function(_) {
 			js.Browser.window.addEventListener("load", function(_) {
 				if( !ready ) {
 				if( !ready ) {
 					ready = true;
 					ready = true;

+ 43 - 5
hxd/FloatBuffer.hx

@@ -1,6 +1,46 @@
 package hxd;
 package hxd;
 
 
-private typedef InnerData = #if flash flash.Vector<Float> #else Array<hxd.impl.Float32> #end
+private typedef InnerData = #if flash flash.Vector<Float> #elseif js Float32Expand #else Array<hxd.impl.Float32> #end
+
+#if js
+private abstract Float32Expand({ pos : Int, array : js.html.Float32Array }) {
+
+	public var length(get, set) : Int;
+
+	public function new(length) {
+		this = { pos : 0, array : new js.html.Float32Array(new js.html.ArrayBuffer(length)) };
+	}
+
+	inline function get_length() return this.array.length;
+	inline function set_length(v:Int) {
+		if( length != v ) {
+			var newArray = new js.html.Float32Array(v);
+			newArray.set(this.array);
+			this.array = newArray;
+		}
+		this.pos = v;
+		return v;
+	}
+
+	public inline function push(v:Float) {
+		if( this.pos == this.array.length ) {
+			var newSize = this.array.length << 1;
+			if( newSize < 128 ) newSize = 128;
+			var newArray = new js.html.Float32Array(newSize);
+			newArray.set(this.array);
+			this.array = newArray;
+		}
+		this.array[this.pos++] = v;
+	}
+
+	@:arrayAccess inline function get(index) return this.array[index];
+	@:arrayAccess inline function set(index,v:Float) return this.array[index] = v;
+
+	@:to inline function toF32Array() return this.array;
+	@:to inline function toArray() return [for( i in 0...this.pos ) this.array[i]];
+
+}
+#end
 
 
 private class InnerIterator {
 private class InnerIterator {
 	var b : InnerData;
 	var b : InnerData;
@@ -24,9 +64,7 @@ abstract FloatBuffer(InnerData) {
 	public var length(get, never) : Int;
 	public var length(get, never) : Int;
 
 
 	public inline function new(length = 0) {
 	public inline function new(length = 0) {
-		#if js
-		this = untyped __new__(Array, length);
-		#elseif flash
+		#if (flash || js)
 		this = new InnerData(length);
 		this = new InnerData(length);
 		#else
 		#else
 		this = new InnerData();
 		this = new InnerData();
@@ -54,7 +92,7 @@ abstract FloatBuffer(InnerData) {
 	}
 	}
 
 
 	public inline function resize( v : Int ) {
 	public inline function resize( v : Int ) {
-		#if flash
+		#if (flash||js)
 		this.length = v;
 		this.length = v;
 		#else
 		#else
 		if( this.length > v ) this.splice(v, this.length - v) else grow(v);
 		if( this.length > v ) this.splice(v, this.length - v) else grow(v);