2
0
Эх сурвалжийг харах

Allocation optimizations (#324)

Pascal Peridont 7 жил өмнө
parent
commit
07fc627a35

+ 24 - 8
h2d/RenderContext.hx

@@ -29,7 +29,8 @@ class RenderContext extends h3d.impl.RenderContext {
 	var baseShaderList : hxsl.ShaderList;
 	var currentObj : Drawable;
 	var stride : Int;
-	var targetsStack : Array<{ t : h3d.mat.Texture, x : Int, y : Int, w : Int, h : Int, renderZone : {x:Float,y:Float,w:Float,h:Float} }>;
+	var targetsStack : Array<{ t : h3d.mat.Texture, x : Int, y : Int, w : Int, h : Int, hasRZ : Bool, rzX:Float, rzY:Float, rzW:Float, rzH:Float }>;
+	var targetsStackIndex : Int;
 	var hasUVPos : Bool;
 	var filterStack : Array<h2d.Sprite>;
 	var inFilter : Sprite;
@@ -60,6 +61,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		baseShader.zValue = 0.;
 		baseShaderList = new hxsl.ShaderList(baseShader);
 		targetsStack = [];
+		targetsStackIndex = 0;
 		filterStack = [];
 		textures = new h3d.impl.TextureCache();
 	}
@@ -123,7 +125,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		texture = null;
 		currentObj = null;
 		baseShaderList.next = null;
-		if( targetsStack.length != 0 ) throw "Missing popTarget()";
+		if( targetsStackIndex != 0 ) throw "Missing popTarget()";
 	}
 
 	public function pushFilter( spr : h2d.Sprite ) {
@@ -152,7 +154,22 @@ class RenderContext extends h3d.impl.RenderContext {
 		if( height < 0 ) height = t == null ? scene.height : t.height;
 		baseShader.halfPixelInverse.set(0.5 / (t == null ? engine.width : t.width), 0.5 / (t == null ? engine.height : t.height));
 		baseShader.viewport.set( -width * 0.5 - startX, -height * 0.5 - startY, 2 / width, -2 / height);
-		targetsStack.push( { t : t, x : startX, y : startY, w : width, h : height, renderZone : hasRenderZone ? {x:renderX,y:renderY,w:renderW,h:renderH} : null } );
+		targetsStackIndex++;
+		if( targetsStackIndex > targetsStack.length ){
+			targetsStack.push( { t : t, x : startX, y : startY, w : width, h : height, hasRZ: hasRenderZone, rzX: renderX, rzY:renderY, rzW:renderW, rzH:renderH } );
+		}else{
+			var o = targetsStack[targetsStackIndex-1];
+			o.t = t;
+			o.x = startX;
+			o.y = startY;
+			o.w = width;
+			o.h = height;
+			o.hasRZ = hasRenderZone;
+			o.rzX = renderX;
+			o.rzY = renderY;
+			o.rzW = renderW;
+			o.rzH = renderH;
+		}
 		curX = startX;
 		curY = startY;
 		curWidth = width;
@@ -162,12 +179,12 @@ class RenderContext extends h3d.impl.RenderContext {
 
 	public function popTarget( restore = true ) {
 		flush();
-		var pinf = targetsStack.pop();
-		if( pinf == null ) throw "Too many popTarget()";
+		if( targetsStackIndex <= 0 ) throw "Too many popTarget()";
+		var pinf = targetsStack[--targetsStackIndex];
 		engine.popTarget();
 
 		if( restore ) {
-			var tinf = targetsStack[targetsStack.length - 1];
+			var tinf = targetsStack[targetsStackIndex - 1];
 			var t = tinf == null ? null : tinf.t;
 			var startX = tinf == null ? 0 : tinf.x;
 			var startY = tinf == null ? 0 : tinf.y;
@@ -182,8 +199,7 @@ class RenderContext extends h3d.impl.RenderContext {
 			curHeight = height;
 		}
 
-		var rz = pinf.renderZone;
-		if( rz != null ) setRenderZone(rz.x, rz.y, rz.w, rz.h);
+		if( pinf.hasRZ ) setRenderZone(pinf.rzX, pinf.rzY, pinf.rzW, pinf.rzH);
 	}
 
 	public function setRenderZone( x : Float, y : Float, w : Float, h : Float ) {

+ 17 - 8
h2d/SpriteBatch.hx

@@ -95,6 +95,7 @@ class SpriteBatch extends Drawable {
 	var last : BatchElement;
 	var tmpBuf : hxd.FloatBuffer;
 	var buffer : h3d.Buffer;
+	var bufferVertices : Int;
 
 	public function new(t,?parent) {
 		super(parent);
@@ -193,12 +194,10 @@ class SpriteBatch extends Drawable {
 	}
 
 	function flush() {
-		if( buffer != null ) {
-			buffer.dispose();
-			buffer = null;
-		}
-		if( first == null )
+		if( first == null ){
+			bufferVertices = 0;
 			return;
+		}
 		if( tmpBuf == null ) tmpBuf = new hxd.FloatBuffer();
 		var pos = 0;
 		var e = first;
@@ -290,7 +289,17 @@ class SpriteBatch extends Drawable {
 			}
 			e = e.next;
 		}
-		buffer = h3d.Buffer.ofSubFloats(tmpBuf, 8, Std.int(pos/8), [Dynamic, Quads, RawFormat]);
+		bufferVertices = pos>>3;
+		if( buffer != null && !buffer.isDisposed() ) {
+			if( buffer.vertices >= bufferVertices ){
+				buffer.uploadVector(tmpBuf, 0, bufferVertices);
+				return;
+			}
+			buffer.dispose();
+			buffer = null;
+		}
+		if( bufferVertices > 0 )
+			buffer = h3d.Buffer.ofSubFloats(tmpBuf, 8, bufferVertices, [Dynamic, Quads, RawFormat]);
 	}
 
 	override function draw( ctx : RenderContext ) {
@@ -299,9 +308,9 @@ class SpriteBatch extends Drawable {
 
 	@:allow(h2d)
 	function drawWith( ctx:RenderContext, obj : Drawable ) {
-		if( first == null || buffer == null || buffer.isDisposed() ) return;
+		if( first == null || buffer == null || buffer.isDisposed() || bufferVertices == 0 ) return;
 		if( !ctx.beginDrawObject(obj, tile.getTexture()) ) return;
-		ctx.engine.renderQuadBuffer(buffer);
+		ctx.engine.renderQuadBuffer(buffer, 0, bufferVertices>>1);
 	}
 
 	public inline function isEmpty() {

+ 4 - 2
h2d/TileGroup.hx

@@ -368,7 +368,8 @@ private class TileLayerContent extends h3d.prim.Primitive {
 
 	override public function alloc(engine:h3d.Engine) {
 		if( tmp == null ) clear();
-		buffer = h3d.Buffer.ofFloats(tmp, 8, [Quads, RawFormat]);
+		if( tmp.length > 0 )
+			buffer = h3d.Buffer.ofFloats(tmp, 8, [Quads, RawFormat]);
 	}
 
 	public inline function flush() {
@@ -377,7 +378,8 @@ private class TileLayerContent extends h3d.prim.Primitive {
 
 	public function doRender(engine:h3d.Engine, min, len) {
 		flush();
-		engine.renderQuadBuffer(buffer, min, len);
+		if( buffer != null )
+			engine.renderQuadBuffer(buffer, min, len);
 	}
 
 }

+ 1 - 1
h3d/Engine.hx

@@ -360,7 +360,7 @@ class Engine {
 	 * Sets up a scissored zone to eliminate pixels outside the given range.
 	 * Call with no parameters to reset to full viewport.
 	 */
-	public function setRenderZone( x = 0, y = 0, ?width = -1, ?height = -1 ) : Void {
+	public function setRenderZone( x = 0, y = 0, width = -1, height = -1 ) : Void {
 		flushTarget();
 		driver.setRenderZone(x, y, width, height);
 	}