|
1 <!-- |
|
2 Copyright (c) 2011 The Chromium Authors. All rights reserved. |
|
3 Use of this source code is governed by a BSD-style license that can be |
|
4 found in the LICENSE file. |
|
5 --> |
|
6 <!DOCTYPE html> |
|
7 <html> |
|
8 <head> |
|
9 <meta charset="utf-8"> |
|
10 <link rel="stylesheet" href="../../resources/js-test-style.css"/> |
|
11 <script src="../../resources/js-test-pre.js"></script> |
|
12 <script src="../resources/webgl-test.js"></script> |
|
13 <script id="vshader" type="x-shader/x-vertex"> |
|
14 attribute vec3 pos; |
|
15 attribute vec4 colorIn; |
|
16 varying vec4 color; |
|
17 |
|
18 void main() |
|
19 { |
|
20 color = colorIn; |
|
21 gl_Position = vec4(pos.xyz, 1.0); |
|
22 } |
|
23 </script> |
|
24 |
|
25 <script id="fshader" type="x-shader/x-fragment"> |
|
26 precision mediump float; |
|
27 varying vec4 color; |
|
28 |
|
29 void main() |
|
30 { |
|
31 gl_FragColor = color; |
|
32 } |
|
33 </script> |
|
34 </head> |
|
35 <body> |
|
36 <canvas id="example" width="32px" height="32px"></canvas> |
|
37 <div id="description"></div> |
|
38 <div id="console"></div> |
|
39 <script> |
|
40 var successfullyParsed = false; |
|
41 |
|
42 // The below declarations need to be global for "shouldBe" to see them |
|
43 var gl = null; |
|
44 var array = null; |
|
45 var pixel = [ 0, 0, 0, 0 ]; |
|
46 var expectedColor = [ 0, 0, 0, 0 ]; |
|
47 |
|
48 function calculatePixelBytes(format, type) |
|
49 { |
|
50 var size = 0; |
|
51 switch (format) { |
|
52 case gl.ALPHA: |
|
53 size = 1; |
|
54 break; |
|
55 case gl.RGB: |
|
56 size = 3; |
|
57 break; |
|
58 case gl.RGBA: |
|
59 size = 4; |
|
60 break; |
|
61 default: |
|
62 return -1; |
|
63 } |
|
64 switch (type) { |
|
65 case gl.UNSIGNED_BYTE: |
|
66 break; |
|
67 case gl.UNSIGNED_SHORT_5_6_5: |
|
68 if (format != gl.RGB) |
|
69 return -1; |
|
70 size = 2; |
|
71 break; |
|
72 case gl.UNSIGNED_SHORT_4_4_4_4: |
|
73 case gl.UNSIGNED_SHORT_5_5_5_1: |
|
74 if (format != gl.RGBA) |
|
75 return -1; |
|
76 size = 2; |
|
77 break; |
|
78 default: |
|
79 return -1; |
|
80 } |
|
81 return size; |
|
82 } |
|
83 |
|
84 function calculatePaddingBytes(bytesPerPixel, packAlignment, width) |
|
85 { |
|
86 var padding = 0; |
|
87 switch (packAlignment) { |
|
88 case 1: |
|
89 case 2: |
|
90 case 4: |
|
91 case 8: |
|
92 padding = (bytesPerPixel * width) % packAlignment; |
|
93 if (padding > 0) |
|
94 padding = packAlignment - padding; |
|
95 break; |
|
96 default: |
|
97 return -1; |
|
98 } |
|
99 return padding; |
|
100 } |
|
101 |
|
102 function packColor(format, type, r, g, b, a) |
|
103 { |
|
104 // FIXME: not sure if the color packing is correct for UNSIGNED_SHORT_*. |
|
105 var color = [ 0, 0, 0, 0 ]; |
|
106 switch (type) { |
|
107 case gl.UNSIGNED_BYTE: |
|
108 switch (format) { |
|
109 case gl.ALPHA: |
|
110 color[0] = a; |
|
111 break; |
|
112 case gl.RGB: |
|
113 color[0] = r; |
|
114 color[1] = g; |
|
115 color[2] = b; |
|
116 break; |
|
117 case gl.RGBA: |
|
118 color[0] = r; |
|
119 color[1] = g; |
|
120 color[2] = b; |
|
121 color[3] = a; |
|
122 break; |
|
123 default: |
|
124 return null; |
|
125 } |
|
126 break; |
|
127 case gl.UNSIGNED_SHORT_5_6_5: |
|
128 if (format != gl.RGB) |
|
129 return null; |
|
130 r >>= 3; |
|
131 g >>= 2; |
|
132 b >>= 3; |
|
133 color[0] = (r << 11) + (g << 5) + b; |
|
134 break; |
|
135 case gl.UNSIGNED_SHORT_4_4_4_4: |
|
136 if (format != gl.RGBA) |
|
137 return null; |
|
138 r >>= 4; |
|
139 g >>= 4; |
|
140 b >>= 4; |
|
141 a >>= 4; |
|
142 color[0] = (r << 12) + (g << 8) + (b << 4) + a; |
|
143 break; |
|
144 case gl.UNSIGNED_SHORT_5_5_5_1: |
|
145 if (format != gl.RGBA) |
|
146 return null; |
|
147 r >>= 3; |
|
148 g >>= 3; |
|
149 b >>= 3; |
|
150 a >>= 7; |
|
151 color[0] = (r << 11) + (g << 6) + (b << 1) + a; |
|
152 break; |
|
153 Default: |
|
154 return null; |
|
155 } |
|
156 return color; |
|
157 } |
|
158 |
|
159 function runTestIteration(format, type, packAlignment, width, height) |
|
160 { |
|
161 debug("Testing PACK_ALIGNMENT = " + packAlignment + ", width = " + width + ", height = " + height); |
|
162 gl.clearColor(1, 0.4, 0, 1); |
|
163 gl.clear(gl.COLOR_BUFFER_BIT); |
|
164 gl.pixelStorei(gl.PACK_ALIGNMENT, packAlignment); |
|
165 glErrorShouldBe(gl, gl.NO_ERROR); |
|
166 var bytesPerPixel = calculatePixelBytes(format, type); |
|
167 var padding = calculatePaddingBytes(bytesPerPixel, packAlignment, width); |
|
168 var size = bytesPerPixel * width * height + padding * (height - 1); |
|
169 if (type != gl.UNSIGNED_BYTE) { |
|
170 throw "test error: only UNSIGNED_BYTE is valid to ReadPixels"; |
|
171 } |
|
172 if (size < 0) |
|
173 size = 0; |
|
174 array = new Uint8Array(size); |
|
175 gl.readPixels(0, 0, width, height, format, type, array); |
|
176 if (width < 0 || height < 0) { |
|
177 glErrorShouldBe(gl, gl.INVALID_VALUE); |
|
178 return; |
|
179 } |
|
180 |
|
181 glErrorShouldBe(gl, gl.NO_ERROR); |
|
182 if (!array.length) |
|
183 return; |
|
184 |
|
185 // Check the last pixel of the last row. |
|
186 var bytesPerRow = width * bytesPerPixel + padding; |
|
187 var pos = bytesPerRow * (height - 1) + (width - 1) * bytesPerPixel; |
|
188 var numComponents = bytesPerPixel; |
|
189 for (var i = 0; i < numComponents; ++i) |
|
190 pixel[i] = array[pos + i]; |
|
191 for (var i = numComponents; i < 4; ++i) |
|
192 pixel[i] = 0; |
|
193 expectedColor = packColor(format, type, 255, 102, 0, 255); |
|
194 shouldBeNonNull("expectedColor"); |
|
195 shouldBe("pixel", "expectedColor"); |
|
196 } |
|
197 |
|
198 description('Verify readPixels() works fine with various PACK_ALIGNMENT values.'); |
|
199 |
|
200 shouldBeNonNull("gl = initWebGL('example', 'vshader', 'fshader', [ 'pos', 'colorIn' ], [ 0, 0, 0, 1 ], 1)"); |
|
201 gl.disable(gl.BLEND); |
|
202 |
|
203 var formats = [ gl.RGBA ]; |
|
204 var formatNames = [ "RGBA" ]; |
|
205 |
|
206 for (var i = 0; i < formats.length; ++i) { |
|
207 var format = formats[i]; |
|
208 |
|
209 debug("Testing format = " + formatNames[i] + " and type = UNSIGNED_BYTE"); |
|
210 runTestIteration(format, gl.UNSIGNED_BYTE, 1, 1, 2); |
|
211 runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, 2); |
|
212 runTestIteration(format, gl.UNSIGNED_BYTE, 4, 1, 2); |
|
213 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 1, 2); |
|
214 runTestIteration(format, gl.UNSIGNED_BYTE, 4, 2, 2); |
|
215 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 2, 2); |
|
216 runTestIteration(format, gl.UNSIGNED_BYTE, 4, 3, 2); |
|
217 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 3, 2); |
|
218 runTestIteration(format, gl.UNSIGNED_BYTE, 4, 4, 2); |
|
219 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 4, 2); |
|
220 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 1); |
|
221 runTestIteration(format, gl.UNSIGNED_BYTE, 4, 5, 2); |
|
222 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 2); |
|
223 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 6, 2); |
|
224 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 7, 2); |
|
225 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 8, 2); |
|
226 runTestIteration(format, gl.UNSIGNED_BYTE, 1, 0, 0); |
|
227 runTestIteration(format, gl.UNSIGNED_BYTE, 2, 0, 0); |
|
228 runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, 0); |
|
229 runTestIteration(format, gl.UNSIGNED_BYTE, 8, 0, 0); |
|
230 runTestIteration(format, gl.UNSIGNED_BYTE, 1, -1, 1); |
|
231 runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, -1); |
|
232 runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, -1); |
|
233 runTestIteration(format, gl.UNSIGNED_BYTE, 8, -1, -1); |
|
234 } |
|
235 |
|
236 successfullyParsed = true; |
|
237 </script> |
|
238 <script>finishTest();</script> |
|
239 </body> |
|
240 </html> |