/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.25/esri/copyright.txt for details. */ import{applySome as t,isNone as e,isSome as s,unwrapOr as i}from"../../core/maybe.js";import{after as a}from"../../core/promiseUtils.js";import{Milliseconds as r}from"../../core/time.js";import{webglDebugEnabled as n}from"./checkWebGLError.js";import{ContextType as l}from"./context-util.js";import{ContextState as h}from"./ContextState.js";import{BufferType as f,Face as o,BASE_TEXTURE_UNIT as _,ClearBufferBit as u,FramebufferTarget as c,TextureSamplingMode as d,SyncCondition as b,ResourceType as F,ClientWaitSyncStatus as g,BlendFactor as E,BlendOperation as B,CullMode as p,CompareFunction as m,StencilOperation as R,ColorAttachment as T,TextureType as A,PrimitiveType as x}from"./enums.js";import{InstanceCounter as O}from"./InstanceCounter.js";import{ProgramCache as U}from"./ProgramCache.js";import{StateTracker as C}from"./renderState.js";import{Texture as S}from"./Texture.js";import{getErrorString as P}from"./Util.js";import{WebGLDriverTest as M}from"./WebGLDriverTest.js";import{Capabilities as N}from"./capabilities/Capabilities.js";import k from"./capabilities/isWebGL2Context.js";class y{constructor(t,e){this.gl=t,this.instanceCounter=new O,this.programCache=new U(this),this._state=new h,this._numOfDrawCalls=0,this._numOfTriangles=0,this.type=k(t)?l.WEBGL2:l.WEBGL1,this._loadExtensions(),this.configure(e)}configure(t){this._capabilities=new N(this.gl,t),this._parameters=this._loadParameters(t);const e=this.gl.getParameter(this.gl.VIEWPORT);this._state=new h,this._state.viewport={x:e[0],y:e[1],width:e[2],height:e[3]},this._stateTracker=new C({setBlending:t=>{if(t){this.setBlendingEnabled(!0),this.setBlendEquationSeparate(t.opRgb,t.opAlpha),this.setBlendFunctionSeparate(t.srcRgb,t.dstRgb,t.srcAlpha,t.dstAlpha);const e=t.color;this.setBlendColor(e.r,e.g,e.b,e.a)}else this.setBlendingEnabled(!1)},setCulling:t=>{t?(this.setFaceCullingEnabled(!0),this.setCullFace(t.face),this.setFrontFace(t.mode)):this.setFaceCullingEnabled(!1)},setPolygonOffset:t=>{t?(this.setPolygonOffsetFillEnabled(!0),this.setPolygonOffset(t.factor,t.units)):this.setPolygonOffsetFillEnabled(!1)},setDepthTest:t=>{t?(this.setDepthTestEnabled(!0),this.setDepthFunction(t.func)):this.setDepthTestEnabled(!1)},setStencilTest:t=>{if(t){this.setStencilTestEnabled(!0);const e=t.function;this.setStencilFunction(e.func,e.ref,e.mask);const s=t.operation;this.setStencilOp(s.fail,s.zFail,s.zPass)}else this.setStencilTestEnabled(!1)},setDepthWrite:t=>{t?(this.setDepthWriteEnabled(!0),this.setDepthRange(t.zNear,t.zFar)):this.setDepthWriteEnabled(!1)},setColorWrite:t=>{t?this.setColorMask(t.r,t.g,t.b,t.a):this.setColorMask(!1,!1,!1,!1)},setStencilWrite:t=>{t?this.setStencilWriteMask(t.mask):this.setStencilWriteMask(0)}}),this.enforceState(),this._driverTest=new M(this)}get driverTest(){return this._driverTest}get contextAttributes(){return this.gl.getContextAttributes()}get parameters(){return this._parameters}dispose(){this.programCache.dispose(),this.bindVAO(null),this.unbindBuffer(f.ARRAY_BUFFER),this.unbindBuffer(f.ELEMENT_ARRAY_BUFFER),k(this.gl)&&(this.unbindBuffer(f.UNIFORM_BUFFER),this._state.uniformBufferBindingPoints.length=0,this.unbindBuffer(f.PIXEL_PACK_BUFFER),this.unbindBuffer(f.PIXEL_UNPACK_BUFFER),this.unbindBuffer(f.COPY_READ_BUFFER),this.unbindBuffer(f.COPY_WRITE_BUFFER)),this._state.textureUnitMap.length=0,n()&&this.instanceCounter.printResourceCount()}setPipelineState(t){this._stateTracker.setPipeline(t)}setBlendingEnabled(t){this._state.blend!==t&&(!0===t?this.gl.enable(this.gl.BLEND):this.gl.disable(this.gl.BLEND),this._state.blend=t,this._stateTracker.invalidateBlending())}externalProgramUpdate(){this._state.program?.stop(),this._state.program=null}externalTextureUnitUpdate(t,e){for(let s=0;s=0&&(this._state.activeTexture=e)}externalVertexArrayObjectUpdate(){const t=this.capabilities.vao;t&&(t.bindVertexArray(null),this._state.vertexArrayObject=null),this._state.vertexBuffer=null,this._state.indexBuffer=null}externalVertexBufferUpdate(){this._state.vertexBuffer=null}externalIndexBufferUpdate(){this._state.indexBuffer=null}setBlendColor(t,e,s,i){t===this._state.blendColor.r&&e===this._state.blendColor.g&&s===this._state.blendColor.b&&i===this._state.blendColor.a||(this.gl.blendColor(t,e,s,i),this._state.blendColor.r=t,this._state.blendColor.g=e,this._state.blendColor.b=s,this._state.blendColor.a=i,this._stateTracker.invalidateBlending())}setBlendFunction(t,e){t===this._state.blendFunction.srcRGB&&e===this._state.blendFunction.dstRGB||(this.gl.blendFunc(t,e),this._state.blendFunction.srcRGB=t,this._state.blendFunction.srcAlpha=t,this._state.blendFunction.dstRGB=e,this._state.blendFunction.dstAlpha=e,this._stateTracker.invalidateBlending())}setBlendFunctionSeparate(t,e,s,i){this._state.blendFunction.srcRGB===t&&this._state.blendFunction.srcAlpha===s&&this._state.blendFunction.dstRGB===e&&this._state.blendFunction.dstAlpha===i||(this.gl.blendFuncSeparate(t,e,s,i),this._state.blendFunction.srcRGB=t,this._state.blendFunction.srcAlpha=s,this._state.blendFunction.dstRGB=e,this._state.blendFunction.dstAlpha=i,this._stateTracker.invalidateBlending())}setBlendEquation(t){this._state.blendEquation.mode!==t&&(this.gl.blendEquation(t),this._state.blendEquation.mode=t,this._state.blendEquation.modeAlpha=t,this._stateTracker.invalidateBlending())}setBlendEquationSeparate(t,e){this._state.blendEquation.mode===t&&this._state.blendEquation.modeAlpha===e||(this.gl.blendEquationSeparate(t,e),this._state.blendEquation.mode=t,this._state.blendEquation.modeAlpha=e,this._stateTracker.invalidateBlending())}setColorMask(t,e,s,i){this._state.colorMask.r===t&&this._state.colorMask.g===e&&this._state.colorMask.b===s&&this._state.colorMask.a===i||(this.gl.colorMask(t,e,s,i),this._state.colorMask.r=t,this._state.colorMask.g=e,this._state.colorMask.b=s,this._state.colorMask.a=i,this._stateTracker.invalidateColorWrite())}setClearColor(t,e,s,i){this._state.clearColor.r===t&&this._state.clearColor.g===e&&this._state.clearColor.b===s&&this._state.clearColor.a===i||(this.gl.clearColor(t,e,s,i),this._state.clearColor.r=t,this._state.clearColor.g=e,this._state.clearColor.b=s,this._state.clearColor.a=i)}setFaceCullingEnabled(t){this._state.faceCulling!==t&&(!0===t?this.gl.enable(this.gl.CULL_FACE):this.gl.disable(this.gl.CULL_FACE),this._state.faceCulling=t,this._stateTracker.invalidateCulling())}setPolygonOffsetFillEnabled(t){this._state.polygonOffsetFill!==t&&(!0===t?this.gl.enable(this.gl.POLYGON_OFFSET_FILL):this.gl.disable(this.gl.POLYGON_OFFSET_FILL),this._state.polygonOffsetFill=t,this._stateTracker.invalidatePolygonOffset())}setPolygonOffset(t,e){this._state.polygonOffset[0]===t&&this._state.polygonOffset[1]===e||(this._state.polygonOffset[0]=t,this._state.polygonOffset[1]=e,this.gl.polygonOffset(t,e),this._stateTracker.invalidatePolygonOffset())}setCullFace(t){this._state.cullFace!==t&&(this.gl.cullFace(t),this._state.cullFace=t,this._stateTracker.invalidateCulling())}setFrontFace(t){this._state.frontFace!==t&&(this.gl.frontFace(t),this._state.frontFace=t,this._stateTracker.invalidateCulling())}setScissorTestEnabled(t){this._state.scissorTest!==t&&(!0===t?this.gl.enable(this.gl.SCISSOR_TEST):this.gl.disable(this.gl.SCISSOR_TEST),this._state.scissorTest=t)}setScissorRect(t,e,s,i){this._state.scissorRect.x===t&&this._state.scissorRect.y===e&&this._state.scissorRect.width===s&&this._state.scissorRect.height===i||(this.gl.scissor(t,e,s,i),this._state.scissorRect.x=t,this._state.scissorRect.y=e,this._state.scissorRect.width=s,this._state.scissorRect.height=i)}setDepthTestEnabled(t){this._state.depthTest!==t&&(!0===t?this.gl.enable(this.gl.DEPTH_TEST):this.gl.disable(this.gl.DEPTH_TEST),this._state.depthTest=t,this._stateTracker.invalidateDepthTest())}setClearDepth(t){this._state.clearDepth!==t&&(this.gl.clearDepth(t),this._state.clearDepth=t)}setDepthFunction(t){this._state.depthFunction!==t&&(this.gl.depthFunc(t),this._state.depthFunction=t,this._stateTracker.invalidateDepthTest())}setDepthWriteEnabled(t){this._state.depthWrite!==t&&(this.gl.depthMask(t),this._state.depthWrite=t,this._stateTracker.invalidateDepthWrite())}setDepthRange(t,e){this._state.depthRange.zNear===t&&this._state.depthRange.zFar===e||(this.gl.depthRange(t,e),this._state.depthRange.zNear=t,this._state.depthRange.zFar=e,this._stateTracker.invalidateDepthWrite())}setStencilTestEnabled(t){this._state.stencilTest!==t&&(!0===t?this.gl.enable(this.gl.STENCIL_TEST):this.gl.disable(this.gl.STENCIL_TEST),this._state.stencilTest=t,this._stateTracker.invalidateStencilTest())}setClearStencil(t){t!==this._state.clearStencil&&(this.gl.clearStencil(t),this._state.clearStencil=t)}setStencilFunction(t,e,s){this._state.stencilFunction.func===t&&this._state.stencilFunction.ref===e&&this._state.stencilFunction.mask===s||(this.gl.stencilFunc(t,e,s),this._state.stencilFunction.face=o.FRONT_AND_BACK,this._state.stencilFunction.func=t,this._state.stencilFunction.ref=e,this._state.stencilFunction.mask=s,this._stateTracker.invalidateStencilTest())}setStencilFunctionSeparate(t,e,s,i){this._state.stencilFunction.face===t&&this._state.stencilFunction.func===e&&this._state.stencilFunction.ref===s&&this._state.stencilFunction.mask===i||(this.gl.stencilFuncSeparate(t,e,s,i),this._state.stencilFunction.face=t,this._state.stencilFunction.func=e,this._state.stencilFunction.ref=s,this._state.stencilFunction.mask=i,this._stateTracker.invalidateStencilTest())}setStencilWriteMask(t){this._state.stencilWriteMask!==t&&(this.gl.stencilMask(t),this._state.stencilWriteMask=t,this._stateTracker.invalidateStencilWrite())}setStencilOp(t,e,s){this._state.stencilOperation.face===o.FRONT_AND_BACK&&this._state.stencilOperation.fail===t&&this._state.stencilOperation.zFail===e&&this._state.stencilOperation.zPass===s||(this.gl.stencilOp(t,e,s),this._state.stencilOperation.face=o.FRONT_AND_BACK,this._state.stencilOperation.fail=t,this._state.stencilOperation.zFail=e,this._state.stencilOperation.zPass=s,this._stateTracker.invalidateStencilTest())}setStencilOpSeparate(t,e,s,i){this._state.stencilOperation.face===t&&this._state.stencilOperation.fail===e&&this._state.stencilOperation.zFail===s&&this._state.stencilOperation.zPass===i||(this.gl.stencilOpSeparate(t,e,s,i),this._state.stencilOperation.face=t,this._state.stencilOperation.fail=e,this._state.stencilOperation.zFail=s,this._state.stencilOperation.zPass=i,this._stateTracker.invalidateStencilTest())}setActiveTexture(t,e=!1){const s=this._state.activeTexture;return t>=0&&(e||t!==this._state.activeTexture)&&(this.gl.activeTexture(_+t),this._state.activeTexture=t),s}clear(t){t&&this.gl.clear(t)}clearSafe(t,e=255){t&&(t&u.COLOR_BUFFER_BIT&&this.setColorMask(!0,!0,!0,!0),t&u.DEPTH_BUFFER_BIT&&this.setDepthWriteEnabled(!0),t&u.STENCIL_BUFFER_BIT&&this.setStencilWriteMask(e),this.gl.clear(t))}drawArrays(t,e,s){if(n()&&(this._numOfDrawCalls++,this._numOfTriangles+=v(t,s)),this.gl.drawArrays(t,e,s),n()){const t=P(this);t&&console.error("drawArrays:",t)}}drawElements(e,s,i,a){if(n()&&(this._numOfDrawCalls++,this._numOfTriangles+=v(e,s)),this.gl.drawElements(e,s,i,a),n()){const r=P(this);if(r){const n=this.getBoundVAO(),l=n?.indexBuffer,h=n?.vertexBuffers,f={indexBuffer:l,vertexBuffers:h},o={mode:e,count:s,type:i,offset:a},_=t(l,(t=>t.size))??0,u=a+s,c=_=this.parameters.maxTextureImageUnits||i<0)&&console.error("Input texture unit is out of range of available units!");const r=this._state.textureUnitMap[i];return e(t)||null==t.glName?(s(r)&&(this.setActiveTexture(i,a),this.gl.bindTexture(r.descriptor.target,null)),this._state.textureUnitMap[i]=null,r):a||r!==t?(this.setActiveTexture(i,a),this.gl.bindTexture(t.descriptor.target,t.glName),t.applyChanges(),this._state.textureUnitMap[i]=t,r):(t.isDirty&&(this.setActiveTexture(i,a),t.applyChanges()),r)}unbindTexture(t){if(!e(t))for(let e=0;e=this.parameters.maxUniformBufferBindings||s<0)return console.error("Uniform buffer binding point is out of range!"),null;const i=this._state.uniformBufferBindingPoints;let a=i[s];return e(a)&&(a={buffer:null,offset:0,size:0},i[s]=a),a}bindBufferBase(t,s,i){const a=this._getBufferBinding(t,s);if(e(a))return;if(a.buffer===i&&0===a.offset&&0===a.size)return;this.gl.bindBufferBase(t,s,i?i.glName:null),a.buffer=i,a.offset=0,a.size=0}bindBufferRange(t,s,i,a,r){const n=this._getBufferBinding(t,s);if(e(n))return;if(n.buffer===i&&n.offset===a&&n.size===r)return;if(a%this._parameters.uniformBufferOffsetAlignment!=0)return void console.error("Uniform buffer binding offset is not a multiple of the context offset alignment");this.gl.bindBufferRange(t,s,i.glName,a,r),n.buffer=i,n.offset=a,n.size=r}bindUBO(t,s,i,a){e(s)?this.bindBufferBase(f.UNIFORM_BUFFER,t,null):(n()&&(a??s.byteLength)>this._parameters.maxUniformBlockSize&&console.error("Attempting to bind more data than the maximum uniform block size"),s.initialize(),void 0!==i&&void 0!==a?this.bindBufferRange(f.UNIFORM_BUFFER,t,s.buffer,i,a):this.bindBufferBase(f.UNIFORM_BUFFER,t,s.buffer))}unbindUBO(t){for(let e=0,i=this._state.uniformBufferBindingPoints.length;e