/* COPYRIGHT Esri - https://js.arcgis.com/5.1.0/LICENSE.txt */
import has from"../../../../core/has.js";import e from"../../../../core/Logger.js";import{create as t}from"../../../../core/libs/gl-matrix-2/factories/mat3f32.js";import{AFeatureTile as s}from"./AFeatureTile.js";import{RESHUFFLING_EXEMPT_MEMORY_BYTES as i,RESHUFFLING_TARGET_MEMORY_EFFICIENCY as r,RESHUFFLING_EXEMPT_DRAW_CALLS as a,RESHUFFLING_TARGET_DRAW_EFFICIENCY as d,tileSize as o}from"./definitions.js";import n from"./DisplayEntity.js";import{TileCpuState as h}from"./TileCpuState.js";import{TileGpuState as u}from"./TileGpuState.js";import{debugMeshDataInfo as p}from"./mesh/meshDebugUtils.js";import m from"./util/Reader.js";import{deserializeList as l}from"./util/serializationUtils.js";const g=()=>e.getLogger("esri.views.2d.engine.webgl.FeatureTile");class c extends s{constructor(e,s,i,r,a){super(e,s,i,r),this._fader=a,this._cpuState=new h,this._gpuState=new u,this._requiresRefresh=!1,this._ended=!1,this._geometryInvalidated=!1,this.decluttering=!1,this.presenting=!1,this.visible=!0,this.transforms.tileUnitsToPixels=t()}destroy(){super.destroy();const e=this._cpuState.takeMetrics();this._fader?.removeFeatureTileMetrics(this,e),this._cpuState.destroy(),this._gpuState.destroy()}beforeRender(e){super.beforeRender(e),this._needsReshuffle&&e.reshuffleManager.schedule(this)}get symbols(){const e=new Map;for(const t of this._cpuState.metrics)e.get(t.labelClassId)||e.set(t.labelClassId,[]),e.get(t.labelClassId).push(t);return e}get id(){return this.key.id}get hasData(){return!!this._cpuState.meshes.size}get requiresRefresh(){return this._requiresRefresh}get ended(){return this._ended}get hasAnimations(){return this._cpuState.hasAnimations}get hasMetrics(){return this._cpuState.metrics.length>0}get entityIds(){return this._cpuState.getEntityObjectIds()}get usedMemory(){return this._cpuState.usedMemory+this._gpuState.usedMemory}get isReady(){return this.presenting}getDisplayList(){return this._gpuState.displayList}getMesh(e){const t=this._gpuState.getMesh(e);if(null==t)throw new Error(`InternalError: Unable to find VAO for instance: ${e}`);return t}getSortKeys(e){return this._cpuState.getSortKeys(e)}clearCpuState(){const e=this._cpuState.takeMetrics();this._fader?.removeFeatureTileMetrics(this,e),this._cpuState.destroy(),this._cpuState=new h,this._geometryInvalidated=!0,this._ended=!1}update(e){switch(e.type){case"append":this._onAppendMessage(e);break;case"update":this._onUpdateMessage(e)}e.objectIdMap&&this._cpuState.mergeObjectIdMap(e.objectIdMap),this._aggregateMemoryStats(),e.end&&(has("esri-2d-update-debug")&&console.debug(`Tile[${this.key.id}] FeatureTile.end`),this._ended=!0),this._geometryInvalidated=!0}reshuffle(e=!1){this.destroyed||(this._geometryInvalidated=!0,this._cpuState.reshuffle(e),this._aggregateMemoryStats(),has("esri-2d-update-debug")&&g().info(`Tile ${this.key.id} was reshuffled.`))}upload(e,t){this.presenting&&(this.hasMetrics&&(this._cpuState.setMetricVisibility(),this._gpuState.uploadVisibility(this._cpuState)),this._geometryInvalidated&&(this._geometryInvalidated=!1,this._cpuState.prepareForUpload(t),this._aggregateMemoryStats(),this._gpuState.uploadGeometry(this,e,t,this._cpuState)))}copyPixelBufferedEntitesFrom(e,t,s,i){const r=s*o,a=i*o,d=this._cpuState.copyPixelBufferedEntitiesFrom(e._cpuState,t,r,a);this._geometryInvalidated||=d}_onAppendMessage(e){if(has("esri-2d-update-debug")&&console.debug(`Tile[${this.key.id}] FeatureTile.append`,{append:p(e?.append)}),!e.append)return;this._requiresRefresh||=e.append.requiresRefresh;const t=l(new m(e.append.entities),n),{insertedMetrics:s}=this._cpuState.append(t,e.append.data,!1,this);this._fader?.insertFeatureTileMetrics(this,s)}_onUpdateMessage(e){has("esri-2d-update-debug")&&console.debug(`Tile[${this.key.id}] FeatureTile.update`,{isPixelBuffer:e.isPixelBuffer,modify:p(e.modify),remove:e.remove});const t=l(new m(e.modify.entities),n),s=t.map(e=>e.id),i=e.isPixelBuffer??!1,r=[...e.remove,...s];if(i){const e=this._cpuState.removeByIdsFromBuffer(r);this._fader?.removeFeatureTileMetrics(this,e)}else{const e=this._cpuState.removeByIds(r);this._fader?.removeFeatureTileMetrics(this,e)}const{insertedMetrics:a}=this._cpuState.append(t,e.modify.data,i,this);this._fader?.insertFeatureTileMetrics(this,a)}_aggregateMemoryStats(){this.debugInfo.memory.bytesUsed=0,this.debugInfo.memory.bytesReserved=0;for(const e of this._cpuState.meshes.values())this.debugInfo.memory.bytesUsed+=e.memoryStats.bytesUsed,this.debugInfo.memory.bytesReserved+=e.memoryStats.bytesReserved}get _needsReshuffle(){if(this.destroyed)return!1;const{bytesUsed:e,bytesReserved:t}=this.debugInfo.memory,s=e/t,{minOrderedLength:o,length:n}=this.debugInfo.display;return t>i&&s<r||n>a&&o/n<d}}export{c as FeatureTile};
