summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html
blob: 35b8c3ddabc55f1796ad36b4f04d5735ce7f4760 (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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!--
Copyright (c) 2019 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>WebGL BlitFramebuffer Tests</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>
</head>
<body>
<canvas id="canvas" width="8" height="8"></canvas>
<div id="description"></div>
<div id="console"></div>

<script>
"use strict";

var wtu = WebGLTestUtils;
description("This test verifies the functionality of blitFramebuffer with multiple draw buffers (srgb image and linear image).");

var gl = wtu.create3DContext("canvas", undefined, 2);
var linearMask = 1;
var srgbMask = 2;

if (!gl) {
    testFailed("WebGL context does not exist");
} else {
    testPassed("WebGL context exists");

    var filters = [gl.LINEAR, gl.NEAREST];
    var drawbuffersFormats = [linearMask, srgbMask, linearMask | srgbMask];
    for (var ii = 0; ii < filters.length; ++ii) {
        for (var jj = 0; jj < drawbuffersFormats.length; ++jj) {
            blitframebuffer_srgb_and_linear_drawbuffers(gl.SRGB8_ALPHA8, drawbuffersFormats[jj], filters[ii]);
            blitframebuffer_srgb_and_linear_drawbuffers(gl.RGBA8, drawbuffersFormats[jj], filters[ii]);
        }
    }
}

function blitframebuffer_srgb_and_linear_drawbuffers(readbufferFormat, drawbuffersFormatMask, filter) {
    debug("");
    debug("The filter is: " + wtu.glEnumToString(gl, filter));
    debug("Read buffer format is: " + wtu.glEnumToString(gl, readbufferFormat));
    var drawbuffersFormat = "\0";
    if (drawbuffersFormatMask & linearMask) {
        drawbuffersFormat += " linear ";
    }
    if (drawbuffersFormatMask & srgbMask) {
        drawbuffersFormat += " srgb ";
    }
    debug("The test have multiple draw buffers, the images are: " + drawbuffersFormat);

    var tex_srgb0 = gl.createTexture();
    var tex_srgb1 = gl.createTexture();
    var tex_linear0 = gl.createTexture();
    var tex_linear1 = gl.createTexture();
    var tex_read = gl.createTexture();
    var fbo_read = gl.createFramebuffer();
    var fbo_draw = gl.createFramebuffer();

    // Create read buffer and feed data to the read buffer
    var size = 8;
    var data = new Uint8Array(size * size * 4);
    var color = [250, 100, 15, 255];
    for (var ii = 0; ii < size * size * 4; ii += 4) {
        for (var jj = 0; jj < 4; ++jj) {
          data[ii + jj] = color[jj];
        }
    }
    gl.bindTexture(gl.TEXTURE_2D, tex_read);
    gl.texImage2D(gl.TEXTURE_2D, 0, readbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
    gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_read, 0);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup read framebuffer should succeed");

    // Create multiple textures. Attach them as fbo's draw buffers.
    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);

    var drawbuffers = [gl.NONE, gl.NONE, gl.NONE, gl.NONE];
    if (drawbuffersFormatMask & srgbMask) {
        gl.bindTexture(gl.TEXTURE_2D, tex_srgb0);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex_srgb0, 0);
        gl.bindTexture(gl.TEXTURE_2D, tex_srgb1);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, tex_srgb1, 0);
        drawbuffers[0] = gl.COLOR_ATTACHMENT0;
        drawbuffers[2] = gl.COLOR_ATTACHMENT2;
    }

    if (drawbuffersFormatMask & linearMask) {
        gl.bindTexture(gl.TEXTURE_2D, tex_linear0);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex_linear0, 0);
        gl.bindTexture(gl.TEXTURE_2D, tex_linear1);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT3, gl.TEXTURE_2D, tex_linear1, 0);
        drawbuffers[1] = gl.COLOR_ATTACHMENT1;
        drawbuffers[3] = gl.COLOR_ATTACHMENT3;
    }

    gl.drawBuffers(drawbuffers);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "setup draw framebuffer should succeed");

    if (gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE ||
        gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
        testFailed("Framebuffer incomplete when setup draw framebuffer.");
        return;
    }

    // Blit to multiple draw buffers with srgb images and linear images
    var dstSize = size - 1;
    gl.blitFramebuffer(0, 0, size, size, 0, 0, dstSize, dstSize, gl.COLOR_BUFFER_BIT, filter);
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "blitframebuffer should succeed");

    // Read pixels from srgb images and linear images
    var srgbPixels0 = new Uint8Array(dstSize * dstSize * 4);
    var srgbPixels1 = new Uint8Array(dstSize * dstSize * 4);
    var linearPixels0 = new Uint8Array(dstSize * dstSize * 4);
    var linearPixels1 = new Uint8Array(dstSize * dstSize * 4);
    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
    if (drawbuffersFormatMask & srgbMask) {
        gl.readBuffer(gl.COLOR_ATTACHMENT0);
        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, srgbPixels0);
        gl.readBuffer(gl.COLOR_ATTACHMENT2);
        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, srgbPixels1);
    }

    if (drawbuffersFormatMask & linearMask) {
        gl.readBuffer(gl.COLOR_ATTACHMENT1);
        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, linearPixels0);
        gl.readBuffer(gl.COLOR_ATTACHMENT3);
        gl.readPixels(0, 0, dstSize, dstSize, gl.RGBA, gl.UNSIGNED_BYTE, linearPixels1);
    }
    wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readpixels should succeed");

    // Compare
    var expectedSRGBColor = (readbufferFormat == gl.SRGB8_ALPHA8) ? color : wtu.linearToSRGB(color);
    var expectedLinearColor = (readbufferFormat == gl.SRGB8_ALPHA8) ? wtu.sRGBToLinear(color) : color;
    var failed = false;
    for (var ii = 0; ii < dstSize; ++ii) {
        for (var jj = 0; jj < dstSize; ++jj) {
            var index = (ii * dstSize + jj) * 4;
            if (drawbuffersFormatMask & srgbMask) {
                var srgbColor0 = [srgbPixels0[index], srgbPixels0[index + 1], srgbPixels0[index + 2], srgbPixels0[index + 3]];
                if (checkPixel(srgbColor0, expectedSRGBColor) == false) {
                    failed = true;
                    debug("Pixels comparison failed for the 1st sRGB image. Pixel at [" + jj + ", " + ii + "] should be (" + expectedSRGBColor + "), but the actual color is (" + srgbColor0 + ")");
                }
                var srgbColor1 = [srgbPixels1[index], srgbPixels1[index + 1], srgbPixels1[index + 2], srgbPixels1[index + 3]];
                if (checkPixel(srgbColor1, expectedSRGBColor) == false) {
                    failed = true;
                    debug("Pixels comparison failed for the 2nd sRGB image. Pixel at [" + jj + ", " + ii + "] should be (" + expectedSRGBColor + "), but the actual color is (" + srgbColor1 + ")");
                }
            }

            if (drawbuffersFormatMask & linearMask) {
                var linearColor0 = [linearPixels0[index], linearPixels0[index + 1], linearPixels0[index + 2], linearPixels0[index + 3]];
                if (checkPixel(linearColor0, expectedLinearColor) == false) {
                    failed = true;
                    debug("Pixel comparison failed for the 1st linear image. Pixel at [" + jj + ", " + ii + "] should be (" + color + "), but the actual color is (" + linearColor0 + ")");
                }
                var linearColor1 = [linearPixels1[index], linearPixels1[index + 1], linearPixels1[index + 2], linearPixels1[index + 3]];
                if (checkPixel(linearColor1, expectedLinearColor) == false) {
                    failed = true;
                    debug("Pixel comparison failed for the 2nd linear image. Pixel at [" + jj + ", " + ii + "] should be (" + color + "), but the actual color is (" + linearColor1 + ")");
                }
            }
        }
    }
    if (failed == false) {
        testPassed("All pixels comparision passed!");
    }

    // deinit
    gl.bindTexture(gl.TEXTURE_2D, null);
    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
    gl.deleteTexture(tex_srgb0);
    gl.deleteTexture(tex_linear0);
    gl.deleteTexture(tex_srgb1);
    gl.deleteTexture(tex_linear1);
    gl.deleteTexture(tex_read);
    gl.deleteFramebuffer(fbo_read);
    gl.deleteFramebuffer(fbo_draw);
}

function checkPixel(color, expectedColor) {
  var tolerance = 3;
  return (Math.abs(color[0] - expectedColor[0]) <= tolerance &&
          Math.abs(color[1] - expectedColor[1]) <= tolerance &&
          Math.abs(color[2] - expectedColor[2]) <= tolerance &&
          Math.abs(color[3] - expectedColor[3]) <= tolerance);
}

var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>

</body>
</html>