'use strict';

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

var Extensions = require('../../../extensions/Extensions.js');
var Matrix = require('../../../maths/Matrix.js');
var getTextureBatchBindGroup = require('../../batcher/gpu/getTextureBatchBindGroup.js');
var _const = require('../../batcher/shared/const.js');
var compileHighShaderToProgram = require('../../high-shader/compileHighShaderToProgram.js');
var colorBit = require('../../high-shader/shader-bits/colorBit.js');
var generateTextureBatchBit = require('../../high-shader/shader-bits/generateTextureBatchBit.js');
var localUniformBit = require('../../high-shader/shader-bits/localUniformBit.js');
var BindGroup = require('../../renderers/gpu/shader/BindGroup.js');
var Shader = require('../../renderers/shared/shader/Shader.js');
var UniformGroup = require('../../renderers/shared/shader/UniformGroup.js');
var colorToUniform = require('./colorToUniform.js');

class GpuGraphicsAdaptor {
  init() {
    const localUniforms = new UniformGroup.UniformGroup({
      color: { value: new Float32Array([1, 1, 1, 1]), type: "vec4<f32>" },
      transformMatrix: { value: new Matrix.Matrix(), type: "mat3x3<f32>" }
    });
    const gpuProgram = compileHighShaderToProgram.compileHighShaderGpuProgram({
      name: "graphics",
      bits: [
        colorBit.colorBit,
        generateTextureBatchBit.generateTextureBatchBit(_const.MAX_TEXTURES),
        localUniformBit.localUniformBit
      ]
    });
    this._shader = new Shader.Shader({
      gpuProgram,
      groups: {
        // added on the fly!
        2: new BindGroup.BindGroup({ 0: localUniforms })
      }
    });
  }
  execute(graphicsPipe, renderable) {
    const context = renderable.view.context;
    const shader = context.customShader || this._shader;
    const renderer = graphicsPipe.renderer;
    const contextSystem = renderer.graphicsContext;
    if (!contextSystem.getGpuContext(context).batches.length) {
      return;
    }
    const {
      geometry,
      instructions
    } = contextSystem.getContextRenderData(context);
    graphicsPipe.state.blendMode = renderable.layerBlendMode;
    const localUniforms = shader.resources.localUniforms;
    shader.resources.localUniforms.uniforms.uTransformMatrix = renderable.layerTransform;
    colorToUniform.color32BitToUniform(
      renderable.layerColor,
      localUniforms.uniforms.uColor,
      0
    );
    const encoder = renderer.encoder;
    encoder.setPipelineFromGeometryProgramAndState(
      geometry,
      shader.gpuProgram,
      graphicsPipe.state
    );
    encoder.setGeometry(geometry);
    const globalUniformsBindGroup = renderer.globalUniforms.bindGroup;
    encoder.setBindGroup(0, globalUniformsBindGroup, shader.gpuProgram);
    const localBindGroup = renderer.renderPipes.uniformBatch.getUniformBindGroup(localUniforms, true);
    encoder.setBindGroup(2, localBindGroup, shader.gpuProgram);
    const batches = instructions.instructions;
    for (let i = 0; i < instructions.instructionSize; i++) {
      const batch = batches[i];
      shader.groups[1] = batch.bindGroup;
      if (!batch.gpuBindGroup) {
        const textureBatch = batch.textures;
        batch.bindGroup = getTextureBatchBindGroup.getTextureBatchBindGroup(textureBatch.textures, textureBatch.count);
        batch.gpuBindGroup = renderer.bindGroup.getBindGroup(
          batch.bindGroup,
          shader.gpuProgram,
          1
        );
      }
      encoder.setBindGroup(1, batch.bindGroup, shader.gpuProgram);
      encoder.renderPassEncoder.drawIndexed(batch.size, 1, batch.start);
    }
  }
  destroy() {
    this._shader.destroy(true);
    this._shader = null;
  }
}
/** @ignore */
GpuGraphicsAdaptor.extension = {
  type: [
    Extensions.ExtensionType.WebGPUPipesAdaptor
  ],
  name: "graphics"
};

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