<commit_before>/**
 * @author       <NAME> <<EMAIL>>
 * @author       <NAME> <@bitnenfer>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../utils/Class');
var DeepCopy = require('../../utils/object/DeepCopy');
var GetFastValue = require('../../utils/object/GetFastValue');
var Matrix4 = require('../../math/Matrix4');
var Utils = require('./Utils');
var WebGLShader = require('./WebGLShader');

/**
 * @classdesc
 * The `WebGLPipeline` is a base class used by all of the core Phaser pipelines.
 *
 * It describes the way elements will be rendered in WebGL. Internally, it handles
 * compiling the shaders, creating vertex buffers, assigning primitive topology and
 * binding vertex attributes, all based on the given configuration data.
 *
 * The pipeline is configured by passing in a `WebGLPipelineConfig` object. Please
 * see the documentation for this type to fully understand the configuration options
 * available to you.
 *
 * Usually, you would not extend from this class directly, but would instead extend
 * from one of the core pipelines, such as the Multi Pipeline.
 *
 * The pipeline flow per render-step is as follows:
 *
 * 1) onPreRender - called once at the start of the render step
 * 2) onRender - call for each Scene Camera that needs to render (so can be multiple times per render step)
 * 3) Internal flow:
 * 3a)   bind (only called if a Game Object is using this pipeline and it's not currently active)
 * 3b)   onBind (called for every Game Object that uses this pipeline)
 * 3c)   flush (can be called by a Game Object, internal method or from outside by changing pipeline)
 * 4) onPostRender - called once at the end of the render step
 *
 * @class WebGLPipeline
 * @memberof Phaser.Renderer.WebGL
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration object for this WebGL Pipeline.
 */
