/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.25/esri/copyright.txt for details. */ import{isArrayLike as e}from"../../core/arrayUtils.js";import t from"../../core/Logger.js";import{nullifyNonNullableForDispose as r,isSome as i}from"../../core/maybe.js";import{isUint16Array as s,isUint32Array as n}from"../../core/typedArrayUtil.js";import{checkWebGLError as o}from"./checkWebGLError.js";import{ContextType as a}from"./context-util.js";import{ResourceType as f,BufferType as u,Usage as _,DataType as h}from"./enums.js";const c=t.getLogger("esri.views.webgl.BufferObject");function b(t){return e(t)}class E{constructor(e,t,r,i){this._context=e,this.bufferType=t,this.usage=r,this._glName=null,this._size=-1,this._indexType=void 0,e.instanceCounter.increment(f.BufferObject,this),this._glName=this._context.gl.createBuffer(),o(this._context.gl),i&&this.setData(i)}static createIndex(e,t,r){return new E(e,u.ELEMENT_ARRAY_BUFFER,t,r)}static createVertex(e,t,r){return new E(e,u.ARRAY_BUFFER,t,r)}static createUniform(e,t,r){if(e.type!==a.WEBGL2)throw new Error("Uniform buffers are supported in WebGL2 only!");return new E(e,u.UNIFORM_BUFFER,t,r)}static createPixelPack(e,t=_.STREAM_READ,r){if(e.type!==a.WEBGL2)throw new Error("Pixel pack buffers are supported in WebGL2 only!");const i=new E(e,u.PIXEL_PACK_BUFFER,t);return r&&i.setSize(r),i}static createPixelUnpack(e,t=_.STREAM_DRAW,r){if(e.type!==a.WEBGL2)throw new Error("Pixel unpack buffers are supported in WebGL2 only!");return new E(e,u.PIXEL_UNPACK_BUFFER,t,r)}get glName(){return this._glName}get size(){return this._size}get indexType(){return this._indexType}get byteSize(){return this.bufferType===u.ELEMENT_ARRAY_BUFFER?this._indexType===h.UNSIGNED_INT?4*this._size:2*this._size:this._size}get _isVAOAware(){return this.bufferType===u.ELEMENT_ARRAY_BUFFER||this.bufferType===u.ARRAY_BUFFER}dispose(){if(this._context?.gl){if(this._glName){this._context.gl.deleteBuffer(this._glName),this._glName=null}this._context.instanceCounter.decrement(f.BufferObject,this),this._context=r(this._context)}else this._glName&&c.warn("Leaked WebGL buffer object")}setSize(e,t=null){if(e<=0&&c.error("Buffer size needs to be positive!"),this.bufferType===u.ELEMENT_ARRAY_BUFFER&&i(t))switch(this._indexType=t,t){case h.UNSIGNED_SHORT:e*=2;break;case h.UNSIGNED_INT:e*=4}this._setBufferData(e)}setData(e){if(!e)return;let t=e.byteLength;this.bufferType===u.ELEMENT_ARRAY_BUFFER&&(s(e)&&(t/=2,this._indexType=h.UNSIGNED_SHORT),n(e)&&(t/=4,this._indexType=h.UNSIGNED_INT)),this._setBufferData(t,e)}_setBufferData(e,t=null){this._size=e;const r=this._context.getBoundVAO();this._isVAOAware&&this._context.bindVAO(null),this._context.bindBuffer(this);const s=this._context.gl;i(t)?s.bufferData(this.bufferType,t,this.usage):s.bufferData(this.bufferType,e,this.usage),o(s),this._isVAOAware&&this._context.bindVAO(r)}setSubData(e,t,r,i){if(!e)return;(t<0||t>=this._size)&&c.error("offset is out of range!"),r>=i&&c.error("end must be bigger than start!"),t+(i-r)>this._size&&c.error("An attempt to write beyond the end of the buffer!");const s=this._context.getBoundVAO();this._isVAOAware&&this._context.bindVAO(null),this._context.bindBuffer(this);const n=this._context.gl;if(this._context.type===a.WEBGL2)n.bufferSubData(this.bufferType,t*e.BYTES_PER_ELEMENT,e,r,i-r);else{const s=0===r&&i===e.length?e:e.subarray(r,i);n.bufferSubData(this.bufferType,t*e.BYTES_PER_ELEMENT,s)}o(n),this._isVAOAware&&this._context.bindVAO(s)}getSubData(e,t=0,r,i){if(this._context.type!==a.WEBGL2)return void c.error("Get buffer subdata is supported in WebGL2 only!");if(r<0||i<0)return void c.error("Problem getting subdata: offset and length were less than zero!");const s=b(e)?e.BYTES_PER_ELEMENT:1;if(s*((r??0)+(i??0))>e.byteLength)return void c.error("Problem getting subdata: offset and length exceeded destination size!");t+s*(i??0)>this.byteSize&&c.warn("Potential problem getting subdata: requested data exceeds buffer size!");const n=this._context.gl;this._context.bindBuffer(this,u.COPY_READ_BUFFER),n.getBufferSubData(u.COPY_READ_BUFFER,t,e,r,i),this._context.unbindBuffer(u.COPY_READ_BUFFER)}async getSubDataAsync(e,t=0,r,i){this._context.type===a.WEBGL2?(await this._context.clientWaitAsync(),this.getSubData(e,t,r,i)):c.error("Get buffer subdata is supported in WebGL2 only!")}}export{E as BufferObject};