text: import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
  
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  
  import { hasFeature, FEATURES, Buffer } from '@luma.gl/core';
  import ShaderAttribute from './shader-attribute';
  import { glArrayFromType } from './gl-utils';
  import typedArrayManager from '../../utils/typed-array-manager';
  import { toDoublePrecisionArray } from '../../utils/math-utils';
  import log from '../../utils/log';
  
  function getStride(accessor) {
    return accessor.stride || accessor.size * accessor.bytesPerElement;
  }
  
  function resolveShaderAttribute(baseAccessor, shaderAttributeOptions) {
    if (shaderAttributeOptions.offset) {
      log.removed('shaderAttribute.offset', 'vertexOffset, elementOffset')();
    }
  
    const stride = getStride(baseAccessor);
    const vertexOffset = 'vertexOffset' in shaderAttributeOptions ? shaderAttributeOptions.vertexOffset : baseAccessor.vertexOffset || 0;
    const elementOffset = shaderAttributeOptions.elementOffset || 0;
    const offset = vertexOffset * stride + elementOffset * baseAccessor.bytesPerElement + (baseAccessor.offset || 0);
    return _objectSpread({}, shaderAttributeOptions, {
      offset,
      stride
    });
  }
  
  function resolveDoublePrecisionShaderAttributes(baseAccessor, shaderAttributeOptions) {
    const resolvedOptions = resolveShaderAttribute(baseAccessor, shaderAttributeOptions);
    return {
      high: resolvedOptions,
      low: _objectSpread({}, resolvedOptions, {
        offset: resolvedOptions.offset + baseAccessor.size * 4
      })
    };
  }
  
  export default class DataColumn {
    constructor(gl, opts) {
      this.gl = gl;
      this.id = opts.id;
      this.size = opts.size;
      const logicalType = opts.logicalType || opts.type;
      const doublePrecision = logicalType === 5130;
      let {
        defaultValue
      } = opts;
      defaultValue = Number.isFinite(defaultValue) ? [defaultValue] : defaultValue || new Array(this.size).fill(0);
      opts.defaultValue = defaultValue;
      let bufferType = logicalType;
  
      if (doublePrecision) {
        bufferType = 5126;
      } else if (!bufferType && opts.isIndexed) {
        bufferType = gl && hasFeature(gl, FEATURES.ELEMENT_INDEX_UINT32) ? 5125 : 5123;
      } else if (!bufferType) {
        bufferType = 5126;
      }
  
      opts.logicalType = logicalType;
      opts.type = bufferType;
      let defaultType = glArrayFromType(logicalType || bufferType || 5126);
      this.shaderAttributes = {};
      this.doublePrecision = doublePrecision;
  
      if (doublePrecision && opts.fp64 === false) {
        defaultType = Float32Array;
      }
  
      opts.bytesPerElement = defaultType.BYTES_PER_ELEMENT;
      this.defaultType = defaultType;
      this.value = null;
      this.settings = opts;
      this.state = {
        externalBuffer: null,
        bufferAccessor: opts,
        allocatedValue: null,
        constant: false
      };
      this._buffer = null;
      this.setData(opts);
    }
  
    get buffer() {
      if (!this._buffer) {
        const {
          isIndexed,
          type
        } = this.settings;
        this._buffer = new Buffer(this.gl, {
          id: this.id,
          target: isIndexed ? 34963 : 34962,
          accessor: {
            type
          }
        });
      }
  
      return this._buffer;
    }
  
    get byteOffset() {
      const accessor = this.getAccessor();
  
      if (accessor.vertexOffset) {
        return accessor.vertexOffset * getStride(accessor);
      }
  
      return 0;
    }
  
    delete() {
      if (this._buffer) {
        this._buffer.delete();
  
        this._buffer = null;
      }
  
      typedArrayManager.release(this.state.allocatedValue);
    }
  
    getShaderAttributes(id, options) {
      if (this.doublePrecision) {
        const shaderAttributes = {};
        const isBuffer64Bit = this.value instanceof Float64Array;
        const doubleShaderAttributeDefs = resolveDoublePrecisionShaderAttributes(this.getAccessor(), options || {});
        shaderAttributes[id] = new ShaderAttribute(this, doubleShaderAttributeDefs.high);
        shaderAttributes["".concat(id, "64Low")] = isBuffer64Bit ? new ShaderAttribute(this, doubleShaderAttributeDefs.low) : new Float32Array(this.size);
        return shaderAttributes;
      }
  
      if (options) {
        const shaderAttributeDef = resolveShaderAttribute(this.getAccessor(), options);
        return {
          [id]: new ShaderAttribute(this, shaderAttributeDef)
        };
      }
  
      return {
        [id]: this
      };
    }
  
    getBuffer() {
      if (this.state.constant) {
        return null;
      }
  
      return this.state.externalBuffer || this._buffer;
    }
  
    getValue() {
      if (this.state.constant) {
        return this.value;
      }
  
      return [this.getBuffer(), this.getAccessor()];
    }
  
    getAccessor() {
      return this.state.bufferAccessor;
    }
  
    setData(opts) {
      const {
        state
      } = this;
  
      if (ArrayBuffer.isView(opts)) {
        opts = {
          value: opts
        };
      } else if (opts instanceof Buffer) {
        opts = {
          buffer: opts
        };
      }
  
      const accessor = _objectSpread({}, this.settings, {}, opts);
  
      state.bufferAccessor = accessor;
  
      if (opts.constant) {
        let value = opts.value;
        value = this._normalizeValue(value, [], 0);
  
        if (this.settings.normalized) {
          value = this._normalizeConstant(value);
        }
  
        const hasChanged = !state.constant || !this._areValuesEqual(value, this.value);
  
        if (!hasChanged) {
          return false;
        }
  
        state.externalBuffer = null;
        state.constant = true;
        this.value = value;
      } else if (opts.buffer) {
        const buffer = opts.buffer;
        state.externalBuffer = buffer;
        state.constant = false;
        this.value = opts.value;
        const isBuffer64Bit = opts.value instanceof Float64Array;
        accessor.type = opts.type || buffer.accessor.type;
        accessor.bytesPerElement = buffer.accessor.BYTES_PER_ELEMENT * (isBuffer64Bit ? 2 : 1);
        accessor.stride = getStride(accessor);
      } else if (opts.value) {
        this._checkExternalBuffer(opts);
  
        let value = opts.value;
        state.externalBuffer = null;
        state.constant = false;
        this.value = value;
        accessor.bytesPerElement = value.BYTES_PER_ELEMENT;
        accessor.stride = getStride(accessor);
        const {
          buffer,
          byteOffset
        } = this;
  
        if (this.doublePrecision && value instanceof Float64Array) {
          value = toDoublePrecisionArray(value, accessor);
        }
  
        if (buffer.byteLength < value.byteLength + byteOffset) {
          buffer.reallocate((value.byteLength + byteOffset) * 2);
        }
  
        buffer.setAccessor(null);
        buffer.subData({
          data: value,
          offset: byteOffset
        });
        accessor.type = opts.type || buffer.accessor.type;
      }
  
      return true;
    }
  
    updateSubBuffer(opts = {}) {
      const {
        value
      } = this;
      const {
        startOffset = 0,
        endOffset
      } = opts;
      this.buffer.subData({
        data: this.doublePrecision && value instanceof Float64Array ? toDoublePrecisionArray(value, {
          size: this.size,
          startIndex: startOffset,
          endIndex: endOffset
        }) : value.subarray(startOffset, endOffset),
        offset: startOffset * value.BYTES_PER_ELEMENT + this.byteOffset
      });
    }
  
    allocate({
      numInstances,
      copy = false
    }) {
      const {
        state
      } = this;
      const oldValue = state.allocatedValue;
      const value = typedArrayManager.allocate(oldValue, numInstances + 1, {
        size: this.size,
        type: this.defaultType,
        copy
      });
      this.value = value;
      const {
        buffer,
        byteOffset
      } = this;
  
      if (buffer.byteLength < value.byteLength + byteOffset) {
        buffer.reallocate(value.byteLength + byteOffset);
  
        if (copy && oldValue) {
          buffer.subData({
            data: oldValue instanceof Float64Array ? toDoublePrecisionArray(oldValue, this) : oldValue,
            offset: byteOffset
          });
        }
      }
  
      state.allocatedValue = value;
      state.constant = false;
      state.externalBuffer = null;
      state.bufferAccessor = this.settings;
      return true;
    }
  
    _checkExternalBuffer(opts) {
      const {
        value
      } = opts;
  
      if (!opts.constant && value) {
        const ArrayType = this.defaultType;
        let illegalArrayType = false;
  
        if (this.doublePrecision) {
          illegalArrayType = value.BYTES_PER_ELEMENT < 4;
        }
  
        if (illegalArrayType) {
          throw new Error("Attribute ".concat(this.id, " does not support ").concat(value.constructor.name));
        }
  
        if (!(value instanceof ArrayType) && this.settings.normalized && !('normalized' in opts)) {
          log.warn("Attribute ".concat(this.id, " is normalized"))();
        }
      }
    }
  
    _normalizeConstant(value) {
      switch (this.settings.type) {
        case 5120:
          return new Float32Array(value).map(x => (x + 128) / 255 * 2 - 1);
  
        case 5122:
          return new Float32Array(value).map(x => (x + 32768) / 65535 * 2 - 1);
  
        case 5121:
          return new Float32Array(value).map(x => x / 255);
  
        case 5123:
          return new Float32Array(value).map(x => x / 65535);
  
        default:
          return value;
      }
    }
  
    _normalizeValue(value, out, start) {
      const {
        defaultValue,
        size
      } = this.settings;
  
      if (Number.isFinite(value)) {
        out[start] = value;
        return out;
      }
  
      if (!value) {
        out[start] = defaultValue[0];
        return out;
      }
  
      switch (size) {
        case 4:
          out[start + 3] = Number.isFinite(value[3]) ? value[3] : defaultValue[3];
  
        case 3:
          out[start + 2] = Number.isFinite(value[2]) ? value[2] : defaultValue[2];
  
        case 2:
          out[start + 1] = Number.isFinite(value[1]) ? value[1] : defaultValue[1];
  
        case 1:
          out[start + 0] = Number.isFinite(value[0]) ? value[0] : defaultValue[0];
          break;
  
        default:
          let i = size;
  
          while (--i >= 0) {
            out[start + i] = Number.isFinite(value[i]) ? value[i] : defaultValue[i];
          }
  
      }
  
      return out;
    }
  
    _areValuesEqual(value1, value2) {
      if (!value1 || !value2) {
        return false;
      }
  
      const {
        size
      } = this;
  
      for (let i = 0; i < size; i++) {
        if (value1[i] !== value2[i]) {
          return false;
        }
      }
  
      return true;
    }
  
  }
  //# sourceMappingURL=data-column.js.map