var WebGLPipeline = new Class({

    initialize:

    function WebGLPipeline (config)
    {
        var game = config.game;
        var renderer = game.renderer;
        var gl = renderer.gl;

        /**
         * Name of the pipeline. Used for identification and setting from Game Objects.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#name
         * @type {string}
         * @since 3.0.0
         */
        this.name = GetFastValue(config, 'name', 'WebGLPipeline');

        /**
         * The Phaser Game instance to which this pipeline is bound.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#game
         * @type {Phaser.Game}
         * @since 3.0.0
         */
        this.game = game;

        /**
         * The WebGL Renderer instance to which this pipeline is bound.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#renderer
         * @type {Phaser.Renderer.WebGL.WebGLRenderer}
         * @since 3.0.0
         */
        this.renderer = renderer;

        /**
         * The WebGL context this WebGL Pipeline uses.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#gl
         * @type {WebGLRenderingContext}
         * @since 3.0.0
         */
        this.gl = gl;

        /**
         * The canvas which this WebGL Pipeline renders to.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#view
         * @type {HTMLCanvasElement}
         * @since 3.0.0
         */
        this.view = game.canvas;

        /**
         * Width of the current viewport.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#width
         * @type {number}
         * @since 3.0.0
         */
        this.width = 0;

        /**
         * Height of the current viewport.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#height
         * @type {number}
         * @since 3.0.0
         */
        this.height = 0;

        /**
         * The current number of vertices that have been added to the pipeline batch.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCount
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.vertexCount = 0;

        /**
         * The total number of vertices that this pipeline batch can hold before it will flush.
         *
         * This defaults to `renderer batchSize * 7`, where `batchSize` is defined in the Renderer Config.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCapacity
         * @type {number}
         * @since 3.0.0
         */
        this.vertexCapacity = 0;

        /**
         * Raw byte buffer of vertices.
         *
         * Either set via the config object, or generates a new Array Buffer of size `vertexCapacity * vertexSize`.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexData
         * @type {ArrayBuffer}
         * @readonly
         * @since 3.0.0
         */
        this.vertexData;

        /**
         * The WebGLBuffer that holds the vertex data.
         *
         * Created from the `vertices` config ArrayBuffer that was passed in, or set by default, by the pipeline.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexBuffer
         * @type {WebGLBuffer}
         * @readonly
         * @since 3.0.0
         */
        this.vertexBuffer;

        /**
         * The primitive topology which the pipeline will use to submit draw calls.
         *
         * Defaults to GL_TRIANGLES if not otherwise set in the config.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#topology
         * @type {GLenum}
         * @since 3.0.0
         */
        this.topology = GetFastValue(config, 'topology', gl.TRIANGLES);

        /**
         * Uint8 view to the `vertexData` ArrayBuffer. Used for uploading vertex buffer resources to the GPU.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#bytes
         * @type {Uint8Array}
         * @since 3.0.0
         */
        this.bytes;

        /**
         * Float32 view of the array buffer containing the pipeline's vertices.
         *
         * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#vertexViewF32
         * @type {Float32Array}
         * @since 3.0.0
         */
        this.vertexViewF32;

        /**
         * Uint32 view of the array buffer containing the pipeline's vertices.
         *
         * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#vertexViewU32
         * @type {Uint32Array}
         * @since 3.0.0
         */
        this.vertexViewU32;

        /**
         * Indicates if the current pipeline is active, or not, for this frame only.
         *
         * Reset to `true` in the `onRender` method.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#active
         * @type {boolean}
         * @since 3.10.0
         */
        this.active = false;

        /**
         * Holds the most recently assigned texture unit.

         * Treat this value as read-only.
         *
         * @name Phaser.Renderer.WebGL.Pipelines.WebGLPipeline#currentUnit
         * @type {number}
         * @since 3.50.0
         */
        this.currentUnit = 0;

        /**
         * Some pipelines require the forced use of texture zero (like the light pipeline).
         *
         * This property should be set when that is the case.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#forceZero
         * @type {boolean}
         * @since 3.50.0
         */
        this.forceZero = false;

        /**
         * Indicates if this pipeline has booted or not.
         *
         * A pipeline boots only when the Game instance itself, and all associated systems, is
         * fully ready.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#hasBooted
         * @type {boolean}
         * @readonly
         * @since 3.50.0
         */
        this.hasBooted = false;

        /**
         * The WebGLFramebuffer this pipeline is targeting, if any.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#targetFramebuffer
         * @type {?WebGLFramebuffer}
         * @since 3.50.0
         */
        this.targetFramebuffer = null;

        /**
         * The WebGLTexture this pipeline is targeting, if any.
         *
         * @name Phaser.GameObjects.Shader#targetTexture
         * @type {?WebGLTexture}
         * @since 3.50.0
         */
        this.targetTexture = null;

        /**
         * When using a targetTexture its dimensions are based on the scale of the WebGLRenderer.
         *
         * This value controls how much those dimensions are scaled.
         *
         * @name Phaser.GameObjects.Shader#targetScale
         * @type {number}
         * @since 3.50.0
         */
        this.targetScale = GetFastValue(config, 'targetScale', 1);

        /**
         * An array of all the WebGLShader instances that belong to this pipeline.
         *
         * All shaders must use the same attributes, as set by this pipeline, but can manage their own
         * uniforms.
         *
         * These are set in a call to the `setShadersFromConfig` method, which happens automatically,
         * but can also be called at any point in your game. See the method documentation for details.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#shaders
         * @type {Phaser.Renderer.WebGL.WebGLShader[]}
         * @since 3.50.0
         */
        this.shaders = [];

        /**
         * A reference to the currently bound WebGLShader instance from the `WebGLPipeline.shaders` array.
         *
         * For lots of pipelines, this is the only shader, so it is a quick way to reference it without
         * an array look-up.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#currentShader
         * @type {Phaser.Renderer.WebGL.WebGLShader}
         * @since 3.50.0
         */
        this.currentShader;

        /**
         * The Model matrix, used by shaders as 'uModelMatrix' uniform.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#modelMatrix
         * @type {Phaser.Math.Matrix4}
         * @since 3.50.0
         */
        this.modelMatrix = new Matrix4().identity();

        /**
         * The View matrix, used by shaders as 'uViewMatrix' uniform.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#viewMatrix
         * @type {Phaser.Math.Matrix4}
         * @since 3.50.0
         */
        this.viewMatrix = new Matrix4().identity();

        /**
         * The Projection matrix, used by shaders as 'uProjectionMatrix' uniform.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionMatrix
         * @type {Phaser.Math.Matrix4}
         * @since 3.50.0
         */
        this.projectionMatrix = new Matrix4().identity();

        /**
         * A flag indicating if the MVP matrices are dirty, or not.
         *
         * Used by WebGLShader when binding the uniforms.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#mvpDirty
         * @type {boolean}
         * @since 3.50.0
         */
        this.mvpDirty = true;

        /**
         * The configuration object that was used to create this pipeline.
         *
         * Treat this object as 'read only', because changing it post-creation will not
         * impact this pipeline in any way. However, it is used internally for cloning
         * and post-boot set-up.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#config
         * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig}
         * @since 3.50.0
         */
        this.config = config;
    },

    /**
     * Called when the Game has fully booted and the Renderer has finished setting up.
     *
     * By this stage all Game level systems are now in place. You can perform any final tasks that the
     * pipeline may need, that relies on game systems such as the Texture Manager being ready.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#boot
     * @since 3.11.0
     */
    boot: function ()
    {
        var gl = this.gl;
        var config = this.config;

        var target = GetFastValue(config, 'target', false);

        var renderer = this.renderer;

        var width = renderer.width * this.targetScale;
        var height = renderer.height * this.targetScale;

        if (target && width > 0 && height > 0)
        {
            this.targetTexture = renderer.createTextureFromSource(null, width, height, 0);
            this.targetFramebuffer = renderer.createFramebuffer(width, height, this.targetTexture, false);

            // this.targetTexture.flipY = flipY;
        }

        this.setShadersFromConfig(config);

        //  Which shader has the largest vertex size?
        var i;
        var shaders = this.shaders;
        var vertexSize = 0;
        var vertexComponentCount = 0;

        for (i = 0; i < shaders.length; i++)
        {
            if (shaders[i].vertexSize > vertexSize)
            {
                vertexSize = shaders[i].vertexSize;
            }

            if (shaders[i].vertexComponentCount > vertexComponentCount)
            {
                vertexComponentCount = shaders[i].vertexComponentCount;
            }
        }

        this.vertexCapacity = GetFastValue(config, 'vertexCapacity', renderer.config.batchSize * vertexComponentCount);

        var data = GetFastValue(config, 'vertices', new ArrayBuffer(this.vertexCapacity * vertexSize));

        this.vertexData = data;

        if (GetFastValue(config, 'vertices', null))
        {
            this.vertexBuffer = renderer.createVertexBuffer(data, gl.STREAM_DRAW);
        }
        else
        {
            this.vertexBuffer = renderer.createVertexBuffer(data.byteLength, gl.STREAM_DRAW);
        }

        this.bytes = new Uint8Array(data);

        this.vertexViewF32 = new Float32Array(data);

        this.vertexViewU32 = new Uint32Array(data);

        //  Set-up shaders

        this.renderer.setVertexBuffer(this.vertexBuffer);

        for (i = 0; i < shaders.length; i++)
        {
            shaders[i].setAttribPointers(true);
        }

        this.currentShader.bind();

        this.hasBooted = true;

        this.onBoot();

        return this;
    },

    /**
     * This method is called once when this pipeline has finished being set-up
     * at the end of the boot process. By the time this method is called, all
     * of the shaders are ready and configured.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#onBoot
     * @since 3.50.0
     */
    onBoot: function ()
    {
    },

    /**
     * Resets the model, projection and view matrices to identity matrices.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#mvpInit
     * @since 3.50.0
     */
    mvpInit: function ()
    {
        this.modelMatrix.identity();
        this.projectionMatrix.identity();
        this.viewMatrix.identity();
    },

    /**
     * Creates a brand new WebGLPipeline instance based on the configuration object that
     * was used to create this one.
     *
     * The new instance is returned by this method. Note that the new instance is _not_
     * added to the Pipeline Manager. You will need to add it yourself should you require so.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#mvpInit
     * @since 3.50.0
     *
     * @param {string} name - The new name to give the cloned pipeline.
     *
     * @return {Phaser.Renderer.WebGL.WebGLPipeline} A clone of this WebGLPipeline instance.
     */
    clone: function (name)
    {
        var clone = new WebGLPipeline(this.config);

        clone.name = name;

        return clone;
    },

    /**
     * Sets the currently active shader within this pipeline.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#setShader
     * @since 3.50.0
     *
     * @param {Phaser.Renderer.WebGL.WebGLPipeline} shader - The shader to set as being current.
     * @param {boolean} [reset=false] - Should the vertex attribute pointers be fully reset?
     *
     * @return {this} This WebGLPipeline instance.
     */
    setShader: function (shader, reset)
    {
        if (shader !== this.currentShader)
        {
            this.flush();

            shader.bind(reset);

            this.currentShader = shader;<commit_msg>Update WebGLPipeline.js<commit_after>/**
 * @author       <NAME> <<EMAIL>>
 * @author       <NAME> <@bitnenfer>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../utils/Class');
var DeepCopy = require('../../utils/object/DeepCopy');
var GetFastValue = require('../../utils/object/GetFastValue');
var Matrix4 = require('../../math/Matrix4');
var Utils = require('./Utils');
var WebGLShader = require('./WebGLShader');

/**
 * @classdesc
 * The `WebGLPipeline` is a base class used by all of the core Phaser pipelines.
 *
 * It describes the way elements will be rendered in WebGL. Internally, it handles
 * compiling the shaders, creating vertex buffers, assigning primitive topology and
 * binding vertex attributes, all based on the given configuration data.
 *
 * The pipeline is configured by passing in a `WebGLPipelineConfig` object. Please
 * see the documentation for this type to fully understand the configuration options
 * available to you.
 *
 * Usually, you would not extend from this class directly, but would instead extend
 * from one of the core pipelines, such as the Multi Pipeline.
 *
 * The pipeline flow per render-step is as follows:
 *
 * 1) onPreRender - called once at the start of the render step
 * 2) onRender - call for each Scene Camera that needs to render (so can be multiple times per render step)
 * 3) Internal flow:
 * 3a)   bind (only called if a Game Object is using this pipeline and it's not currently active)
 * 3b)   onBind (called for every Game Object that uses this pipeline)
 * 3c)   flush (can be called by a Game Object, internal method or from outside by changing pipeline)
 * 4) onPostRender - called once at the end of the render step
 *
 * @class WebGLPipeline
 * @memberof Phaser.Renderer.WebGL
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration object for this WebGL Pipeline.
 */
var WebGLPipeline = new Class({

    initialize:

    function WebGLPipeline (config)
    {
        var game = config.game;
        var renderer = game.renderer;
        var gl = renderer.gl;

        /**
         * Name of the pipeline. Used for identification and setting from Game Objects.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#name
         * @type {string}
         * @since 3.0.0
         */
        this.name = GetFastValue(config, 'name', 'WebGLPipeline');

        /**
         * The Phaser Game instance to which this pipeline is bound.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#game
         * @type {Phaser.Game}
         * @since 3.0.0
         */
        this.game = game;

        /**
         * The WebGL Renderer instance to which this pipeline is bound.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#renderer
         * @type {Phaser.Renderer.WebGL.WebGLRenderer}
         * @since 3.0.0
         */
        this.renderer = renderer;

        /**
         * The WebGL context this WebGL Pipeline uses.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#gl
         * @type {WebGLRenderingContext}
         * @since 3.0.0
         */
        this.gl = gl;

        /**
         * The canvas which this WebGL Pipeline renders to.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#view
         * @type {HTMLCanvasElement}
         * @since 3.0.0
         */
        this.view = game.canvas;

        /**
         * Width of the current viewport.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#width
         * @type {number}
         * @since 3.0.0
         */
        this.width = 0;

        /**
         * Height of the current viewport.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#height
         * @type {number}
         * @since 3.0.0
         */
        this.height = 0;

        /**
         * The current number of vertices that have been added to the pipeline batch.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCount
         * @type {number}
         * @default 0
         * @since 3.0.0
         */
        this.vertexCount = 0;

        /**
         * The total number of vertices that this pipeline batch can hold before it will flush.
         *
         * This defaults to `renderer batchSize * 7`, where `batchSize` is defined in the Renderer Config.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexCapacity
         * @type {number}
         * @since 3.0.0
         */
        this.vertexCapacity = 0;

        /**
         * Raw byte buffer of vertices.
         *
         * Either set via the config object, or generates a new Array Buffer of size `vertexCapacity * vertexSize`.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexData
         * @type {ArrayBuffer}
         * @readonly
         * @since 3.0.0
         */
        this.vertexData;

        /**
         * The WebGLBuffer that holds the vertex data.
         *
         * Created from the `vertices` config ArrayBuffer that was passed in, or set by default, by the pipeline.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#vertexBuffer
         * @type {WebGLBuffer}
         * @readonly
         * @since 3.0.0
         */
        this.vertexBuffer;

        /**
         * The primitive topology which the pipeline will use to submit draw calls.
         *
         * Defaults to GL_TRIANGLES if not otherwise set in the config.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#topology
         * @type {GLenum}
         * @since 3.0.0
         */
        this.topology = GetFastValue(config, 'topology', gl.TRIANGLES);

        /**
         * Uint8 view to the `vertexData` ArrayBuffer. Used for uploading vertex buffer resources to the GPU.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#bytes
         * @type {Uint8Array}
         * @since 3.0.0
         */
        this.bytes;

        /**
         * Float32 view of the array buffer containing the pipeline's vertices.
         *
         * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#vertexViewF32
         * @type {Float32Array}
         * @since 3.0.0
         */
        this.vertexViewF32;

        /**
         * Uint32 view of the array buffer containing the pipeline's vertices.
         *
         * @name Phaser.Renderer.WebGL.Pipelines.MultiPipeline#vertexViewU32
         * @type {Uint32Array}
         * @since 3.0.0
         */
        this.vertexViewU32;

        /**
         * Indicates if the current pipeline is active, or not, for this frame only.
         *
         * Reset to `true` in the `onRender` method.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#active
         * @type {boolean}
         * @since 3.10.0
         */
        this.active = false;

        /**
         * Holds the most recently assigned texture unit.

         * Treat this value as read-only.
         *
         * @name Phaser.Renderer.WebGL.Pipelines.WebGLPipeline#currentUnit
         * @type {number}
         * @since 3.50.0
         */
        this.currentUnit = 0;

        /**
         * Some pipelines require the forced use of texture zero (like the light pipeline).
         *
         * This property should be set when that is the case.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#forceZero
         * @type {boolean}
         * @since 3.50.0
         */
        this.forceZero = false;

        /**
         * Indicates if this pipeline has booted or not.
         *
         * A pipeline boots only when the Game instance itself, and all associated systems, is
         * fully ready.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#hasBooted
         * @type {boolean}
         * @readonly
         * @since 3.50.0
         */
        this.hasBooted = false;

        /**
         * The WebGLFramebuffer this pipeline is targeting, if any.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#targetFramebuffer
         * @type {?WebGLFramebuffer}
         * @since 3.50.0
         */
        this.targetFramebuffer = null;

        /**
         * The WebGLTexture this pipeline is targeting, if any.
         *
         * @name Phaser.GameObjects.Shader#targetTexture
         * @type {?WebGLTexture}
         * @since 3.50.0
         */
        this.targetTexture = null;

        /**
         * When using a targetTexture its dimensions are based on the scale of the WebGLRenderer.
         *
         * This value controls how much those dimensions are scaled.
         *
         * @name Phaser.GameObjects.Shader#targetScale
         * @type {number}
         * @since 3.50.0
         */
        this.targetScale = GetFastValue(config, 'targetScale', 1);

        /**
         * An array of all the WebGLShader instances that belong to this pipeline.
         *
         * All shaders must use the same attributes, as set by this pipeline, but can manage their own
         * uniforms.
         *
         * These are set in a call to the `setShadersFromConfig` method, which happens automatically,
         * but can also be called at any point in your game. See the method documentation for details.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#shaders
         * @type {Phaser.Renderer.WebGL.WebGLShader[]}
         * @since 3.50.0
         */
        this.shaders = [];

        /**
         * A reference to the currently bound WebGLShader instance from the `WebGLPipeline.shaders` array.
         *
         * For lots of pipelines, this is the only shader, so it is a quick way to reference it without
         * an array look-up.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#currentShader
         * @type {Phaser.Renderer.WebGL.WebGLShader}
         * @since 3.50.0
         */
        this.currentShader;

        /**
         * The Model matrix, used by shaders as 'uModelMatrix' uniform.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#modelMatrix
         * @type {Phaser.Math.Matrix4}
         * @since 3.50.0
         */
        this.modelMatrix = new Matrix4().identity();

        /**
         * The View matrix, used by shaders as 'uViewMatrix' uniform.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#viewMatrix
         * @type {Phaser.Math.Matrix4}
         * @since 3.50.0
         */
        this.viewMatrix = new Matrix4().identity();

        /**
         * The Projection matrix, used by shaders as 'uProjectionMatrix' uniform.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#projectionMatrix
         * @type {Phaser.Math.Matrix4}
         * @since 3.50.0
         */
        this.projectionMatrix = new Matrix4().identity();

        /**
         * A flag indicating if the MVP matrices are dirty, or not.
         *
         * Used by WebGLShader when binding the uniforms.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#mvpDirty
         * @type {boolean}
         * @since 3.50.0
         */
        this.mvpDirty = true;

        /**
         * The configuration object that was used to create this pipeline.
         *
         * Treat this object as 'read only', because changing it post-creation will not
         * impact this pipeline in any way. However, it is used internally for cloning
         * and post-boot set-up.
         *
         * @name Phaser.Renderer.WebGL.WebGLPipeline#config
         * @type {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig}
         * @since 3.50.0
         */
        this.config = config;
    },

    /**
     * Called when the Game has fully booted and the Renderer has finished setting up.
     *
     * By this stage all Game level systems are now in place. You can perform any final tasks that the
     * pipeline may need, that relies on game systems such as the Texture Manager being ready.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#boot
     * @since 3.11.0
     */
    boot: function ()
    {
        var gl = this.gl;
        var config = this.config;

        var target = GetFastValue(config, 'target', false);

        var renderer = this.renderer;

        var width = renderer.width * this.targetScale;
        var height = renderer.height * this.targetScale;

        if (target && width > 0 && height > 0)
        {
            this.targetTexture = renderer.createTextureFromSource(null, width, height, 0);
            this.targetFramebuffer = renderer.createFramebuffer(width, height, this.targetTexture, false);

            // this.targetTexture.flipY = flipY;
        }

        this.setShadersFromConfig(config);

        //  Which shader has the largest vertex size?
        var i;
        var shaders = this.shaders;
        var vertexSize = 0;
        var vertexComponentCount = 0;

        for (i = 0; i < shaders.length; i++)
        {
            if (shaders[i].vertexSize > vertexSize)
            {
                vertexSize = shaders[i].vertexSize;
            }

            if (shaders[i].vertexComponentCount > vertexComponentCount)
            {
                vertexComponentCount = shaders[i].vertexComponentCount;
            }
        }

        this.vertexCapacity = GetFastValue(config, 'vertexCapacity', renderer.config.batchSize * vertexComponentCount);

        var data = GetFastValue(config, 'vertices', new ArrayBuffer(this.vertexCapacity * vertexSize));

        this.vertexData = data;

        if (GetFastValue(config, 'vertices', null))
        {
            this.vertexBuffer = renderer.createVertexBuffer(data, gl.STREAM_DRAW);
        }
        else
        {
            this.vertexBuffer = renderer.createVertexBuffer(data.byteLength, gl.STREAM_DRAW);
        }

        this.bytes = new Uint8Array(data);

        this.vertexViewF32 = new Float32Array(data);

        this.vertexViewU32 = new Uint32Array(data);

        //  Set-up shaders

        this.renderer.setVertexBuffer(this.vertexBuffer);

        for (i = 0; i < shaders.length; i++)
        {
            shaders[i].setAttribPointers(true);
        }

        this.currentShader.bind();

        this.hasBooted = true;

        this.onBoot();

        return this;
    },

    /**
     * This method is called once when this pipeline has finished being set-up
     * at the end of the boot process. By the time this method is called, all
     * of the shaders are ready and configured.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#onBoot
     * @since 3.50.0
     */
    onBoot: function ()
    {
    },

    /**
     * Resets the model, projection and view matrices to identity matrices.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#mvpInit
     * @since 3.50.0
     */
    mvpInit: function ()
    {
        this.modelMatrix.identity();
        this.projectionMatrix.identity();
        this.viewMatrix.identity();
    },

    /**
     * Creates a brand new WebGLPipeline instance based on the configuration object that
     * was used to create this one.
     *
     * The new instance is returned by this method. Note that the new instance is _not_
     * added to the Pipeline Manager. You will need to add it yourself should you require so.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#mvpInit
     * @since 3.50.0
     *
     * @param {string} name - The new name to give the cloned pipeline.
     *
     * @return {Phaser.Renderer.WebGL.WebGLPipeline} A clone of this WebGLPipeline instance.
     */
    clone: function (name)
    {
        var clone = new WebGLPipeline(this.config);

        clone.name = name;

        return clone;
    },

    /**
     * Sets the currently active shader within this pipeline.
     *
     * @method Phaser.Renderer.WebGL.WebGLPipeline#setShader
     * @since 3.50.0
     *
     * @param {Phaser.Renderer.WebGL.WebGLPipeline} shader - The shader to set as being current.
     * @param {boolean} [reset=false] - Should the vertex attribute pointers be fully reset?
     *
     * @return {this} This WebGLPipeline instance.
     */
    setShader: function (shader, reset)
    {
        if (shader !== this.currentShader)
        {
            this.flush();

            this.renderer.setVertexBuffer(this.vertexBuffer);

            shader.bind(reset);

            this.currentShader = shader;
{'fraction_non_alphanumeric': 0.09595573625164308, 'fraction_numerical': 0.01131048818512518, 'mean_word_length': 1.853628750872296, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4721461', 'n_tokens_mistral': 9358, 'n_tokens_neox': 8982, 'n_words': 2737}