summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rasterizer-discard-and-implicit-clear.html
blob: f605a25f26445bf65ec461bf4cd9bf0eccb8e483 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<!--
Copyright (c) 2020 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>RASTERIZER_DISCARD doesn't affect implicit clears</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
<script id="vshader" type="x-shader/x-vertex">#version 300 es
layout(location=0) in vec2 vPosition;
uniform float xTranslation;
void main(void) {
  gl_Position = vec4(vPosition[0] + xTranslation, vPosition[1], 0.0, 1.0);
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
uniform vec4 color;
out vec4 outColor;
void main() {
  outColor = color;
}
</script>
</head>
<body>
<canvas id="example"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
debug("");

description("Enabling RASTERIZER_DISCARD should not affect implicit clears");

const wtu = WebGLTestUtils;
const canvas = document.getElementById("example");
const sz = canvas.width = canvas.height = 256;
const gl = wtu.create3DContext(canvas, undefined, 2);
const NUM_FRAMES = 15;
let framesToGo = NUM_FRAMES;
let xTranslationLoc;
let colorLoc;
const positionLocation = 0;
const red = [ 1.0, 0.0, 0.0, 1.0 ];
const green = [ 0.0, 1.0, 0.0, 1.0 ];
const transparentBlackRender = [ 0, 0, 0, 0 ];
const greenRender = [ 0, 255, 0, 255 ];

if (!gl) {
    testFailed("WebGL context creation failed");
    finishTest();
} else {
    testPassed("WebGL context creation succeeded");
    runDrawTest();
}

function runDrawTest() {
    debug("Verify that draws with rasterizer discard enabled do not interfere with implicit clears");
    let prog = wtu.loadProgramFromScript(gl, "vshader", "fshader");
    gl.useProgram(prog);
    xTranslationLoc = gl.getUniformLocation(prog, "xTranslation");
    colorLoc = gl.getUniformLocation(prog, "color");
    let leftRectBuffer = gl.createBuffer();
    gl.enableVertexAttribArray(positionLocation);
    gl.bindBuffer(gl.ARRAY_BUFFER, leftRectBuffer);
    // Create a rectangle covering the left half of the viewport, in
    // normalized device coordinates.
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
         0.0,  1.0,
        -1.0,  1.0,
        -1.0, -1.0,
         0.0,  1.0,
        -1.0, -1.0,
         0.0, -1.0]), gl.STATIC_DRAW);
    gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
    requestAnimationFrame(renderDrawTestFrame);
}

function renderDrawTestFrame() {
    // Animation is required in order to expose this bug. When it
    // occurs, the rectangle leaves trails behind it.
    gl.uniform1f(xTranslationLoc, 0.0);
    gl.enable(gl.RASTERIZER_DISCARD);
    gl.uniform4fv(colorLoc, red);
    gl.drawArrays(gl.TRIANGLES, 0, 6);
    gl.disable(gl.RASTERIZER_DISCARD);

    // Animate the rectangle from the left to the right half of the viewport.
    gl.uniform1f(xTranslationLoc, (NUM_FRAMES - framesToGo) / NUM_FRAMES);
    // Draw the last frame with green so any (incorrect) trails are visibly red.
    if (framesToGo == 0)
        gl.uniform4fv(colorLoc, green);
    gl.drawArrays(gl.TRIANGLES, 0, 6);

    if (framesToGo-- == 0) {
        // The left half of the canvas should be transparent black,
        // which comes from the implicit clear just before drawing the
        // rectangle without rasterizer discard enabled.
        wtu.checkCanvasRect(gl, 0, 0, sz / 2, sz, transparentBlackRender, "left half of canvas should be clear", 3);
        // The right half of the canvas should be solid green, from
        // the last render of the translated rectangle.
        wtu.checkCanvasRect(gl, sz / 2, 0, sz / 2, sz, greenRender, "right half of canvas should be green", 3);
        runReadPixelsTest();
    } else {
        requestAnimationFrame(renderDrawTestFrame);
    }
}

function runReadPixelsTest() {
    debug("Verify that readPixels with rasterizer discard enabled receives implicitly cleared data");
    framesToGo = NUM_FRAMES;  // Reset state.
    // Clear to transparent black.
    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    // Start with rasterizer discard enabled.
    gl.enable(gl.RASTERIZER_DISCARD);
    requestAnimationFrame(renderReadPixelsTestFrame);
}

function renderReadPixelsTestFrame() {
    // Rasterizer discard is enabled at the beginning of this test.

    // The canvas should always contain transparent black at the beginning of the frame.
    wtu.checkCanvasRect(gl, 0, 0, sz, sz, transparentBlackRender, undefined, 3);

    gl.disable(gl.RASTERIZER_DISCARD);
    // Clear to red.
    gl.clearColor(1.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    // Enable rasterizer discard again.
    gl.enable(gl.RASTERIZER_DISCARD);

    if (--framesToGo == 0) {
        finishTest();
    } else {
        requestAnimationFrame(renderReadPixelsTestFrame);
    }
}

</script>

</body>
</html>