summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-mochitest/test_hidden_depth_stencil.html
blob: 987af9e371e2769dd4f892809f54f6723e64185e (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
<!DOCTYPE HTML>
<title>WebGL test: Hidden depth/stencil passes without a depth/stencil buffer respectively</title>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='webgl-util.js'></script>
<body>
<script id='vs' type='x-shader/x-vertex'>
  void main(void) {
    gl_PointSize = 1.0; // Note that this is undefined if we don't write to it!
    gl_Position = vec4(vec3(0), 1);
  }
</script>

<script id='fs' type='x-shader/x-fragment'>
  precision mediump float;

  void main(void) {
    gl_FragColor = vec4(0, 1, 0, 1);
  }
</script>
<script>

function ColorString(arr) {
  return '[' + arr[0] + ', ' + arr[1] + ', ' + arr[2] + ', ' + arr[3] + ']';
}

function DrawAndCheck(gl, infoPrefix, refColorStr) {
  gl.viewport(0, 0, 1, 1);

  gl.clearColor(1, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
  gl.drawArrays(gl.POINTS, 0, 1);

  var pixel = new Uint8Array(4);
  gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
  var pixelStr = ColorString(pixel);

  ok(pixelStr == refColorStr, infoPrefix + pixelStr + ' should be ' + refColorStr);
}

function TestCurrent(gl, attribs, infoPrefix) {
  infoPrefix = infoPrefix + JSON.stringify(attribs) + ': ';

  var CLEAR_COLOR = ColorString([255, 0, 0, 255]);
  var DRAW_COLOR = ColorString([0, 255, 0, 255]);

  gl.disable(gl.DEPTH_TEST);
  gl.disable(gl.STENCIL_TEST);

  DrawAndCheck(gl, infoPrefix + 'initial: ', DRAW_COLOR);

  if (!attribs.depth) {
    gl.enable(gl.DEPTH_TEST);
    gl.depthFunc(gl.NEVER);

    gl.disable(gl.STENCIL_TEST);

    // Depth test is enabled, and should pass NEVER.
    // Since there is no depth buffer, the depth test is not run.
    // Stencil test is disabled.
    DrawAndCheck(gl, infoPrefix + 'no-depth: ', DRAW_COLOR);
  }

  if (!attribs.stencil) {
    gl.disable(gl.DEPTH_TEST);

    gl.enable(gl.STENCIL_TEST);
    gl.stencilFunc(gl.NEVER, 0, 0);

    // Depth test is disabled.
    // Stencil test is enabled, and should pass NEVER.
    // Since there is no stencil buffer, the stencil test is not run.
    DrawAndCheck(gl, infoPrefix + 'no-stencil: ', DRAW_COLOR);
  }
}

function TestBackbuffer(requestedAttribs) {
  var canvas = document.createElement('canvas');
  canvas.width = 1;
  canvas.height = 1;
  var gl = canvas.getContext('experimental-webgl', requestedAttribs);
  if (!gl) {
    ok(true, 'WebGL doesn\'t work, skipping test.');
    return;
  }

  ok(gl.drawingBufferWidth == 1 && gl.drawingBufferHeight == 1,
     'backbuffer should be 1x1');

  var prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs');
  gl.useProgram(prog);

  var attribs = {
    depth: gl.getContextAttributes().depth,
    stencil: gl.getContextAttributes().stencil,
  };
  TestCurrent(gl, attribs, 'Backbuffer: ');
}

function TestUserFB() {
  var canvas = document.createElement('canvas');
  var gl = canvas.getContext('experimental-webgl');
  if (!gl) {
    ok(true, 'WebGL doesn\'t work, skipping test.');
    return;
  }

  var prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs');
  gl.useProgram(prog);

  var rb = gl.createRenderbuffer();
  gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
  gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 1, 1);

  var fb = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
  gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);

  var depthRB = gl.createRenderbuffer();
  gl.bindRenderbuffer(gl.RENDERBUFFER, depthRB);
  gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);

  var stencilRB = gl.createRenderbuffer();
  gl.bindRenderbuffer(gl.RENDERBUFFER, stencilRB);
  gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, 1, 1);

  do {
    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
    var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    if (status != gl.FRAMEBUFFER_COMPLETE) {
      ok(true, 'Depth-only user FB is incomplete. This is allowed.');
      break;
    }

    TestCurrent(gl, {depth: true, stencil: false}, 'Depth-only user FB');
  } while (false);

  do {
    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, stencilRB);
    var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    if (status != gl.FRAMEBUFFER_COMPLETE) {
      ok(true, 'Stencil-only user FB is incomplete. This is allowed.');
      break;
    }

    TestCurrent(gl, {depth: false, stencil: true}, 'Stencil-only user FB');
  } while (false);
}

(function(){
  TestBackbuffer({depth: true, stencil: false});
  TestBackbuffer({depth: false, stencil: true});
  TestUserFB();
})();

</script>
</body>