<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>235478</bug_id>
          
          <creation_ts>2022-01-22 07:16:52 -0800</creation_ts>
          <short_desc>WebGL enabling Blend causes high performance drop</short_desc>
          <delta_ts>2022-03-01 02:22:10 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebGL</component>
          <version>Safari Technology Preview</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          <blocked>231180</blocked>
          <everconfirmed>1</everconfirmed>
          <reporter name="Reinis">muiznieks.reinis</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>dino</cc>
    
    <cc>johncunningham</cc>
    
    <cc>kbr</cc>
    
    <cc>kkinnunen</cc>
    
    <cc>kpiddington</cc>
    
    <cc>webkit-bug-importer</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1833008</commentid>
    <comment_count>0</comment_count>
    <who name="Reinis">muiznieks.reinis</who>
    <bug_when>2022-01-22 07:16:52 -0800</bug_when>
    <thetext>I develop a game using WebGL2. If I enable `gl.enable(gl.BLEND);` it causes the framerate to go down from 30 to 4. (Macbook air M1, but the same is for my iPad and iPhone as well)

In my scene, I have around 60k vertices (Updated every frame) + I use blend to overlay the screen with texture.


```
........

        // Bind uniforms
        gl.uniformBlockBinding(this.glProgram, this.uniBlockMain, 0);
        gl.uniform1i(this.uniTextures, 1); // texture sampler array is bound to texture1
        gl.uniform2fv(this.uniTextureOffsets, this.textureOffsets, 0);

        // We just allow the GL to do face culling. Note this requires the priority renderer
        // to have logic to disregard culled faces in the priority depth testing.
        gl.enable(gl.CULL_FACE);

        // Enable blending for alpha
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

        // Draw buffers
        gl.bindVertexArray(this.vaoHandle);

        gl.enableVertexAttribArray(0);
        gl.bindBuffer(gl.ARRAY_BUFFER, this.tmpVertexBuffer.buffer);
        gl.vertexAttribIPointer(0, 4, gl.INT, 0, 0);

        gl.enableVertexAttribArray(1);
        gl.bindBuffer(gl.ARRAY_BUFFER, this.tmpUvBuffer.buffer);
        gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);

        gl.drawArrays(gl.TRIANGLES, 0, this.vertexBuffer.length() / 4);

        // gl.disable(gl.BLEND);
        gl.disable(gl.CULL_FACE);

        gl.useProgram(null);

        this.vertexBuffer.clear();
        this.uvBuffer.clear();

        this.drawUi(canvasWidth, canvasHeight);

        gl.flush();

.....
```

````
    private drawUi(canvasWidth: number, canvasHeight: number) {
        const gl = this.gl;

        gl.enable(gl.BLEND);
		gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
		gl.bindTexture(gl.TEXTURE_2D, this.interfaceTexture);

		gl.useProgram(this.glUiProgram);
		gl.uniform2i(this.uniTexSourceDimensions, canvasWidth, canvasHeight);

        gl.viewport(0, 0, canvasWidth, canvasHeight);

        gl.uniform2i(this.uniTexTargetDimensions, canvasWidth, canvasHeight);
		
		// Texture on UI
		gl.bindVertexArray(this.vaoUiHandle);
		gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);

		gl.disable(gl.BLEND);
    }

```

Running on chrome I get stable 60fps :/</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1833175</commentid>
    <comment_count>1</comment_count>
    <who name="Alexey Proskuryakov">ap</who>
    <bug_when>2022-01-23 17:27:15 -0800</bug_when>
    <thetext>This seems like two issues: frame rate being 2x too low without blend, and 15x too low with it.

Could you please provide a complete test case that can be viewed in a browser?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1833223</commentid>
    <comment_count>2</comment_count>
    <who name="Reinis">muiznieks.reinis</who>
    <bug_when>2022-01-24 01:47:07 -0800</bug_when>
    <thetext>I have a working demo of my project here https://play.rsps.app/ 
Let me know if this is enough to check, or if I should create a smaller test case.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1833240</commentid>
    <comment_count>3</comment_count>
    <who name="Reinis">muiznieks.reinis</who>
    <bug_when>2022-01-24 02:52:44 -0800</bug_when>
    <thetext>I have made a bit of a breakthrough. Issue happens only if I render textures in the scene. Otherwise, it is solid 50 fps

```

