// Class: openfl._internal.stage3D.opengl.GLContext3D

var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this

$global.Object.defineProperty(exports, "__esModule", {value: true});

var __map_reserved = {};

// Imports

var $hxClasses = require("./../../../../hxClasses_stub").default;
var $import = require("./../../../../import_stub").default;
function openfl__$Vector_Vector_$Impl_$() {return require("./../../../../openfl/_Vector/Vector_Impl_");}
function openfl__$internal_stage3D_SamplerState() {return require("./../../../../openfl/_internal/stage3D/SamplerState");}
function Reflect() {return require("./../../../../Reflect");}
function openfl_display3D_Context3D() {return require("./../../../../openfl/display3D/Context3D");}
function openfl__$internal_stage3D_GLUtils() {return require("./../../../../openfl/_internal/stage3D/GLUtils");}
function Std() {return require("./../../../../Std");}
function lime_math_Rectangle() {return require("./../../../../lime/math/Rectangle");}
function lime_math_Vector2() {return require("./../../../../lime/math/Vector2");}
function lime_utils__$DataPointer_DataPointer_$Impl_$() {return require("./../../../../lime/utils/_DataPointer/DataPointer_Impl_");}
function openfl_errors_IllegalOperationError() {return require("./../../../../openfl/errors/IllegalOperationError");}
function js__$Boot_HaxeError() {return require("./../../../../js/_Boot/HaxeError");}
function openfl_utils__$ByteArray_ByteArray_$Impl_$() {return require("./../../../../openfl/utils/_ByteArray/ByteArray_Impl_");}
function _$UInt_UInt_$Impl_$() {return require("./../../../../_UInt/UInt_Impl_");}
function openfl_display3D_textures_Texture() {return require("./../../../../openfl/display3D/textures/Texture");}
function openfl_display3D_textures_RectangleTexture() {return require("./../../../../openfl/display3D/textures/RectangleTexture");}
function openfl_display3D_textures_CubeTexture() {return require("./../../../../openfl/display3D/textures/CubeTexture");}
function openfl_errors_Error() {return require("./../../../../openfl/errors/Error");}
function haxe_Log() {return require("./../../../../haxe/Log");}
function openfl_display_Stage3D() {return require("./../../../../openfl/display/Stage3D");}

// Constructor

var GLContext3D = function(){}

// Meta

GLContext3D.__name__ = ["openfl","_internal","stage3D","opengl","GLContext3D"];
GLContext3D.prototype = {
	
};
GLContext3D.prototype.__class__ = $hxClasses["openfl._internal.stage3D.opengl.GLContext3D"] = GLContext3D;

// Init



// Statics

