I follow a 2D GPU library and saw an issue someone was having with memory allocation. An Array<Map>
of enums is called every frame via setBlendMode
, ultimately calling Haxe's Type.enumParameters
each time.
class GBlendModeFunc
{
private static var blendFactors:Array<Map<GBlendMode,Array<Context3DBlendFactor>>> = [
[
GBlendMode.NONE => [Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO],
GBlendMode.NORMAL => [Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
GBlendMode.ADD => [Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.DESTINATION_ALPHA],
GBlendMode.MULTIPLY => [Context3DBlendFactor.DESTINATION_COLOR, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
GBlendMode.SCREEN => [Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE],
GBlendMode.ERASE => [Context3DBlendFactor.ZERO, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
],
[
GBlendMode.NONE => [Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO],
GBlendMode.NORMAL => [Context3DBlendFactor.ONE, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
GBlendMode.ADD => [Context3DBlendFactor.ONE, Context3DBlendFactor.ONE],
GBlendMode.MULTIPLY => [Context3DBlendFactor.DESTINATION_COLOR, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
GBlendMode.SCREEN => [Context3DBlendFactor.ONE, Context3DBlendFactor.ONE_MINUS_SOURCE_COLOR],
GBlendMode.ERASE => [Context3DBlendFactor.ZERO, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
]
];
static public function setBlendMode(p_context:Context3D, p_mode:GBlendMode, p_premultiplied:Bool):Void {
var p:Int = (p_premultiplied) ? 1 : 0;
p_context.setBlendFactors(blendFactors[p][p_mode][0], blendFactors[p][p_mode][1]);
}
}
The issue here is that Type.enumParameters
creates a new Array each time it checks the values of enum array from setBlendMode
, quickly adding tens of thousands of variables that trigger GC frequently.
I'm not familiar with best Haxe practices and not sure how to reorganize. Is there a more performant way to store the enums that won't create an allocation issue?
Edit: The GBlendMode enums cannot be converted to abstract enums because it breaks other functions.
Edit 2: A solution was proposed: https://github.com/pshtif/Genome2D-ContextFlash/issues/17