'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var Extensions = require('../../../../extensions/Extensions.js');
var unsafeEvalSupported = require('../../../../utils/unsafeEvalSupported.js');
var generateUniformsSync = require('./program/generateUniformsSync.js');

class GlUniformGroupSystem {
  /** @param renderer - The renderer this System works for. */
  constructor(renderer) {
    this.destroyed = false;
    /** Cache to holds the generated functions. Stored against UniformObjects unique signature. */
    this._cache = {};
    this._uniformGroupSyncHash = {};
    this._renderer = renderer;
    this._systemCheck();
    this.gl = null;
    this._cache = {};
  }
  /**
   * Overrideable function by `@pixi/unsafe-eval` to silence
   * throwing an error if platform doesn't support unsafe-evals.
   * @private
   */
  _systemCheck() {
    if (!unsafeEvalSupported.unsafeEvalSupported()) {
      throw new Error("Current environment does not allow unsafe-eval, please use @pixi/unsafe-eval module to enable support.");
    }
  }
  contextChange(gl) {
    this.gl = gl;
  }
  /**
   * Uploads the uniforms values to the currently bound shader.
   * @param group - the uniforms values that be applied to the current shader
   * @param program
   * @param syncData
   * @param syncData.textureCount
   */
  updateUniformGroup(group, program, syncData) {
    const programData = this._renderer.shader.getProgramData(program);
    if (!group.isStatic || group.dirtyId !== programData.uniformDirtyGroups[group.uid]) {
      programData.uniformDirtyGroups[group.uid] = group.dirtyId;
      const syncFunc = this._getUniformSyncFunction(group, program);
      syncFunc(programData.uniformData, group.uniforms, this._renderer, syncData);
    }
  }
  /**
   * Overrideable by the @pixi/unsafe-eval package to use static syncUniforms instead.
   * @param group
   * @param program
   */
  _getUniformSyncFunction(group, program) {
    return this._uniformGroupSyncHash[group.signature]?.[program.key] || this._createUniformSyncFunction(group, program);
  }
  _createUniformSyncFunction(group, program) {
    const uniformGroupSyncHash = this._uniformGroupSyncHash[group.signature] || (this._uniformGroupSyncHash[group.signature] = {});
    const id = this._getSignature(group, program.uniformData, "u");
    if (!this._cache[id]) {
      this._cache[id] = generateUniformsSync.generateUniformsSync(group, program.uniformData);
    }
    uniformGroupSyncHash[program.key] = this._cache[id];
    return uniformGroupSyncHash[program.key];
  }
  /**
   * Takes a uniform group and data and generates a unique signature for them.
   * @param group - The uniform group to get signature of
   * @param group.uniforms
   * @param uniformData - Uniform information generated by the shader
   * @param preFix
   * @returns Unique signature of the uniform group
   */
  _getSignature(group, uniformData, preFix) {
    const uniforms = group.uniforms;
    const strings = [`${preFix}-`];
    for (const i in uniforms) {
      strings.push(i);
      if (uniformData[i]) {
        strings.push(uniformData[i].type);
      }
    }
    return strings.join("-");
  }
  /** Destroys this System and removes all its textures. */
  destroy() {
    this._renderer = null;
    this.destroyed = true;
    this._cache = null;
  }
}
/** @ignore */
GlUniformGroupSystem.extension = {
  type: [
    Extensions.ExtensionType.WebGLSystem
  ],
  name: "uniformGroup"
};

exports.GlUniformGroupSystem = GlUniformGroupSystem;
//# sourceMappingURL=GlUniformGroupSystem.js.map