GLContext3D.create = function(context) {
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	var this1 = new Float32Array(512);
	context.__vertexConstants = this1;
	var this2 = new Float32Array(512);
	context.__fragmentConstants = this2;
	var array = [1.0,1.0,1.0,1.0];
	var this3;
	if(array != null) {
		this3 = new Float32Array(array);
	} else {
		this3 = null;
	}
	context.__positionScale = this3;
	context.__samplerDirty = 0;
	context.__samplerTextures = (openfl__$Vector_Vector_$Impl_$().default)._new(8);
	context.__samplerStates = [];
	var _g = 0;
	while(_g < 8) {
		var i = _g++;
		context.__samplerStates[i] = new (openfl__$internal_stage3D_SamplerState().default)(gl.LINEAR,gl.LINEAR,gl.CLAMP_TO_EDGE,gl.CLAMP_TO_EDGE);
	}
	context.maxBackBufferHeight = context.maxBackBufferWidth = gl.getParameter(gl.MAX_VIEWPORT_DIMS);
	context.__backBufferAntiAlias = 0;
	context.__backBufferEnableDepthAndStencil = true;
	context.__backBufferWantsBestResolution = false;
	context.__frameCount = 0;
	context.__rttDepthAndStencil = false;
	context.__samplerDirty = 0;
	context.__stencilCompareMode = "always";
	context.__stencilRef = 0;
	context.__stencilReadMask = 255;
	var anisoExtension = gl.getExtension("EXT_texture_filter_anisotropic");
	if(anisoExtension == null || !(Reflect().default).hasField(anisoExtension,"MAX_TEXTURE_MAX_ANISOTROPY_EXT")) {
		anisoExtension = gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
	}
	if(anisoExtension == null || !(Reflect().default).hasField(anisoExtension,"MAX_TEXTURE_MAX_ANISOTROPY_EXT")) {
		anisoExtension = gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic");
	}
	context.__supportsPackedDepthStencil = true;
	(openfl_display3D_Context3D().default).DEPTH_STENCIL = gl.DEPTH_STENCIL;
	context.__supportsAnisotropicFiltering = anisoExtension != null;
	if(context.__supportsAnisotropicFiltering) {
		(openfl_display3D_Context3D().default).TEXTURE_MAX_ANISOTROPY_EXT = anisoExtension.TEXTURE_MAX_ANISOTROPY_EXT;
		var maxAnisotropy = gl.getParameter(anisoExtension.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
		context.__maxAnisotropyTexture2D = maxAnisotropy;
		context.__maxAnisotropyTexture2D = maxAnisotropy;
	}
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	var vendor = gl.getParameter(gl.VENDOR);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	var version = gl.getParameter(gl.VERSION);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	var renderer1 = gl.getParameter(gl.RENDERER);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	var glslVersion = gl.getParameter(gl.SHADING_LANGUAGE_VERSION);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	context.driverInfo = "OpenGL" + " Vendor=" + vendor + " Version=" + version + " Renderer=" + renderer1 + " GLSL=" + glslVersion;
}
GLContext3D.clear = function(context,red,green,blue,alpha,depth,stencil,mask) {
	if(mask == null) {
		mask = 7;
	}
	if(stencil == null) {
		stencil = 0;
	}
	if(depth == null) {
		depth = 1;
	}
	if(alpha == null) {
		alpha = 1;
	}
	if(blue == null) {
		blue = 0;
	}
	if(green == null) {
		green = 0;
	}
	if(red == null) {
		red = 0;
	}
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	var clearMask = 0;
	if((mask & 1) != 0) {
		clearMask |= gl.COLOR_BUFFER_BIT;
		gl.clearColor(red,green,blue,alpha);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	}
	if((mask & 2) != 0) {
		clearMask |= gl.DEPTH_BUFFER_BIT;
		gl.depthMask(true);
		gl.clearDepthf(depth);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	}
	if((mask & 4) != 0) {
		clearMask |= gl.STENCIL_BUFFER_BIT;
		gl.clearStencil(stencil);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	}
	gl.clear(clearMask);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
}
GLContext3D.configureBackBuffer = function(context,width,height,antiAlias,enableDepthAndStencil,wantsBestResolution,wantsBestResolutionOnBrowserZoom) {
	if(wantsBestResolutionOnBrowserZoom == null) {
		wantsBestResolutionOnBrowserZoom = false;
	}
	if(wantsBestResolution == null) {
		wantsBestResolution = false;
	}
	if(enableDepthAndStencil == null) {
		enableDepthAndStencil = true;
	}
	GLContext3D.context = context;
	var renderer = context.__renderer;
	GLContext3D.gl = renderer.__gl;
	GLContext3D.__updateBackbufferViewport();
	context.backBufferWidth = width;
	context.backBufferHeight = height;
	context.__backBufferAntiAlias = antiAlias;
	context.__backBufferEnableDepthAndStencil = enableDepthAndStencil;
	context.__backBufferWantsBestResolution = wantsBestResolution;
	(openfl_display3D_Context3D().default).__stateCache.clearSettings();
}
GLContext3D.dispose = function(context,recreate) {
	if(recreate == null) {
		recreate = true;
	}
}
GLContext3D.drawToBitmapData = function(context,destination) {
	var $window = context.__stage3D.__stage.window;
	if($window != null) {
		var image = $window.renderer.readPixels();
		var offsetX = context.__stage3D.get_x() > 0 ? (Std().default)["int"](-context.__stage3D.get_x()) : 0;
		var offsetY = context.__stage3D.get_y() < 0 ? (Std().default)["int"](-context.__stage3D.get_y()) : 0;
		destination.image.copyPixels(image,new (lime_math_Rectangle().default)(0,0,context.backBufferWidth,context.backBufferHeight),new (lime_math_Vector2().default)(offsetX,offsetY));
	}
}
GLContext3D.drawTriangles = function(context,indexBuffer,firstIndex,numTriangles) {
	if(numTriangles == null) {
		numTriangles = -1;
	}
	if(firstIndex == null) {
		firstIndex = 0;
	}
	if(context.__program == null) {
		return;
	}
	GLContext3D.context = context;
	var renderer = context.__renderer;
	GLContext3D.gl = renderer.__gl;
	GLContext3D.__flushSamplerState();
	context.__program.__flush();
	var count = numTriangles == -1 ? indexBuffer.__numIndices : numTriangles * 3;
	GLContext3D.gl.bindBuffer(GLContext3D.gl.ELEMENT_ARRAY_BUFFER,indexBuffer.__id);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	GLContext3D.gl.drawElements(GLContext3D.gl.TRIANGLES,count,indexBuffer.__elementType,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(firstIndex));
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
}
GLContext3D.present = function(context) {
}
GLContext3D.setBlendFactors = function(context,sourceFactor,destinationFactor) {
	var updateSrc = (openfl_display3D_Context3D().default).__stateCache.updateBlendSrcFactor(sourceFactor);
	var updateDest = (openfl_display3D_Context3D().default).__stateCache.updateBlendDestFactor(destinationFactor);
	if(updateSrc || updateDest) {
		GLContext3D.context = context;
		var renderer = context.__renderer;
		GLContext3D.gl = renderer.__gl;
		GLContext3D.__updateBlendFactors();
	}
}
GLContext3D.setColorMask = function(context,red,green,blue,alpha) {
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	gl.colorMask(red,green,blue,alpha);
}
GLContext3D.setCulling = function(context,triangleFaceToCull) {
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	if((openfl_display3D_Context3D().default).__stateCache.updateCullingMode(triangleFaceToCull)) {
		switch(triangleFaceToCull) {
		case "back":
			gl.enable(gl.CULL_FACE);
			gl.cullFace(gl.FRONT);
			break;
		case "front":
			gl.enable(gl.CULL_FACE);
			gl.cullFace(gl.BACK);
			break;
		case "frontAndBack":
			gl.enable(gl.CULL_FACE);
			gl.cullFace(gl.FRONT_AND_BACK);
			break;
		case "none":
			gl.disable(gl.CULL_FACE);
			break;
		default:
			return new (openfl_errors_IllegalOperationError().default)();
		}
	}
	return null;
}
GLContext3D.setDepthTest = function(context,depthMask,passCompareMode) {
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	var depthTestEnabled = context.__backBufferEnableDepthAndStencil;
	if((openfl_display3D_Context3D().default).__stateCache.updateDepthTestEnabled(depthTestEnabled)) {
		if(depthTestEnabled) {
			gl.enable(gl.DEPTH_TEST);
		} else {
			gl.disable(gl.DEPTH_TEST);
		}
	}
	if((openfl_display3D_Context3D().default).__stateCache.updateDepthTestMask(depthMask)) {
		gl.depthMask(depthMask);
	}
	if((openfl_display3D_Context3D().default).__stateCache.updateDepthCompareMode(passCompareMode)) {
		switch(passCompareMode) {
		case "always":
			gl.depthFunc(gl.ALWAYS);
			break;
		case "equal":
			gl.depthFunc(gl.EQUAL);
			break;
		case "greater":
			gl.depthFunc(gl.GREATER);
			break;
		case "greaterEqual":
			gl.depthFunc(gl.GEQUAL);
			break;
		case "less":
			gl.depthFunc(gl.LESS);
			break;
		case "lessEqual":
			gl.depthFunc(gl.LEQUAL);
			break;
		case "never":
			gl.depthFunc(gl.NEVER);
			break;
		case "notEqual":
			gl.depthFunc(gl.NOTEQUAL);
			break;
		default:
			throw new (js__$Boot_HaxeError().default)(new (openfl_errors_IllegalOperationError().default)());
		}
	}
}
GLContext3D.setEnableErrorChecking = function(value) {
	(openfl__$internal_stage3D_GLUtils().default).debug = value;
}
GLContext3D.setProgram = function(context,program) {
	if((openfl_display3D_Context3D().default).__stateCache.updateProgram3D(program)) {
		program.__use();
		program.__setPositionScale(context.__positionScale);
		context.__program = program;
		context.__samplerDirty |= context.__program.__samplerUsageMask;
		var _g = 0;
		while(_g < 8) {
			var i = _g++;
			context.__samplerStates[i].copyFrom(context.__program.__getSamplerState(i));
		}
	}
}
GLContext3D.setProgramConstantsFromByteArray = function(context,programType,firstRegister,numRegisters,data,byteArrayOffset) {
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	if(numRegisters == -1) {
		numRegisters = ((openfl_utils__$ByteArray_ByteArray_$Impl_$().default).get_length(data) >> 2) - byteArrayOffset;
	}
	var isVertex = programType == "vertex";
	var dest = isVertex ? context.__vertexConstants : context.__fragmentConstants;
	var bytes = (openfl_utils__$ByteArray_ByteArray_$Impl_$().default).toBytes(data);
	var len = (openfl_utils__$ByteArray_ByteArray_$Impl_$().default).get_length(data);
	var floatData = len == null ? new Float32Array(bytes.getData(),0) : new Float32Array(bytes.getData(),0,len);
	var outOffset = firstRegister * 4;
	var inOffset = (Std().default)["int"]((_$UInt_UInt_$Impl_$().default).toFloat(byteArrayOffset) / (_$UInt_UInt_$Impl_$().default).toFloat(4));
	var _g1 = 0;
	var _g = numRegisters * 4;
	while(_g1 < _g) {
		var i = _g1++;
		dest[outOffset + i] = floatData[inOffset + i];
	}
	if(context.__program != null) {
		context.__program.__markDirty(isVertex,firstRegister,numRegisters);
	}
}
GLContext3D.setProgramConstantsFromMatrix = function(context,programType,firstRegister,matrix,transposedMatrix) {
	if(transposedMatrix == null) {
		transposedMatrix = false;
	}
	var isVertex = programType == "vertex";
	var dest = isVertex ? context.__vertexConstants : context.__fragmentConstants;
	var source = matrix.rawData;
	var i = firstRegister * 4;
	if(transposedMatrix) {
		dest[i++] = source.get(0);
		dest[i++] = source.get(4);
		dest[i++] = source.get(8);
		dest[i++] = source.get(12);
		dest[i++] = source.get(1);
		dest[i++] = source.get(5);
		dest[i++] = source.get(9);
		dest[i++] = source.get(13);
		dest[i++] = source.get(2);
		dest[i++] = source.get(6);
		dest[i++] = source.get(10);
		dest[i++] = source.get(14);
		dest[i++] = source.get(3);
		dest[i++] = source.get(7);
		dest[i++] = source.get(11);
		dest[i++] = source.get(15);
	} else {
		dest[i++] = source.get(0);
		dest[i++] = source.get(1);
		dest[i++] = source.get(2);
		dest[i++] = source.get(3);
		dest[i++] = source.get(4);
		dest[i++] = source.get(5);
		dest[i++] = source.get(6);
		dest[i++] = source.get(7);
		dest[i++] = source.get(8);
		dest[i++] = source.get(9);
		dest[i++] = source.get(10);
		dest[i++] = source.get(11);
		dest[i++] = source.get(12);
		dest[i++] = source.get(13);
		dest[i++] = source.get(14);
		dest[i++] = source.get(15);
	}
	if(context.__program != null) {
		context.__program.__markDirty(isVertex,firstRegister,4);
	}
}
GLContext3D.setProgramConstantsFromVector = function(context,programType,firstRegister,data,numRegisters) {
	if(numRegisters == null) {
		numRegisters = -1;
	}
	if(numRegisters == -1) {
		numRegisters = data.get_length() >> 2;
	}
	var isVertex = programType == "vertex";
	var dest = isVertex ? context.__vertexConstants : context.__fragmentConstants;
	var source = data;
	var sourceIndex = 0;
	var destIndex = firstRegister * 4;
	var _g1 = 0;
	var _g = numRegisters;
	while(_g1 < _g) {
		var i = _g1++;
		dest[destIndex++] = source.get(sourceIndex++);
		dest[destIndex++] = source.get(sourceIndex++);
		dest[destIndex++] = source.get(sourceIndex++);
		dest[destIndex++] = source.get(sourceIndex++);
	}
	if(context.__program != null) {
		context.__program.__markDirty(isVertex,firstRegister,numRegisters);
	}
}
GLContext3D.setRenderToBackBuffer = function(context) {
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	gl.bindFramebuffer(gl.FRAMEBUFFER,null);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	gl.frontFace(gl.CCW);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	context.__renderToTexture = null;
	context.__scissorRectangle = null;
	GLContext3D.__updateBackbufferViewport();
	GLContext3D.__updateScissorRectangle();
	GLContext3D.__updateDepthAndStencilState();
	context.__positionScale[1] = 1.0;
	if(context.__program != null) {
		context.__program.__setPositionScale(context.__positionScale);
	}
}
GLContext3D.setRenderToTexture = function(context,texture,enableDepthAndStencil,antiAlias,surfaceSelector) {
	if(surfaceSelector == null) {
		surfaceSelector = 0;
	}
	if(antiAlias == null) {
		antiAlias = 0;
	}
	if(enableDepthAndStencil == null) {
		enableDepthAndStencil = false;
	}
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	var width = 0;
	var height = 0;
	if(context.__framebuffer == null) {
		context.__framebuffer = gl.createFramebuffer();
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	}
	gl.bindFramebuffer(gl.FRAMEBUFFER,context.__framebuffer);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	if((Std().default)["is"](texture,(openfl_display3D_textures_Texture().default))) {
		var texture2D = texture;
		width = texture2D.__width;
		height = texture2D.__height;
		gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texture.__textureID,0);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	} else if((Std().default)["is"](texture,(openfl_display3D_textures_RectangleTexture().default))) {
		var rectTexture = texture;
		width = rectTexture.__width;
		height = rectTexture.__height;
		gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,texture.__textureID,0);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	} else if((Std().default)["is"](texture,(openfl_display3D_textures_CubeTexture().default))) {
		var cubeTexture = texture;
		width = cubeTexture.__size;
		height = cubeTexture.__size;
		var _g = 0;
		while(_g < 6) {
			var i = _g++;
			gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_CUBE_MAP_POSITIVE_X + i,texture.__textureID,0);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		}
	} else {
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_Error().default)("Invalid texture"));
	}
	if(enableDepthAndStencil) {
		if(context.__supportsPackedDepthStencil) {
			if(context.__depthStencilRenderBuffer == null) {
				context.__depthStencilRenderBuffer = gl.createRenderbuffer();
				(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			}
			gl.bindRenderbuffer(gl.RENDERBUFFER,context.__depthStencilRenderBuffer);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			gl.renderbufferStorage(gl.RENDERBUFFER,(openfl_display3D_Context3D().default).DEPTH_STENCIL,width,height);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.DEPTH_STENCIL_ATTACHMENT,gl.RENDERBUFFER,context.__depthStencilRenderBuffer);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		} else {
			if(context.__depthRenderBuffer == null) {
				context.__depthRenderBuffer = gl.createRenderbuffer();
				(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			}
			if(context.__stencilRenderBuffer == null) {
				context.__stencilRenderBuffer = gl.createRenderbuffer();
				(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			}
			gl.bindRenderbuffer(gl.RENDERBUFFER,context.__depthRenderBuffer);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			gl.renderbufferStorage(gl.RENDERBUFFER,gl.DEPTH_COMPONENT16,width,height);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			gl.bindRenderbuffer(gl.RENDERBUFFER,context.__stencilRenderBuffer);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			gl.renderbufferStorage(gl.RENDERBUFFER,gl.STENCIL_INDEX8,width,height);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.DEPTH_ATTACHMENT,gl.RENDERBUFFER,context.__depthRenderBuffer);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.STENCIL_ATTACHMENT,gl.RENDERBUFFER,context.__stencilRenderBuffer);
			(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		}
		gl.bindRenderbuffer(gl.RENDERBUFFER,null);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	}
	GLContext3D.__setViewport(0,0,width,height);
	if(context.__enableErrorChecking) {
		var code = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
		if(code != gl.FRAMEBUFFER_COMPLETE) {
			(haxe_Log().default).trace("Error: Context3D.setRenderToTexture status:" + code + " width:" + width + " height:" + height,{ fileName : "GLContext3D.hx", lineNumber : 768, className : "openfl._internal.stage3D.opengl.GLContext3D", methodName : "setRenderToTexture"});
		}
	}
	context.__positionScale[1] = -1.0;
	if(context.__program != null) {
		context.__program.__setPositionScale(context.__positionScale);
	}
	gl.frontFace(gl.CW);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	context.__renderToTexture = texture;
	context.__scissorRectangle = null;
	context.__rttDepthAndStencil = enableDepthAndStencil;
	GLContext3D.__updateScissorRectangle();
	GLContext3D.__updateDepthAndStencilState();
}
GLContext3D.setSamplerStateAt = function(context,sampler,wrap,filter,mipfilter) {
	if(sampler < 0 || sampler > 8) {
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_Error().default)("sampler out of range"));
	}
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	var state = context.__samplerStates[sampler];
	switch(wrap) {
	case "clamp":
		state.set_wrapModeS(gl.CLAMP_TO_EDGE);
		state.set_wrapModeT(gl.CLAMP_TO_EDGE);
		break;
	case "clamp_u_repeat_v":
		state.set_wrapModeS(gl.CLAMP_TO_EDGE);
		state.set_wrapModeT(gl.REPEAT);
		break;
	case "repeat":
		state.set_wrapModeS(gl.REPEAT);
		state.set_wrapModeT(gl.REPEAT);
		break;
	case "repeat_u_clamp_v":
		state.set_wrapModeS(gl.REPEAT);
		state.set_wrapModeT(gl.CLAMP_TO_EDGE);
		break;
	default:
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_Error().default)("wrap bad enum"));
	}
	switch(filter) {
	case "anisotropic16x":
		if(context.__supportsAnisotropicFiltering) {
			state.set_maxAniso(context.__maxAnisotropyTexture2D < 16 ? context.__maxAnisotropyTexture2D : 16);
		}
		break;
	case "anisotropic2x":
		if(context.__supportsAnisotropicFiltering) {
			state.set_maxAniso(context.__maxAnisotropyTexture2D < 2 ? context.__maxAnisotropyTexture2D : 2);
		}
		break;
	case "anisotropic4x":
		if(context.__supportsAnisotropicFiltering) {
			state.set_maxAniso(context.__maxAnisotropyTexture2D < 4 ? context.__maxAnisotropyTexture2D : 4);
		}
		break;
	case "anisotropic8x":
		if(context.__supportsAnisotropicFiltering) {
			state.set_maxAniso(context.__maxAnisotropyTexture2D < 8 ? context.__maxAnisotropyTexture2D : 8);
		}
		break;
	case "linear":
		state.set_magFilter(gl.LINEAR);
		if(context.__supportsAnisotropicFiltering) {
			state.set_maxAniso(1);
		}
		break;
	case "nearest":
		state.set_magFilter(gl.NEAREST);
		if(context.__supportsAnisotropicFiltering) {
			state.set_maxAniso(1);
		}
		break;
	default:
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_Error().default)("filter bad enum"));
	}
	switch(mipfilter) {
	case "miplinear":
		state.set_minFilter(filter == "nearest" ? gl.NEAREST_MIPMAP_LINEAR : gl.LINEAR_MIPMAP_LINEAR);
		break;
	case "mipnearest":
		state.set_minFilter(filter == "nearest" ? gl.NEAREST_MIPMAP_NEAREST : gl.LINEAR_MIPMAP_NEAREST);
		break;
	case "mipnone":
		state.set_minFilter(filter == "nearest" ? gl.NEAREST : gl.LINEAR);
		break;
	default:
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_Error().default)("mipfiter bad enum"));
	}
}
GLContext3D.setScissorRectangle = function(context,rectangle) {
	GLContext3D.context = context;
	var renderer = context.__renderer;
	GLContext3D.gl = renderer.__gl;
	context.__scissorRectangle = rectangle != null ? rectangle.clone() : null;
	GLContext3D.__updateScissorRectangle();
}
GLContext3D.setStencilActions = function(context,triangleFace,compareMode,actionOnBothPass,actionOnDepthFail,actionOnDepthPassStencilFail) {
	if(actionOnDepthPassStencilFail == null) {
		actionOnDepthPassStencilFail = "keep";
	}
	if(actionOnDepthFail == null) {
		actionOnDepthFail = "keep";
	}
	if(actionOnBothPass == null) {
		actionOnBothPass = "keep";
	}
	if(compareMode == null) {
		compareMode = "always";
	}
	if(triangleFace == null) {
		triangleFace = "frontAndBack";
	}
	GLContext3D.context = context;
	var renderer = context.__renderer;
	GLContext3D.gl = renderer.__gl;
	context.__stencilCompareMode = compareMode;
	GLContext3D.gl.stencilOpSeparate(GLContext3D.__getGLTriangleFace(triangleFace),GLContext3D.__getGLStencilAction(actionOnDepthPassStencilFail),GLContext3D.__getGLStencilAction(actionOnDepthFail),GLContext3D.__getGLStencilAction(actionOnBothPass));
	GLContext3D.gl.stencilFunc(GLContext3D.__getGLCompareMode(context.__stencilCompareMode),context.__stencilRef,context.__stencilReadMask);
}
GLContext3D.setStencilReferenceValue = function(context,referenceValue,readMask,writeMask) {
	if(writeMask == null) {
		writeMask = 255;
	}
	if(readMask == null) {
		readMask = 255;
	}
	GLContext3D.context = context;
	var renderer = context.__renderer;
	GLContext3D.gl = renderer.__gl;
	context.__stencilReadMask = readMask;
	context.__stencilRef = referenceValue;
	GLContext3D.gl.stencilFunc(GLContext3D.__getGLCompareMode(context.__stencilCompareMode),context.__stencilRef,context.__stencilReadMask);
	GLContext3D.gl.stencilMask(writeMask);
}
GLContext3D.setTextureAt = function(context,sampler,texture) {
	if(context.__samplerTextures.get(sampler) != texture) {
		context.__samplerTextures.set(sampler,texture);
		context.__samplerDirty |= 1 << sampler;
	}
}
GLContext3D.setVertexBufferAt = function(context,index,buffer,bufferOffset,format) {
	if(format == null) {
		format = "float4";
	}
	if(bufferOffset == null) {
		bufferOffset = 0;
	}
	var renderer = context.__renderer;
	var gl = renderer.__gl;
	if(buffer == null) {
		gl.disableVertexAttribArray(index);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		gl.bindBuffer(gl.ARRAY_BUFFER,null);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		return;
	}
	gl.enableVertexAttribArray(index);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	gl.bindBuffer(gl.ARRAY_BUFFER,buffer.__id);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	var byteOffset = bufferOffset * 4;
	switch(format) {
	case "bytes4":
		gl.vertexAttribPointer(index,4,gl.UNSIGNED_BYTE,true,buffer.__stride,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(byteOffset));
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		break;
	case "float1":
		gl.vertexAttribPointer(index,1,gl.FLOAT,false,buffer.__stride,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(byteOffset));
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		break;
	case "float2":
		gl.vertexAttribPointer(index,2,gl.FLOAT,false,buffer.__stride,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(byteOffset));
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		break;
	case "float3":
		gl.vertexAttribPointer(index,3,gl.FLOAT,false,buffer.__stride,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(byteOffset));
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		break;
	case "float4":
		gl.vertexAttribPointer(index,4,gl.FLOAT,false,buffer.__stride,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(byteOffset));
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		break;
	default:
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_IllegalOperationError().default)());
	}
}
GLContext3D.__flushSamplerState = function() {
	var sampler = 0;
	while(GLContext3D.context.__samplerDirty != 0) {
		if((GLContext3D.context.__samplerDirty & 1 << sampler) != 0) {
			if((openfl_display3D_Context3D().default).__stateCache.updateActiveTextureSample(sampler)) {
				GLContext3D.gl.activeTexture(GLContext3D.gl.TEXTURE0 + sampler);
				(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			}
			var texture = GLContext3D.context.__samplerTextures.get(sampler);
			if(texture != null) {
				var target = texture.__textureTarget;
				GLContext3D.gl.bindTexture(target,texture.__getTexture());
				(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
				texture.__setSamplerState(GLContext3D.context.__samplerStates[sampler]);
			} else {
				GLContext3D.gl.bindTexture(GLContext3D.gl.TEXTURE_2D,null);
				(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
			}
			if(GLContext3D.context.__samplerStates[sampler].textureAlpha) {
				GLContext3D.gl.activeTexture(GLContext3D.gl.TEXTURE0 + sampler + 4);
				(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
				if(texture != null && texture.__alphaTexture != null) {
					var target1 = texture.__alphaTexture.__textureTarget;
					GLContext3D.gl.bindTexture(target1,texture.__alphaTexture.__getTexture());
					(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
					texture.__alphaTexture.__setSamplerState(GLContext3D.context.__samplerStates[sampler]);
					GLContext3D.gl.uniform1i(GLContext3D.context.__program.__alphaSamplerEnabled[sampler].location,1);
					(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
				} else {
					GLContext3D.gl.bindTexture(GLContext3D.gl.TEXTURE_2D,null);
					(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
					GLContext3D.gl.uniform1i(GLContext3D.context.__program.__alphaSamplerEnabled[sampler].location,0);
					(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
				}
			}
			GLContext3D.context.__samplerDirty &= ~(1 << sampler);
		}
		++sampler;
	}
}
GLContext3D.__getGLCompareMode = function(compareMode) {
	switch(compareMode) {
	case "always":
		return GLContext3D.gl.ALWAYS;
	case "equal":
		return GLContext3D.gl.EQUAL;
	case "greater":
		return GLContext3D.gl.GREATER;
	case "greaterEqual":
		return GLContext3D.gl.GEQUAL;
	case "less":
		return GLContext3D.gl.LESS;
	case "lessEqual":
		return GLContext3D.gl.LEQUAL;
	case "never":
		return GLContext3D.gl.NEVER;
	case "notEqual":
		return GLContext3D.gl.NOTEQUAL;
	default:
		return GLContext3D.gl.EQUAL;
	}
}
GLContext3D.__getGLTriangleFace = function(triangleFace) {
	switch(triangleFace) {
	case "back":
		return GLContext3D.gl.BACK;
	case "front":
		return GLContext3D.gl.FRONT;
	case "frontAndBack":
		return GLContext3D.gl.FRONT_AND_BACK;
	case "none":
		return GLContext3D.gl.NONE;
	default:
		return GLContext3D.gl.FRONT_AND_BACK;
	}
}
GLContext3D.__getGLStencilAction = function(stencilAction) {
	switch(stencilAction) {
	case "decrementSaturate":
		return GLContext3D.gl.DECR;
	case "decrementWrap":
		return GLContext3D.gl.DECR_WRAP;
	case "incrementSaturate":
		return GLContext3D.gl.INCR;
	case "incrementWrap":
		return GLContext3D.gl.INCR_WRAP;
	case "invert":
		return GLContext3D.gl.INVERT;
	case "keep":
		return GLContext3D.gl.KEEP;
	case "set":
		return GLContext3D.gl.REPLACE;
	case "zero":
		return GLContext3D.gl.ZERO;
	default:
		return GLContext3D.gl.KEEP;
	}
}
GLContext3D.__hasGLExtension = function(name) {
	return GLContext3D.gl.getSupportedExtensions().indexOf(name) != -1;
}
GLContext3D.__setViewport = function(originX,originY,width,height) {
	if(GLContext3D.context.__renderToTexture != null) {
		originY *= -1;
	}
	if((openfl_display3D_Context3D().default).__stateCache.updateViewport(originX,originY,width,height)) {
		GLContext3D.gl.viewport(originX,originY,width,height);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	}
}
GLContext3D.__updateBackbufferViewportTEMP = function(context) {
	GLContext3D.context = context;
	var renderer = context.__renderer;
	GLContext3D.gl = renderer.__gl;
	GLContext3D.__updateBackbufferViewport();
}
GLContext3D.__updateBackbufferViewport = function() {
	if(!(openfl_display_Stage3D().default).__active) {
		(openfl_display_Stage3D().default).__active = true;
		var renderer = GLContext3D.context.__renderer;
		renderer.__clear();
	}
	if(GLContext3D.context.__renderToTexture == null && GLContext3D.context.backBufferWidth > 0 && GLContext3D.context.backBufferHeight > 0) {
		var $window = GLContext3D.context.__stage3D.__stage.window;
		var x = (Std().default)["int"](GLContext3D.context.__stage3D.get_x());
		var y = (Std().default)["int"]($window.get_height() * $window.get_scale() - GLContext3D.context.backBufferHeight - GLContext3D.context.__stage3D.get_y());
		GLContext3D.__setViewport(x > 0 ? x : 0,y > 0 ? y : 0,GLContext3D.context.backBufferWidth,GLContext3D.context.backBufferHeight);
	}
}
GLContext3D.__updateBlendFactorsTEMP = function(context) {
	GLContext3D.context = context;
	var renderer = context.__renderer;
	GLContext3D.gl = renderer.__gl;
	GLContext3D.__updateBlendFactors();
}
GLContext3D.__updateBlendFactors = function() {
	if((openfl_display3D_Context3D().default).__stateCache._srcBlendFactor == null || (openfl_display3D_Context3D().default).__stateCache._destBlendFactor == null) {
		return;
	}
	var src = GLContext3D.gl.ONE;
	var dest = GLContext3D.gl.ZERO;
	var _g = (openfl_display3D_Context3D().default).__stateCache._srcBlendFactor;
	switch(_g) {
	case "destinationAlpha":
		src = GLContext3D.gl.DST_ALPHA;
		break;
	case "destinationColor":
		src = GLContext3D.gl.DST_COLOR;
		break;
	case "one":
		src = GLContext3D.gl.ONE;
		break;
	case "oneMinusDestinationAlpha":
		src = GLContext3D.gl.ONE_MINUS_DST_ALPHA;
		break;
	case "oneMinusDestinationColor":
		src = GLContext3D.gl.ONE_MINUS_DST_COLOR;
		break;
	case "oneMinusSourceAlpha":
		src = GLContext3D.gl.ONE_MINUS_SRC_ALPHA;
		break;
	case "sourceAlpha":
		src = GLContext3D.gl.SRC_ALPHA;
		break;
	case "zero":
		src = GLContext3D.gl.ZERO;
		break;
	default:
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_IllegalOperationError().default)());
	}
	var _g1 = (openfl_display3D_Context3D().default).__stateCache._destBlendFactor;
	switch(_g1) {
	case "destinationAlpha":
		dest = GLContext3D.gl.DST_ALPHA;
		break;
	case "one":
		dest = GLContext3D.gl.ONE;
		break;
	case "oneMinusDestinationAlpha":
		dest = GLContext3D.gl.ONE_MINUS_DST_ALPHA;
		break;
	case "oneMinusSourceAlpha":
		dest = GLContext3D.gl.ONE_MINUS_SRC_ALPHA;
		break;
	case "oneMinusSourceColor":
		dest = GLContext3D.gl.ONE_MINUS_SRC_COLOR;
		break;
	case "sourceAlpha":
		dest = GLContext3D.gl.SRC_ALPHA;
		break;
	case "sourceColor":
		dest = GLContext3D.gl.SRC_COLOR;
		break;
	case "zero":
		dest = GLContext3D.gl.ZERO;
		break;
	default:
		throw new (js__$Boot_HaxeError().default)(new (openfl_errors_IllegalOperationError().default)());
	}
	GLContext3D.gl.enable(GLContext3D.gl.BLEND);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	GLContext3D.gl.blendFunc(src,dest);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
}
GLContext3D.__updateDepthAndStencilState = function() {
	var depthAndStencil = GLContext3D.context.__renderToTexture != null ? GLContext3D.context.__rttDepthAndStencil : GLContext3D.context.__backBufferEnableDepthAndStencil;
	if(depthAndStencil) {
		GLContext3D.gl.enable(GLContext3D.gl.DEPTH_TEST);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		GLContext3D.gl.enable(GLContext3D.gl.STENCIL_TEST);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	} else {
		GLContext3D.gl.disable(GLContext3D.gl.DEPTH_TEST);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		GLContext3D.gl.disable(GLContext3D.gl.STENCIL_TEST);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	}
}
GLContext3D.__updateScissorRectangle = function() {
	if(GLContext3D.context.__scissorRectangle == null) {
		GLContext3D.gl.disable(GLContext3D.gl.SCISSOR_TEST);
		(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
		return;
	}
	GLContext3D.gl.enable(GLContext3D.gl.SCISSOR_TEST);
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
	var height = 0;
	var offsetX = 0;
	var offsetY = 0;
	if(GLContext3D.context.__renderToTexture != null) {
		if((Std().default)["is"](GLContext3D.context.__renderToTexture,(openfl_display3D_textures_Texture().default))) {
			var texture2D = GLContext3D.context.__renderToTexture;
			height = texture2D.__height;
		} else if((Std().default)["is"](GLContext3D.context.__renderToTexture,(openfl_display3D_textures_RectangleTexture().default))) {
			var rectTexture = GLContext3D.context.__renderToTexture;
			height = rectTexture.__height;
		}
	} else {
		height = GLContext3D.context.backBufferHeight;
		offsetX = (Std().default)["int"](GLContext3D.context.__stage3D.get_x());
		offsetY = (Std().default)["int"](GLContext3D.context.__stage3D.get_y());
	}
	GLContext3D.gl.scissor((Std().default)["int"](GLContext3D.context.__scissorRectangle.x) + offsetX,height - (Std().default)["int"](GLContext3D.context.__scissorRectangle.y) - (Std().default)["int"](GLContext3D.context.__scissorRectangle.height) + offsetY,(Std().default)["int"](GLContext3D.context.__scissorRectangle.width),(Std().default)["int"](GLContext3D.context.__scissorRectangle.height));
	(openfl__$internal_stage3D_GLUtils().default).CheckGLError();
}


// Export

exports.default = GLContext3D;