@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 9.88 kB
JavaScript
import{neverReached as t}from"../../../../core/compilerUtils.js";import e from"../../../../core/Error.js";import r from"../../../../core/Evented.js";import{isPowerOfTwo as s,nextHighestPowerOfTwo as i}from"../../../../core/mathUtils.js";import{isNone as a,isSome as o,removeMaybe as n}from"../../../../core/maybe.js";import{throwIfAborted as h,onAbort as l,createAbortError as m}from"../../../../core/promiseUtils.js";import{isArrayBuffer as p,isUint8Array as d}from"../../../../core/typedArrayUtil.js";import{isBlobProtocol as _,isDataProtocol as c}from"../../../../core/urlUtils.js";import{requestImage as u}from"../../../../support/requestImageUtils.js";import{loadImageAsync as T}from"../../../../support/requestUtils.js";import{T as g}from"../../../../chunks/TextureOnly.glsl.js";import{PowerOfTwoResizeMode as f,TextureEncodingMimeType as w}from"./basicInterfaces.js";import{estimateMemoryKTX2 as E,estimateMemoryBasis as A,createTextureKTX2 as x,createTextureBasis as D}from"./BasisUtil.js";import{ContentObject as M}from"./ContentObject.js";import{ContentObjectType as y}from"./ContentObjectType.js";import{createDDSTexture as I}from"./DDSUtil.js";import{createQuadVAO as F}from"./glUtil3D.js";import{assert as O}from"./Util.js";import{ContextType as R}from"../../../webgl/context-util.js";import{TextureWrapMode as U,TextureType as P,PixelFormat as N,PixelType as b,TextureSamplingMode as C,TargetType as H,DepthStencilTargetType as V,PrimitiveType as v}from"../../../webgl/enums.js";import{FramebufferObject as S}from"../../../webgl/FramebufferObject.js";import{Texture as j}from"../../../webgl/Texture.js";import{vertexCount as L}from"../../../webgl/Util.js";class G extends M{constructor(t,e){super(),this._data=t,this.type=y.Texture,this._glTexture=null,this._powerOfTwoStretchInfo=null,this._loadingPromise=null,this._loadingController=null,this.events=new r,this._passParameters=new g,this.params=e||{},this.params.mipmap=!1!==this.params.mipmap,this.params.noUnpackFlip=this.params.noUnpackFlip||!1,this.params.preMultiplyAlpha=this.params.preMultiplyAlpha||!1,this.params.wrap=this.params.wrap||{s:U.REPEAT,t:U.REPEAT},this.params.powerOfTwoResizeMode=this.params.powerOfTwoResizeMode||f.STRETCH,this.estimatedTexMemRequired=G._estimateTexMemRequired(this._data,this.params),this._startPreload()}_startPreload(){const t=this._data;a(t)||(t instanceof HTMLVideoElement?this._startPreloadVideoElement(t):t instanceof HTMLImageElement&&this._startPreloadImageElement(t))}_startPreloadVideoElement(t){if(!(_(t.src)||"auto"===t.preload&&t.crossOrigin)){t.preload="auto",t.crossOrigin="anonymous";const e=!t.paused;if(t.src=t.src,e&&t.autoplay){const e=()=>{t.removeEventListener("canplay",e),t.play()};t.addEventListener("canplay",e)}}}_startPreloadImageElement(t){c(t.src)||_(t.src)||t.crossOrigin||(t.crossOrigin="anonymous",t.src=t.src)}static _getDataDimensions(t){return t instanceof HTMLVideoElement?{width:t.videoWidth,height:t.videoHeight}:t}static _estimateTexMemRequired(t,e){if(a(t))return 0;if(p(t)||d(t))return e.encoding===w.KTX2_ENCODING?E(t,!!e.mipmap):e.encoding===w.BASIS_ENCODING?A(t,!!e.mipmap):t.byteLength;const{width:r,height:s}=t instanceof Image||t instanceof ImageData||t instanceof HTMLCanvasElement||t instanceof HTMLVideoElement?G._getDataDimensions(t):e;return(e.mipmap?4/3:1)*r*s*(e.components||4)||0}dispose(){this._data=void 0}get width(){return this.params.width}get height(){return this.params.height}_createDescriptor(t){return{target:P.TEXTURE_2D,pixelFormat:N.RGBA,dataType:b.UNSIGNED_BYTE,wrapMode:this.params.wrap,flipped:!this.params.noUnpackFlip,samplingMode:this.params.mipmap?C.LINEAR_MIPMAP_LINEAR:C.LINEAR,hasMipmap:this.params.mipmap,preMultiplyAlpha:this.params.preMultiplyAlpha,maxAnisotropy:this.params.maxAnisotropy??(this.params.mipmap?t.parameters.maxMaxAnisotropy:1)}}get glTexture(){return this._glTexture}load(t,e){if(o(this._glTexture))return this._glTexture;if(o(this._loadingPromise))return this._loadingPromise;const r=this._data;return a(r)?(this._glTexture=new j(t,this._createDescriptor(t),null),this._glTexture):"string"==typeof r?this._loadFromURL(t,e,r):r instanceof Image?this._loadFromImageElement(t,e,r):r instanceof HTMLVideoElement?this._loadFromVideoElement(t,e,r):r instanceof ImageData||r instanceof HTMLCanvasElement?this._loadFromImage(t,r,e):(p(r)||d(r))&&this.params.encoding===w.DDS_ENCODING?(this._data=void 0,this._loadFromDDSData(t,r)):(p(r)||d(r))&&this.params.encoding===w.KTX2_ENCODING?(this._data=void 0,this._loadFromKTX2(t,r)):(p(r)||d(r))&&this.params.encoding===w.BASIS_ENCODING?(this._data=void 0,this._loadFromBasis(t,r)):d(r)?this._loadFromPixelData(t,r):p(r)?this._loadFromPixelData(t,new Uint8Array(r)):null}get requiresFrameUpdates(){return this._data instanceof HTMLVideoElement}frameUpdate(t,e,r){if(!(this._data instanceof HTMLVideoElement)||a(this._glTexture))return r;if(this._data.readyState<B.HAVE_CURRENT_DATA||r===this._data.currentTime)return r;if(o(this._powerOfTwoStretchInfo)){const{framebuffer:r,vao:s,sourceTexture:i}=this._powerOfTwoStretchInfo;i.setData(this._data),this._drawStretchedTexture(t,e,r,s,i,this._glTexture)}else{const{videoWidth:t,videoHeight:e}=this._data,{width:r,height:s}=this._glTexture.descriptor;t!==r||e!==s?this._glTexture.updateData(0,0,0,Math.min(t,r),Math.min(e,s),this._data):this._glTexture.setData(this._data)}return this._glTexture.descriptor.hasMipmap&&this._glTexture.generateMipmap(),this.params.updateCallback&&this.params.updateCallback(),this._data.currentTime}_loadFromDDSData(t,e){return this._glTexture=I(t,this._createDescriptor(t),e),this._glTexture}_loadFromKTX2(t,e){return this._loadAsync((()=>x(t,this._createDescriptor(t),e).then((t=>(this._glTexture=t,t)))))}_loadFromBasis(t,e){return this._loadAsync((()=>D(t,this._createDescriptor(t),e).then((t=>(this._glTexture=t,t)))))}_loadFromPixelData(t,e){O(this.params.width>0&&this.params.height>0);const r=this._createDescriptor(t);return r.pixelFormat=1===this.params.components?N.LUMINANCE:3===this.params.components?N.RGB:N.RGBA,r.width=this.params.width,r.height=this.params.height,this._glTexture=new j(t,r,e),this._glTexture}_loadFromURL(t,e,r){return this._loadAsync((async s=>{const i=await u(r,{signal:s});return h(s),this._loadFromImage(t,i,e)}))}_loadFromImageElement(t,e,r){return r.complete?this._loadFromImage(t,r,e):this._loadAsync((async s=>{const i=await T(r,r.src,!1,s);return h(s),this._loadFromImage(t,i,e)}))}_loadFromVideoElement(t,e,r){return r.readyState>=B.HAVE_CURRENT_DATA?this._loadFromImage(t,r,e):this._loadFromVideoElementAsync(t,e,r)}_loadFromVideoElementAsync(t,r,s){return this._loadAsync((i=>new Promise(((a,o)=>{const h=()=>{s.removeEventListener("loadeddata",p),s.removeEventListener("error",d),n(_)},p=()=>{s.readyState>=B.HAVE_CURRENT_DATA&&(h(),a(this._loadFromImage(t,s,r)))},d=t=>{h(),o(t||new e("Failed to load video"))};s.addEventListener("loadeddata",p),s.addEventListener("error",d);const _=l(i,(()=>d(m())))}))))}_loadFromImage(t,e,r){const i=G._getDataDimensions(e);this.params.width=i.width,this.params.height=i.height;const a=this._createDescriptor(t);return a.pixelFormat=3===this.params.components?N.RGB:N.RGBA,!this._requiresPowerOfTwo(t,a)||s(i.width)&&s(i.height)?(a.width=i.width,a.height=i.height,this._glTexture=new j(t,a,e),this._glTexture):(this._glTexture=this._makePowerOfTwoTexture(t,e,i,a,r),this._glTexture)}_loadAsync(t){const e=new AbortController;this._loadingController=e;const r=t(e.signal);this._loadingPromise=r;const s=()=>{this._loadingController===e&&(this._loadingController=null),this._loadingPromise===r&&(this._loadingPromise=null)};return r.then(s,s),r}_requiresPowerOfTwo(t,e){const r=U.CLAMP_TO_EDGE,s="number"==typeof e.wrapMode?e.wrapMode===r:e.wrapMode.s===r&&e.wrapMode.t===r;return t.type===R.WEBGL1&&(e.hasMipmap||!s)}_makePowerOfTwoTexture(e,r,s,a,o){const{width:n,height:h}=s,l=i(n),m=i(h);let p;switch(a.width=l,a.height=m,this.params.powerOfTwoResizeMode){case f.PAD:a.textureCoordinateScaleFactor=[n/l,h/m],p=new j(e,a),p.updateData(0,0,0,n,h,r);break;case f.STRETCH:case null:case void 0:p=this._stretchToPowerOfTwo(e,r,a,o());break;default:t(this.params.powerOfTwoResizeMode)}return a.hasMipmap&&p.generateMipmap(),p}_stretchToPowerOfTwo(t,e,r,s){const i=new j(t,r),a=new S(t,{colorTarget:H.TEXTURE,depthStencilTarget:V.NONE},i),o=new j(t,{target:P.TEXTURE_2D,pixelFormat:r.pixelFormat,dataType:b.UNSIGNED_BYTE,wrapMode:U.CLAMP_TO_EDGE,samplingMode:C.LINEAR,flipped:!!r.flipped,maxAnisotropy:8,preMultiplyAlpha:r.preMultiplyAlpha},e),n=F(t),h=t.getBoundFramebufferObject();return this._drawStretchedTexture(t,s,a,n,o,i),this.requiresFrameUpdates?this._powerOfTwoStretchInfo={vao:n,sourceTexture:o,framebuffer:a}:(n.dispose(!0),o.dispose(),a.detachColorTexture(),a.dispose()),t.bindFramebuffer(h),i}_drawStretchedTexture(t,e,r,s,i,a){this._passParameters.texture=i,t.bindFramebuffer(r);const o=t.getViewport();t.setViewport(0,0,a.descriptor.width,a.descriptor.height),t.bindTechnique(e,this._passParameters,null),t.bindVAO(s),t.drawArrays(v.TRIANGLE_STRIP,0,L(s,"geometry")),t.bindFramebuffer(null),t.setViewport(o.x,o.y,o.width,o.height),this._passParameters.texture=null}unload(){if(o(this._powerOfTwoStretchInfo)){const{framebuffer:t,vao:e,sourceTexture:r}=this._powerOfTwoStretchInfo;e.dispose(!0),r.dispose(),t.dispose(),this._glTexture=null,this._powerOfTwoStretchInfo=null}if(o(this._glTexture)&&(this._glTexture.dispose(),this._glTexture=null),o(this._loadingController)){const t=this._loadingController;this._loadingController=null,this._loadingPromise=null,t.abort()}this.events.emit("unloaded")}}var B;!function(t){t[t.HAVE_NOTHING=0]="HAVE_NOTHING",t[t.HAVE_METADATA=1]="HAVE_METADATA",t[t.HAVE_CURRENT_DATA=2]="HAVE_CURRENT_DATA",t[t.HAVE_FUTURE_DATA=3]="HAVE_FUTURE_DATA",t[t.HAVE_ENOUGH_DATA=4]="HAVE_ENOUGH_DATA"}(B||(B={}));export{G as Texture};