export const fragmentShader = `#version 300 es

    precision highp float;
    precision highp int;
    precision highp sampler2DArray;

    uniform sampler2DArray textures;
    uniform vec2 textureOffsets[128];
    uniform float brightness;
    uniform float smoothBanding;
    uniform vec4 fogColor;
    uniform int colorBlindMode;
    uniform float textureLightMode;

    in vec4 Color;
    centroid in float fHsl;
    flat in int textureId;
    in vec2 fUv;
    in float fogAmount;

    out vec4 FragColor;

    ${hslToRgb}

    void main()	{
        vec4 c;

        // if (textureId &gt; 0) {
        //     int textureIdx = textureId - 1;

        //     vec2 animatedUv = fUv + textureOffsets[textureIdx];

        //     vec4 textureColor = texture(textures, vec3(animatedUv, float(textureIdx)));

        //     vec4 textureColorBrightness = pow(textureColor, vec4(brightness, brightness, brightness, 1.0f));

        //     vec3 mul = 1.0 - (Color.rgb);
        //     c = textureColorBrightness * vec4(mul, 1.f);
        // } else {
            c = Color;
        // }

        vec3 mixedColor = mix(c.rgb, fogColor.rgb, fogAmount);
        FragColor = vec4(mixedColor, c.a);

    }
`;
```

This is my fragment shader I have commented part and it works smooth.

```
export const initTextureArray = (gl: WebGL2RenderingContext): WebGLTexture | null =&gt; {
    if (!allTexturesLoaded()) {
        return null;
    }

    const textures = Rasterizer3D.textures;

    const textureArray = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D_ARRAY, textureArray);
    gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 8, gl.RGBA8, TEXTURE_SIZE, TEXTURE_SIZE, textures.length);

    gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

    gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);

    // Set brightness to 1.0d to upload unmodified textures to GPU
    const save = Rasterizer3D.brightness;
    Rasterizer3D.setBrightness(1.0);

    updateTextures(gl);

    Rasterizer3D.setBrightness(save);

    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D_ARRAY, textureArray);
    gl.generateMipmap(gl.TEXTURE_2D_ARRAY);
    gl.activeTexture(gl.TEXTURE0);

    return textureArray;
};
```

Code responsible for loading `uniform sampler2DArray textures;`

I did notice this bug https://bugs.webkit.org/show_bug.cgi?id=223322 I wonder if it is related. Maybe my textures change internal pixel format that safari doesn&apos;t support well?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1833242</commentid>
    <comment_count>4</comment_count>
    <who name="Reinis">muiznieks.reinis</who>
    <bug_when>2022-01-24 03:21:12 -0800</bug_when>
    <thetext>The 30 FPS limit I noticed before was because the console was open. Didn&apos;t know before that it affects it.

Seems like I found the issue..

* Causes lag
```
int textureIdx = textureId - 1;
vec2 animatedUv = fUv + textureOffsets[textureIdx];
```

* Causes lag
```
int textureIdx = textureId - 1;
if (textureIdx &gt; 127) {
    c = Color;
    return;
}
vec2 animatedUv = fUv + textureOffsets[textureIdx];
```

* Doesn&apos;t lag
```
int textureIdx = textureId - 1;
vec2 animatedUv = fUv + textureOffsets[1];
```

* Doesn&apos;t lag
```
int textureIdx = 1;
vec2 animatedUv = fUv + textureOffsets[textureIdx];
```


* Doesn&apos;t lag
```
int textureIdx = textureId - 1;
vec2 animatedUv = fUv;
```

I did a bit more experiments, but it seems that using `flat in int textureId;` as an index in `uniform vec2 textureOffsets[128];` causes lag.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1833391</commentid>
    <comment_count>5</comment_count>
    <who name="Kenneth Russell">kbr</who>
    <bug_when>2022-01-24 11:01:09 -0800</bug_when>
    <thetext>The use of flat interpolation will probably trigger a code path where indices will be rewritten every frame. This is a known area for future optimization in the Metal backend.

Please try to create a smaller test case. This report is not easily investigated without one. Thanks.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1835284</commentid>
    <comment_count>6</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2022-01-29 07:17:18 -0800</bug_when>
    <thetext>&lt;rdar://problem/88224455&gt;</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>