import { ExtensionType } from '../../../extensions/Extensions.mjs';
import { BigPool } from '../../../utils/pool/PoolGroup.mjs';
import { State } from '../../renderers/shared/state/State.mjs';
import { BatchableGraphics } from './BatchableGraphics.mjs';

class GraphicsPipe {
  constructor(renderer, adaptor) {
    this.state = State.for2d();
    // batchable graphics list, used to render batches
    this._renderableBatchesHash = /* @__PURE__ */ Object.create(null);
    this.renderer = renderer;
    this._adaptor = adaptor;
    this._adaptor.init();
  }
  validateRenderable(renderable) {
    const context = renderable.view.context;
    const wasBatched = !!this._renderableBatchesHash[renderable.uid];
    const gpuContext = this.renderer.graphicsContext.updateGpuContext(context);
    if (gpuContext.isBatchable || wasBatched !== gpuContext.isBatchable) {
      return true;
    }
    return false;
  }
  addRenderable(renderable, instructionSet) {
    const gpuContext = this.renderer.graphicsContext.updateGpuContext(renderable.view.context);
    if (renderable.view._didUpdate) {
      renderable.view._didUpdate = false;
      this._rebuild(renderable);
    }
    if (gpuContext.isBatchable) {
      this._addToBatcher(renderable, instructionSet);
    } else {
      this.renderer.renderPipes.batch.break(instructionSet);
      instructionSet.add({
        type: "graphics",
        renderable
      });
    }
  }
  updateRenderable(renderable) {
    const batches = this._renderableBatchesHash[renderable.uid];
    if (batches) {
      for (let i = 0; i < batches.length; i++) {
        const batch = batches[i];
        batch.batcher.updateElement(batch);
      }
    }
  }
  destroyRenderable(renderable) {
    this._removeBatchForRenderable(renderable.uid);
  }
  execute({ renderable }) {
    if (!renderable.isRenderable)
      return;
    this._adaptor.execute(this, renderable);
  }
  _rebuild(renderable) {
    const wasBatched = !!this._renderableBatchesHash[renderable.uid];
    const gpuContext = this.renderer.graphicsContext.updateGpuContext(renderable.view.context);
    if (wasBatched) {
      this._removeBatchForRenderable(renderable.uid);
    }
    if (gpuContext.isBatchable) {
      this._initBatchesForRenderable(renderable);
    }
    renderable.view.batched = gpuContext.isBatchable;
  }
  _addToBatcher(renderable, instructionSet) {
    const batchPipe = this.renderer.renderPipes.batch;
    const batches = this._getBatchesForRenderable(renderable);
    for (let i = 0; i < batches.length; i++) {
      const batch = batches[i];
      batchPipe.addToBatch(batch, instructionSet);
    }
  }
  _getBatchesForRenderable(renderable) {
    return this._renderableBatchesHash[renderable.uid] || this._initBatchesForRenderable(renderable);
  }
  _initBatchesForRenderable(renderable) {
    const context = renderable.view.context;
    const gpuContext = this.renderer.graphicsContext.getGpuContext(context);
    const batches = gpuContext.batches.map((batch) => {
      const batchClone = BigPool.get(BatchableGraphics);
      batch.copyTo(batchClone);
      batchClone.renderable = renderable;
      return batchClone;
    });
    this._renderableBatchesHash[renderable.uid] = batches;
    renderable.on("destroyed", () => {
      this.destroyRenderable(renderable);
    });
    return batches;
  }
  _removeBatchForRenderable(renderableUid) {
    this._renderableBatchesHash[renderableUid].forEach((batch) => {
      BigPool.return(batch);
    });
    this._renderableBatchesHash[renderableUid] = null;
  }
  destroy() {
    this.renderer = null;
    this._adaptor.destroy();
    this._adaptor = null;
    this.state = null;
    for (const i in this._renderableBatchesHash) {
      this._removeBatchForRenderable(i);
    }
    this._renderableBatchesHash = null;
  }
}
/** @ignore */
GraphicsPipe.extension = {
  type: [
    ExtensionType.WebGLPipes,
    ExtensionType.WebGPUPipes,
    ExtensionType.CanvasPipes
  ],
  name: "graphics"
};

export { GraphicsPipe };
//# sourceMappingURL=GraphicsPipe.mjs.map
