UNPKG

bytev-charts

Version:

基于echarts和JavaScript及ES6封装的一个可以直接调用的图表组件库,内置主题设计,简单快捷,且支持用户自定义配置; npm 安装方式: npm install bytev-charts 若启动提示还需额外install插件,则运行 npm install @babel/runtime-corejs2 即可;

365 lines (323 loc) 13.3 kB
import _classCallCheck from "@babel/runtime-corejs2/helpers/classCallCheck"; import _createClass from "@babel/runtime-corejs2/helpers/createClass"; import "core-js/modules/es.function.bind.js"; import "core-js/modules/es.array.join.js"; import "core-js/modules/es.math.log2.js"; import _Map from "@babel/runtime-corejs2/core-js/map"; import { GPUTextureFormat, GPUAddressMode, GPUFilterMode } from './constants.js'; import { Texture, NearestFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, LinearFilter, RepeatWrapping, MirroredRepeatWrapping, FloatType, HalfFloatType } from '../../../../build/three.module.js'; import WebGPUTextureUtils from './WebGPUTextureUtils.js'; var WebGPUTextures = /*#__PURE__*/function () { function WebGPUTextures(device, properties, info, glslang) { _classCallCheck(this, WebGPUTextures); this.device = device; this.properties = properties; this.info = info; this.glslang = glslang; this.defaultTexture = null; this.defaultSampler = null; this.samplerCache = new _Map(); this.utils = null; } _createClass(WebGPUTextures, [{ key: "getDefaultSampler", value: function getDefaultSampler() { if (this.defaultSampler === null) { this.defaultSampler = this.device.createSampler({}); } return this.defaultSampler; } }, { key: "getDefaultTexture", value: function getDefaultTexture() { if (this.defaultTexture === null) { this.defaultTexture = this._createTexture(new Texture()); } return this.defaultTexture; } }, { key: "getTextureGPU", value: function getTextureGPU(texture) { var textureProperties = this.properties.get(texture); return textureProperties.textureGPU; } }, { key: "getSampler", value: function getSampler(texture) { var textureProperties = this.properties.get(texture); return textureProperties.samplerGPU; } }, { key: "updateTexture", value: function updateTexture(texture) { var forceUpdate = false; var textureProperties = this.properties.get(texture); if (texture.version > 0 && textureProperties.version !== texture.version) { var image = texture.image; if (image === undefined) { console.warn('THREE.WebGPURenderer: Texture marked for update but image is undefined.'); } else if (image.complete === false) { console.warn('THREE.WebGPURenderer: Texture marked for update but image is incomplete.'); } else { // texture init if (textureProperties.initialized === undefined) { textureProperties.initialized = true; var disposeCallback = onTextureDispose.bind(this); textureProperties.disposeCallback = disposeCallback; texture.addEventListener('dispose', disposeCallback); this.info.memory.textures++; } // texture creation if (textureProperties.textureGPU !== undefined) { // @TODO: Avoid calling of destroy() in certain scenarios. When only the contents of a texture // are updated, a buffer upload should be sufficient. However, if the user changes // the dimensions of the texture, format or usage, a new instance of GPUTexture is required. textureProperties.textureGPU.destroy(); } textureProperties.textureGPU = this._createTexture(texture); textureProperties.version = texture.version; forceUpdate = true; } } // if the texture is used for RTT, it's necessary to init it once so the binding // group's resource definition points to the respective GPUTexture if (textureProperties.initializedRTT === false) { textureProperties.initializedRTT = true; forceUpdate = true; } return forceUpdate; } }, { key: "updateSampler", value: function updateSampler(texture) { var array = []; array.push(texture.wrapS); array.push(texture.wrapT); array.push(texture.wrapR); array.push(texture.magFilter); array.push(texture.minFilter); array.push(texture.anisotropy); var key = array.join(); var samplerGPU = this.samplerCache.get(key); if (samplerGPU === undefined) { samplerGPU = this.device.createSampler({ addressModeU: this._convertAddressMode(texture.wrapS), addressModeV: this._convertAddressMode(texture.wrapT), addressModeW: this._convertAddressMode(texture.wrapR), magFilter: this._convertFilterMode(texture.magFilter), minFilter: this._convertFilterMode(texture.minFilter), mipmapFilter: this._convertFilterMode(texture.minFilter), maxAnisotropy: texture.anisotropy }); this.samplerCache.set(key, samplerGPU); } var textureProperties = this.properties.get(texture); textureProperties.samplerGPU = samplerGPU; } }, { key: "initRenderTarget", value: function initRenderTarget(renderTarget) { var properties = this.properties; var renderTargetProperties = properties.get(renderTarget); if (renderTargetProperties.initialized === undefined) { var device = this.device; var width = renderTarget.width; var height = renderTarget.height; var colorTextureGPU = device.createTexture({ size: { width: width, height: height, depth: 1 }, format: GPUTextureFormat.BRGA8Unorm, // @TODO: Make configurable usage: GPUTextureUsage.OUTPUT_ATTACHMENT | GPUTextureUsage.SAMPLED }); renderTargetProperties.colorTextureGPU = colorTextureGPU; // When the ".texture" or ".depthTexture" property of a render target is used as a map, // the renderer has to find the respective GPUTexture objects to setup the bind groups. // Since it's not possible to see just from a texture object whether it belongs to a render // target or not, we need the initializedRTT flag. var textureProperties = properties.get(renderTarget.texture); textureProperties.textureGPU = colorTextureGPU; textureProperties.initializedRTT = false; if (renderTarget.depthBuffer === true) { var depthTextureGPU = device.createTexture({ size: { width: width, height: height, depth: 1 }, format: GPUTextureFormat.Depth24PlusStencil8, // @TODO: Make configurable usage: GPUTextureUsage.OUTPUT_ATTACHMENT }); renderTargetProperties.depthTextureGPU = depthTextureGPU; if (renderTarget.depthTexture !== null) { var depthTextureProperties = properties.get(renderTarget.depthTexture); depthTextureProperties.textureGPU = depthTextureGPU; depthTextureProperties.initializedRTT = false; } } renderTargetProperties.initialized = true; } } }, { key: "dispose", value: function dispose() { this.samplerCache.clear(); } }, { key: "_computeMipLevelCount", value: function _computeMipLevelCount(width, height) { return Math.floor(Math.log2(Math.max(width, height))) + 1; } }, { key: "_convertAddressMode", value: function _convertAddressMode(value) { var addressMode = GPUAddressMode.ClampToEdge; if (value === RepeatWrapping) { addressMode = GPUAddressMode.Repeat; } else if (value === MirroredRepeatWrapping) { addressMode = GPUAddressMode.MirrorRepeat; } return addressMode; } }, { key: "_convertFilterMode", value: function _convertFilterMode(value) { var filterMode = GPUFilterMode.Linear; if (value === NearestFilter || value === NearestMipmapNearestFilter || value === NearestMipmapLinearFilter) { filterMode = GPUFilterMode.Nearest; } return filterMode; } }, { key: "_convertFormat", value: function _convertFormat(type) { var formatGPU = GPUTextureFormat.RGBA8Unorm; if (type === FloatType) { formatGPU = GPUTextureFormat.RGBA32Float; } else if (type === HalfFloatType) { formatGPU = GPUTextureFormat.RGBA16Float; } return formatGPU; } }, { key: "_createTexture", value: function _createTexture(texture) { var _this = this; var device = this.device; var image = texture.image; var width = image !== undefined ? image.width : 1; var height = image !== undefined ? image.height : 1; var format = this._convertFormat(texture.type); var needsMipmaps = this._needsMipmaps(texture); var mipLevelCount = needsMipmaps === true ? this._computeMipLevelCount(width, height) : undefined; var usage = GPUTextureUsage.SAMPLED | GPUTextureUsage.COPY_DST; if (needsMipmaps === true) { usage |= GPUTextureUsage.OUTPUT_ATTACHMENT; } // texture creation var textureGPUDescriptor = { size: { width: width, height: height, depth: 1 }, format: format, usage: usage, mipLevelCount: mipLevelCount }; var textureGPU = device.createTexture(textureGPUDescriptor); // transfer texture data if (texture.isDataTexture) { this._copyBufferToTexture(image, format, textureGPU); } else { // convert HTML iamges and canvas elements to ImageBitmap before copy if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement) { var options = {}; options.imageOrientation = texture.flipY === true ? 'flipY' : 'none'; options.premultiplyAlpha = texture.premultiplyAlpha === true ? 'premultiply' : 'default'; createImageBitmap(image, 0, 0, width, height, options).then(function (imageBitmap) { _this._copyImageBitmapToTexture(imageBitmap, textureGPU, needsMipmaps, textureGPUDescriptor); }); } else { if (image !== undefined) { // assuming ImageBitmap. Directly start copy operation of the contents of ImageBitmap into the destination texture this._copyImageBitmapToTexture(image, textureGPU, needsMipmaps, textureGPUDescriptor); } } } return textureGPU; } }, { key: "_copyBufferToTexture", value: function _copyBufferToTexture(image, format, textureGPU) { // this code assumes data textures in RGBA format // @TODO: Consider to support valid buffer layouts with other formats like RGB // @TODO: Support mipmaps var device = this.device; var data = image.data; var bytesPerTexel = this._getBytesPerTexel(format); var bytesPerRow = Math.ceil(image.width * bytesPerTexel / 256) * 256; var textureDataBuffer = device.createBuffer({ size: data.byteLength, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, mappedAtCreation: true }); new data.constructor(textureDataBuffer.getMappedRange()).set(data); textureDataBuffer.unmap(); var commandEncoder = device.createCommandEncoder({}); commandEncoder.copyBufferToTexture({ buffer: textureDataBuffer, bytesPerRow: bytesPerRow }, { texture: textureGPU }, { width: image.width, height: image.height, depth: 1 }); device.defaultQueue.submit([commandEncoder.finish()]); textureDataBuffer.destroy(); } }, { key: "_copyImageBitmapToTexture", value: function _copyImageBitmapToTexture(imageBitmap, textureGPU, needsMipmaps, textureGPUDescriptor) { var device = this.device; device.defaultQueue.copyImageBitmapToTexture({ imageBitmap: imageBitmap }, { texture: textureGPU }, { width: imageBitmap.width, height: imageBitmap.height, depth: 1 }); if (needsMipmaps === true) { if (this.utils === null) { this.utils = new WebGPUTextureUtils(this.device, this.glslang); // only create this helper if necessary } this.utils.generateMipmappedTexture(imageBitmap, textureGPU, textureGPUDescriptor); } } }, { key: "_getBytesPerTexel", value: function _getBytesPerTexel(format) { if (format === GPUTextureFormat.RGBA8Unorm) return 4; if (format === GPUTextureFormat.RGBA16Float) return 8; if (format === GPUTextureFormat.RGBA32Float) return 16; } }, { key: "_needsMipmaps", value: function _needsMipmaps(texture) { return texture.generateMipmaps === true && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter; } }]); return WebGPUTextures; }(); function onTextureDispose(event) { var texture = event.target; var textureProperties = this.properties.get(texture); textureProperties.textureGPU.destroy(); texture.removeEventListener('dispose', textureProperties.disposeCallback); this.properties.remove(texture); this.info.memory.textures--; } export default WebGPUTextures;