summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/conformance/textures
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance/textures')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/00_test_list.txt14
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html39
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/00_test_list.txt58
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html100
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/compressed-tex-image.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-2d-formats.html173
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html137
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-crash.html69
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html65
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-subrects.html170
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-incomplete-fbo.html72
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-map-uploads-out-of-order.html90
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/default-texture.html42
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/exif-orientation.html167
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/format-filterable-renderable.html378
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-get-tex-parameter.html27
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-pixelstorei.html96
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html406
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/mipmap-fbo.html109
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance-offscreencanvas.html125
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance.html137
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/png-image-types.html164
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html304
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-uniform-binding-bugs.html44
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-canvas-corruption.html51
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-webgl.html78
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-format-and-type.html722
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-invalid-data.html158
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-input-validation.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d-bad-args.html133
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d.html101
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html191
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texparameter-test.html129
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind-2.html210
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind.html179
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-attachment-formats.html176
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-clear.html43
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-complete.html63
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-and-deletion.html91
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-feedback-loops.html82
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-corner-case-videos.html47
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-cube-as-fbo-attachment.html65
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-draw-with-2d-and-cube.html103
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-fakeblack.html94
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-formats-test.html274
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-hd-dpi.html117
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-mips.html297
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot-video.html160
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot.html305
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-cube-maps.html331
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-limit.html167
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size.html217
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-srgb-upload.html253
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-sub-image-cube-maps.html316
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-transparent-pixels-initialized.html87
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-cube-maps.html52
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-size.html151
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-video-transparent.html164
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html72
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/upload-from-srcset-with-empty-data.html44
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/video-rotation.html167
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html38
177 files changed, 12997 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/00_test_list.txt
new file mode 100644
index 0000000000..c6041ff82f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/00_test_list.txt
@@ -0,0 +1,14 @@
+misc/00_test_list.txt
+canvas/00_test_list.txt
+--min-version 1.0.4 canvas_sub_rectangle/00_test_list.txt
+image/00_test_list.txt
+image_data/00_test_list.txt
+--min-version 1.0.4 svg_image/00_test_list.txt
+video/00_test_list.txt
+webgl_canvas/00_test_list.txt
+image_bitmap_from_image_data/00_test_list.txt
+image_bitmap_from_image/00_test_list.txt
+image_bitmap_from_video/00_test_list.txt
+image_bitmap_from_canvas/00_test_list.txt
+image_bitmap_from_blob/00_test_list.txt
+image_bitmap_from_image_bitmap/00_test_list.txt
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..4d9e90a89a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..555ec9f7bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..3e2dd533f3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..c1048aba4f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..55177f4657
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..3db61ef492
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..f6dafa9a51
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..054ad8f7d3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..42b25dbe45
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..443bbeee85
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..03d6aff9b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..c3d2dcb1e8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..e841cd8b3b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..b41edb8f31
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..0b33104d30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..fe394c6ae3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..99a6d0aca0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..044c4d2334
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..a0eb04e7f1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..af6f0ffbf3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..a5f6adbd7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..4e9fcfb323
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..11033be46d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..57b5a3075b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..3a0f359d58
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..63137f0c12
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..28b68bb2c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..c8712cc226
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..c7f5406d8b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..3a94793561
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..011716760c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..84ea95ec34
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..60bc8c96ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..d69fbc1ff3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..c141ecd96e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..ad2f120c9f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..b89d10cc62
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..e6d6e105ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..3c9564a31c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..4aae144b39
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..9d371e7a7d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..ad59d05e7e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..d7a9ce4f9b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..d61f6ebf8e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..a3eeee8a9d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..f818adaa8a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..2b78f918e0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..f314b58319
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..14f6624c93
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..0802d11106
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..68ec518abb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..35b1e3bb85
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..6c55d536c9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..69cbc37d95
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..eae074f55f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..c0702275b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..aead08998d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..af81a29c07
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..c5b1d52ecd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..66ef9b8475
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..0bca358b3e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..91dc8e25c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..bc519e2e6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..2359b91b59
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..299282586d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..7471323b4e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..b700257b99
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..065dd77bc1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..6f1125132a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..e58c1612dc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..e49c039885
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..b5eeeb3b0f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..7b1b1ebd6a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..88ceac1072
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..c953c8be91
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..4650594945
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..49744f65f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..95bd9686c9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..9d80cf6927
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..b7a529f4ec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,39 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-image-data.js"></script>
+</head>
+<body>
+<canvas id="texcanvas" width="2" height="2"></canvas>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/00_test_list.txt
new file mode 100644
index 0000000000..c86c269d56
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/00_test_list.txt
@@ -0,0 +1,58 @@
+--min-version 1.0.4 canvas-teximage-after-multiple-drawimages.html
+--max-version 1.9.9 compressed-tex-image.html
+copy-tex-image-and-sub-image-2d.html
+--min-version 1.0.2 copy-tex-image-2d-formats.html
+--min-version 1.0.4 copy-tex-image-crash.html
+--min-version 1.0.4 copytexsubimage2d-large-partial-copy-corruption.html
+--min-version 1.0.4 copytexsubimage2d-subrects.html
+--min-version 1.0.4 cube-incomplete-fbo.html
+--min-version 1.0.4 cube-map-uploads-out-of-order.html
+--min-version 1.0.3 default-texture.html
+--min-version 1.0.4 exif-orientation.html
+--min-version 1.0.4 format-filterable-renderable.html
+--min-version 1.0.2 --max-version 1.9.9 gl-get-tex-parameter.html
+gl-pixelstorei.html
+gl-teximage.html
+--min-version 1.0.2 mipmap-fbo.html
+origin-clean-conformance.html
+--min-version 1.0.4 origin-clean-conformance-offscreencanvas.html
+tex-image-and-sub-image-2d-with-array-buffer-view.html
+tex-image-and-uniform-binding-bugs.html
+--min-version 1.0.3 tex-image-canvas-corruption.html
+--min-version 1.0.2 tex-image-webgl.html
+tex-image-with-format-and-type.html
+tex-image-with-invalid-data.html
+--max-version 1.9.9 tex-input-validation.html
+tex-sub-image-2d-bad-args.html
+tex-sub-image-2d.html
+--min-version 1.0.4 tex-video-using-tex-unit-non-zero.html
+texparameter-test.html
+texture-active-bind-2.html
+texture-active-bind.html
+--min-version 1.0.2 texture-attachment-formats.html
+--min-version 1.0.2 texture-clear.html
+texture-complete.html
+--min-version 1.0.4 texture-copying-and-deletion.html
+--min-version 1.0.3 texture-copying-feedback-loops.html
+--min-version 1.0.4 texture-corner-case-videos.html
+--min-version 1.0.4 texture-cube-as-fbo-attachment.html
+--min-version 1.0.3 texture-draw-with-2d-and-cube.html
+--min-version 1.0.3 --max-version 1.9.9 texture-fakeblack.html
+--min-version 1.0.2 --max-version 1.9.9 texture-formats-test.html
+--min-version 1.0.2 texture-hd-dpi.html
+texture-mips.html
+--max-version 1.9.9 texture-npot-video.html
+--max-version 1.9.9 texture-npot.html
+texture-size.html
+texture-size-cube-maps.html
+--min-version 1.0.2 texture-size-limit.html
+--min-version 1.0.4 texture-srgb-upload.html
+--min-version 1.0.2 texture-sub-image-cube-maps.html
+texture-transparent-pixels-initialized.html
+--min-version 1.0.2 texture-upload-cube-maps.html
+--min-version 1.0.3 texture-upload-size.html
+--min-version 1.0.4 texture-video-transparent.html
+--min-version 1.0.4 texture-with-flip-y-and-premultiply-alpha.html
+--min-version 1.0.4 upload-from-srcset-with-empty-data.html
+--min-version 1.0.4 video-rotation.html
+--min-version 1.0.4 png-image-types.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html
new file mode 100644
index 0000000000..0c5d45b7b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html
@@ -0,0 +1,100 @@
+<!--
+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>TexImage2D of 2D Canvas after multiple drawImages</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>
+"use strict";
+const wtu = WebGLTestUtils;
+
+const sz = 512;
+let greenImage = null;
+
+function loadImageAndStart(startFunc) {
+ let c = document.createElement('canvas');
+ c.width = sz;
+ c.height = sz;
+ let ctx = c.getContext('2d');
+ ctx.fillStyle = 'rgb(0,255,0)';
+ ctx.fillRect(0, 0, sz, sz);
+ greenImage = wtu.makeImageFromCanvas(c, startFunc);
+}
+
+function runTest() {
+ description();
+ debug('Regression test for <a href="http://crbug.com/878545">http://crbug.com/878545</a>');
+ // Mimics the image-to-texture upload path from the old JavaScript
+ // port of O3D, salvaged at https://github.com/petersont/o3d .
+
+ // Create a canvas and draw the entire image into it.
+ let bigCanvas = document.createElement('canvas');
+ bigCanvas.width = greenImage.naturalWidth;
+ bigCanvas.height = greenImage.naturalHeight;
+ let bc = bigCanvas.getContext('2d');
+ bc.drawImage(greenImage, 0, 0, bigCanvas.width, bigCanvas.height);
+ // Create a temp canvas to flip vertically.
+ let tempCanvas = document.createElement('canvas');
+ tempCanvas.width = bigCanvas.width;
+ tempCanvas.height = bigCanvas.height;
+ let tc = tempCanvas.getContext('2d');
+ tc.translate(0, tempCanvas.height);
+ tc.scale(1, -1);
+ tc.drawImage(bigCanvas, 0, 0, tempCanvas.width, tempCanvas.height);
+ // Set up to draw via WebGL.
+ let c3d = document.getElementById('canvas');
+ let gl = wtu.create3DContext(c3d);
+ let prog = wtu.setupTexturedQuad(gl);
+ gl.uniform1i(gl.getUniformLocation(prog, 'tex'), 0);
+ let tex = gl.createTexture();
+ // Iterate through the large canvas, drawing pieces of it to a
+ // scratch canvas.
+ let scratchCanvas = document.createElement('canvas');
+ const width = tempCanvas.width / 2;
+ const height = tempCanvas.height / 2;
+ let bb = new Uint8Array(4 * c3d.width * c3d.height);
+ for (let jj = 0; jj < 2; ++jj) {
+ for (let ii = 0; ii < 2; ++ii) {
+ // Prepare texture.
+ scratchCanvas.width = width;
+ scratchCanvas.height = height;
+ let ctx = scratchCanvas.getContext('2d');
+ ctx.save();
+ ctx.translate(-(ii * width), -(jj * height));
+ ctx.scale(1.0, 1.0);
+ ctx.drawImage(tempCanvas, 0, 0, tempCanvas.width, tempCanvas.height);
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
+ scratchCanvas);
+ ctx.restore();
+ gl.generateMipmap(gl.TEXTURE_2D);
+ // Draw and check that rendering occurred properly.
+ gl.uniform1i(gl.getUniformLocation(prog, 'tex'), 0);
+ wtu.drawUnitQuad(gl);
+ let tolerance = 2;
+ wtu.checkCanvasRect(gl, 1, 1, c3d.width - 2, c3d.height - 2,
+ [ 0, 255, 0, 255 ],
+ "should be green",
+ tolerance);
+
+ }
+ }
+
+ finishTest();
+}
+</script>
+</head>
+<body onload="loadImageAndStart(runTest)">
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="40" height="40"></canvas>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/compressed-tex-image.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/compressed-tex-image.html
new file mode 100644
index 0000000000..d019a65254
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/compressed-tex-image.html
@@ -0,0 +1,24 @@
+<!--
+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">
+<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>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+const contextVersion = 1;
+</script>
+<script src="../../../js/tests/compressed-tex-image.js"></script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-2d-formats.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-2d-formats.html
new file mode 100644
index 0000000000..fd44f9cc73
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-2d-formats.html
@@ -0,0 +1,173 @@
+<!--
+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>
+<title>Verify copyTexImage2D follows format restictions</title>
+<meta charset="utf-8">
+<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>
+<div id="description"></div>
+<canvas id="canvas" width="2" height="2"></canvas>
+<canvas id="canvasNoAlpha" width="2" height="2"></canvas>
+<div id="console"></div>
+<script>
+"use strict";
+
+function getChannelsFromFormat(format) {
+ switch (gl[format]) {
+ case gl.ALPHA:
+ return 0x0001;
+ case gl.LUMINANCE:
+ case gl.RGB:
+ return 0x1110;
+ case gl.LUMINANCE_ALPHA:
+ case gl.RGBA:
+ return 0x1111;
+ default:
+ return 0;
+ }
+}
+
+var formats = [
+ 'ALPHA',
+ 'LUMINANCE',
+ 'LUMINANCE_ALPHA',
+ 'RGB',
+ 'RGBA'
+];
+
+var isRenderable = {
+ 'ALPHA': false,
+ 'LUMINANCE': false,
+ 'LUMINANCE_ALPHA': false,
+ 'RGB': true,
+ 'RGBA': true
+};
+
+var gl = null;
+var wtu = WebGLTestUtils;
+
+description();
+
+var canvas = document.getElementById("canvas");
+var canvasNoAlpha = document.getElementById("canvasNoAlpha");
+var gl = wtu.create3DContext(canvas, {alpha:true});
+var glNoAlpha = wtu.create3DContext(canvasNoAlpha, {alpha:false});
+
+debug("test with an RGBA backbuffer");
+var program = wtu.setupTexturedQuad(gl);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "During Initialization");
+testFormats('RGBA');
+
+testBackbufferFormats();
+
+debug("test with an RGB backbuffer");
+var gl = glNoAlpha;
+var program = wtu.setupTexturedQuad(gl);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "During Initialization");
+testFormats('RGB');
+
+function testBackbufferFormats() {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ for (var ii = 0; ii < formats.length; ++ii) {
+ var backFormat = formats[ii];
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl[backFormat], 2, 2, 0, gl[backFormat], gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ debug('');
+ if (status == gl.FRAMEBUFFER_COMPLETE) {
+ if (!isRenderable[backFormat]) {
+ testFailed('Creating framebuffer from ' + backFormat + ' texture succeeded even though it is not a renderable format');
+ } else {
+ debug('test with ' + backFormat + ' fbo');
+ testFormats(backFormat);
+ }
+ } else {
+ debug(backFormat + ' not supported as a renderbuffer attachment');
+ }
+ }
+}
+
+function testFormats(backFormat) {
+ for (var ii = 0; ii < formats.length; ++ii) {
+ testCopyTexImage2D(backFormat, formats[ii]);
+ }
+}
+
+function toChannels(value) {
+ return ((value & 0x1000) ? 'R' : '_') +
+ ((value & 0x0100) ? 'G' : '_') +
+ ((value & 0x0010) ? 'B' : '_') +
+ ((value & 0x0001) ? 'A' : '_');
+}
+
+function testCopyTexImage2D(backFormat, texFormat) {
+ var need = getChannelsFromFormat(texFormat);
+ var have = getChannelsFromFormat(backFormat);
+ var shouldPass = (need & have) == need;
+
+ //debug("need: " + toChannels(need));
+ //debug("have: " + toChannels(have));
+ //debug("both: " + toChannels(have & need));
+
+ // clear backbuffer
+ gl.clearColor(0.25, 1, 0.75, 0.5);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ var texture = gl.createTexture();
+ // Bind the texture to texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl[texFormat], 0, 0, 2, 2, 0);
+ if (!shouldPass) {
+ wtu.glErrorShouldBe(
+ gl, gl.INVALID_OPERATION,
+ "should not be able to copyTexImage2D " + texFormat + " from " + backFormat);
+ return;
+ }
+
+ wtu.glErrorShouldBe(
+ gl, gl.NO_ERROR,
+ "should be able to copyTexImage2D " + texFormat + " from " + backFormat);
+
+ // Draw
+ wtu.clearAndDrawUnitQuad(gl);
+
+ var expectedColors = {
+ 'ALPHA': [0, 0, 0, 127],
+ 'LUMINANCE': [64, 64, 64, 255],
+ 'LUMINANCE_ALPHA': [64, 64, 64, 127],
+ 'RGB': [64, 255, 191, 255],
+ 'RGBA': [64, 255, 191, 127]
+ };
+
+ var color = expectedColors[texFormat];
+
+ wtu.checkCanvas(gl, color, "should be " + color, 16);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html
new file mode 100644
index 0000000000..a751582472
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html
@@ -0,0 +1,137 @@
+<!--
+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">
+<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>
+"use strict";
+var successfullyParsed = false;
+
+function init()
+{
+ description('Verify copyTexImage2D and copyTexSubImage2D');
+
+ runTest();
+}
+
+var gl = null;
+var wtu = WebGLTestUtils;
+
+function runTestIteration(antialias)
+{
+ var canvas = document.getElementById(
+ antialias ? "antialiasOn" : "antialiasOff");
+ var attribs = antialias ? { antialias: true } : { antialias: false };
+ gl = wtu.create3DContext(canvas, attribs);
+ var program = wtu.setupTexturedQuad(gl);
+ var textureLoc = gl.getUniformLocation(program, "tex");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "During Initialization");
+
+ gl.colorMask(1, 1, 1, 1);
+ gl.disable(gl.BLEND);
+ debug('Testing copyTexImage2D');
+
+ // Red canvas
+ gl.clearColor(1, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ var texture = gl.createTexture();
+ // Bind the texture to texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ // Set up texture
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.uniform1i(textureLoc, 0);
+
+ var colors = [
+ [1, 0, 0, 1],
+ [0, 1, 0, 1],
+ [0, 0, 1, 1],
+ [0.5, 0.5, 0.5, 0.5],
+ ];
+ var data = new Uint8Array(2 * 2 * 4);
+ for (var ii = 0; ii < 2 * 2 * 4; ++ii)
+ data[ii] = 136; // A random number other than 0.
+ var count = 0;
+ for (var yy = -2; yy <= 2; ++yy) {
+ for (var xx = -2; xx <= 2; ++xx) {
+ for (var ii = 0; ii < 2; ++ii) {
+ var texColor = colors[count];
+ var clearColor = colors[(count + 1) % colors.length];
+ // clear to some color
+ gl.clearColor(texColor[0], texColor[1], texColor[2], texColor[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ // copy that color to the texture.
+ switch (ii) {
+ case 0:
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, xx, yy, 2, 2, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "using copyTexImage2D: x = " + xx + ", y = " + yy);
+ break;
+ case 1:
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, xx, yy, 2, 2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "using copyTexSubImage2D: x = " + xx + ", y = " + yy);
+ break;
+ }
+
+ // clear to some other color.
+ gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ // Draw the triangles
+ wtu.clearAndDrawUnitQuad(gl);
+
+ // check the rendering results
+ for (var iy = 0; iy < 2; ++iy) {
+ for (var ix = 0; ix < 2; ++ix) {
+ var x = xx + ix;
+ var y = yy + iy;
+ var expectedColor = (x < 0 || y < 0 || x >= 2 || y >= 2) ?
+ (ii == 0 ? [0, 0, 0, 0] : [136, 136, 136, 136]) :
+ [Math.floor(255 * texColor[0]),
+ Math.floor(255 * texColor[1]),
+ Math.floor(255 * texColor[2]),
+ Math.floor(255 * texColor[3])];
+ wtu.checkCanvasRect(gl, ix, iy, 1, 1, expectedColor,
+ "" + ix + ", " + iy + " should render " + expectedColor + " (+/-1)", 1);
+ }
+ }
+ count = (count + 1) % colors.length;
+ }
+ }
+ }
+
+ debug("");
+}
+
+function runTest(antialias)
+{
+ debug("Testing with antialias on");
+ runTestIteration(true);
+ debug("Testing with antialias off");
+ runTestIteration(false);
+
+ finishTest();
+}
+</script>
+</head>
+<body onload="init()">
+<canvas id="antialiasOn" width="2" height="2"></canvas>
+<canvas id="antialiasOff" width="2" height="2"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-crash.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-crash.html
new file mode 100644
index 0000000000..994051672a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-crash.html
@@ -0,0 +1,69 @@
+<!--
+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>copyTexImage2D should not crash</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>
+<div id="description"></div>
+<canvas id="canvas"></canvas>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Draw into source of copyTexSubImage2D shouldn't crash: regression test for https://crbug.com/707445");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+canvas.width = 16;
+canvas.height = 16;
+var gl = wtu.create3DContext(canvas);
+
+function runTest() {
+ // Setup/clear source texture
+ let tex1 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ let fb1 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb1);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex1, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Setup/clear destination texture
+ let tex2 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ let fb2 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Copy from source to destination texture
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb1);
+ gl.bindTexture(gl.TEXTURE_2D, tex2);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 16, 16, 0);
+
+ // Draw into source texture
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ let program = wtu.setupColorQuad(gl); // Used as a trivial shader; any shader will work.
+ gl.useProgram(program);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+}
+
+runTest();
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html
new file mode 100644
index 0000000000..41fe47008f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html
@@ -0,0 +1,65 @@
+<!--
+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>CopyTexSubImage2D partial destination texture test</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>
+<div id="description"></div>
+<canvas id="canvas"></canvas>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Verifies that copyTexSubImage2D redefining part of the destination texture works as expected.");
+
+function runTest() {
+ var wtu = WebGLTestUtils;
+ var canvas = document.getElementById("canvas");
+ canvas.width = 256;
+ canvas.height = 256;
+ var gl = wtu.create3DContext(canvas);
+ // Try this test multiple times.
+ for (var ii = 0; ii < 10; ++ii) {
+ gl.clearColor(0.0, 1.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ // Allocate a texture twice as tall as the canvas.
+ // Conceptually, it is filled with zeros.
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, 2 * canvas.height,
+ 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ // Copy the entire framebuffer into the top part of this texture.
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, canvas.width, canvas.height);
+ // Draw the texture back into the canvas.
+ var program = wtu.setupTexturedQuad(gl);
+ wtu.drawUnitQuad(gl);
+ gl.deleteProgram(program);
+ gl.deleteTexture(tex);
+ wtu.checkCanvasRect(gl, 0, 0, canvas.width, canvas.height / 2, [0, 255, 0, 255],
+ "should be green");
+ wtu.checkCanvasRect(gl, 0, canvas.height / 2, canvas.width, canvas.height / 2, [0, 0, 0, 0],
+ "should be transparent black");
+ }
+}
+
+runTest();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-subrects.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-subrects.html
new file mode 100644
index 0000000000..d4a1791790
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-subrects.html
@@ -0,0 +1,170 @@
+<!--
+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>CopyTexSubImage2D partial destination texture test</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>
+<div id="description"></div>
+<canvas id="canvas"></canvas>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Verifies that copyTexSubImage2D redefining part of the destination texture works as expected.");
+
+////
+
+var kWidth = 16;
+var kHeight = 16;
+
+////
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+
+canvas.width = kWidth;
+canvas.height = kHeight;
+var gl = wtu.create3DContext(canvas);
+
+////
+
+function clearTo(color) {
+ gl.clearColor(color[0], color[1], color[2], color[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+}
+
+function readInto(view) {
+ gl.readPixels(0, 0, kWidth, kHeight, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(view.buffer));
+}
+
+////
+
+function runTest() {
+ gl.enable(gl.SCISSOR_TEST);
+
+ gl.scissor(0, 0, kWidth/2, kHeight/2);
+ clearTo([1,0,0,1]);
+ gl.scissor(kWidth/2, 0, kWidth/2, kHeight/2);
+ clearTo([0,1,0,1]);
+ gl.scissor(0, kHeight/2, kWidth/2, kHeight/2);
+ clearTo([0,0,1,1]);
+ gl.scissor(kWidth/2, kHeight/2, kWidth/2, kHeight/2);
+ clearTo([0,1,1,1]);
+
+ var srcData = new Uint32Array(kWidth * kHeight);
+ readInto(srcData);
+ console.log('0x' + srcData[0].toString(16));
+
+ ////
+
+ var dstTex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, dstTex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, kWidth, kHeight,
+ 0, gl.RGBA, gl.UNSIGNED_BYTE, null); // Uploads zeros.
+ var dstRefData = new Uint32Array(kWidth * kHeight); // Also cleared to zeros!
+ var dstTestData = new Uint32Array(kWidth * kHeight);
+
+ var dstFB = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, dstFB);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, dstTex, 0);
+
+ ////
+
+ function pixelPos(x, y) {
+ return y * kWidth + x;
+ }
+
+ function testCmd(tuple) {
+ var dstX0, dstY0, srcX0, srcY0, width, height;
+ [dstX0, dstY0, srcX0, srcY0, width, height] = tuple
+ debug("copyTexSubImage2D(" +
+ [dstX0+','+dstY0, srcX0+','+srcY0, width+','+height].join(', ') +
+ ")");
+
+ // Test
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0,
+ dstX0, dstY0, srcX0, srcY0, width, height);
+
+ // Emulate for reference
+ for (var x = 0; x < width; x++) {
+ var srcX = srcX0 + x;
+ var dstX = dstX0 + x;
+ if (srcX < 0 || srcX >= kWidth ||
+ dstX < 0 || dstX >= kWidth)
+ {
+ continue;
+ }
+
+ for (var y = 0; y < height; y++) {
+ var srcY = srcY0 + y;
+ var dstY = dstY0 + y;
+ if (srcY < 0 || srcY >= kHeight ||
+ dstY < 0 || dstY >= kHeight)
+ {
+ continue;
+ }
+
+
+ var srcPos = pixelPos(srcX, srcY);
+ var dstPos = pixelPos(dstX, dstY);
+ dstRefData[dstPos] = srcData[srcPos];
+ }
+ }
+
+ // Compare
+ gl.bindFramebuffer(gl.FRAMEBUFFER, dstFB);
+ readInto(dstTestData);
+
+ for (var x = 0; x < kWidth; x++) {
+ for (var y = 0; y < kHeight; y++) {
+ var pos = pixelPos(x, y);
+ var refPixel = dstRefData[pos];
+ var testPixel = dstTestData[pos];
+
+ //console.log([x, y].join(",") + ":",
+ // testPixel.toString(16), refPixel.toString(16))
+ if (testPixel == refPixel)
+ continue;
+
+ testFailed("Mismatch at (" + [x, y].join(", ") + "): " +
+ " Should be 0x" + refPixel.toString(16) +
+ ", was 0x" + testPixel.toString(16));
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ var tests = [
+ [0,0, 0,0, 2,3],
+ [0,0, 5,8, 2,3],
+ [1,0, 0,0, 2,3],
+ [1,7, 0,0, 2,3],
+ ];
+
+ tests.every(x => testCmd(x));
+}
+
+runTest();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-incomplete-fbo.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-incomplete-fbo.html
new file mode 100644
index 0000000000..d08801f085
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-incomplete-fbo.html
@@ -0,0 +1,72 @@
+<!--
+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>Test that cube incomplete textures can not be used as FBO attachments</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="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example");
+
+var testIncompleteCubemapFaceInFBO = function() {
+ // Create a cube map texture that's not cube complete.
+ var tex2 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex2);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+
+ var cube_map_faces = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ // Fill in all but 1 cube map face
+ for (var i = 0; i < cube_map_faces.length - 1; ++i) {
+ gl.texImage2D(cube_map_faces[i], 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+
+ var fb2 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex2, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors after attaching cube map face.");
+ debug("Cubemap has 1 missing face, so framebuffer should not be complete.");
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+
+ debug("");
+
+ // Fill in missing cube map face
+ gl.texImage2D(cube_map_faces[5], 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ debug("Missing face is added, so framebuffer should become complete.");
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+}
+
+testIncompleteCubemapFaceInFBO();
+
+var successfullyParsed = true;
+finishTest();
+
+</script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-map-uploads-out-of-order.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-map-uploads-out-of-order.html
new file mode 100644
index 0000000000..88ea83e325
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-map-uploads-out-of-order.html
@@ -0,0 +1,90 @@
+<!--
+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 cube map out of order upload test.</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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="example" width="64" height="64">
+</canvas>
+<script>
+"use strict";
+description("Test out of order cube map uploads.");
+debug("Regression test for crbug.com/473739 / Apple Radar 20444072.");
+
+<!-- Thanks to Gregg Tavares for the original report and test case. -->
+
+var wtu = WebGLTestUtils;
+
+var canvas = document.getElementById("example");
+canvas.addEventListener('webglcontextlost', contextLost, false);
+
+var contextWasLost = false;
+
+function contextLost(e) {
+ e.preventDefault();
+ contextWasLost = true;
+ debug("***context lost -- should not happen***");
+}
+
+var dataWidth = 256;
+var dataHeight = 256;
+var gl = wtu.create3DContext(canvas);
+var tex = gl.createTexture();
+// start with 1x1 pixel cubemap
+gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+var color = new Uint8Array([128, 192, 255, 255]);
+for (var ii = 0; ii < 6; ++ii) {
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color);
+}
+gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+gl.generateMipmap(gl.TEXTURE_CUBE_MAP); // there's no need to call this but the code doesn't check the size.
+
+var textureData = new Uint8Array(dataWidth * dataHeight * 4);
+
+// The first texture has downloaded
+var first = 1;
+gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + first, 0, gl.RGBA, dataWidth, dataHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureData);
+
+// Now because the first face downloaded doesn't match the other 5 faces upload the same image to the other 5
+// 1x1 faces
+for (var ii = 0; ii < 6; ++ii) {
+ if (ii !== first) {
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, dataWidth, dataHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureData);
+ }
+}
+gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+
+// Now as each new face comes in add it
+for (var ii = 0; ii < 6; ++ii) {
+ if (ii !== first) {
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, dataWidth, dataHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureData);
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ }
+}
+
+gl.flush();
+
+setTimeout(function() {
+ shouldBe("contextWasLost", "false");
+ finishTest();
+}, 1000);
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/default-texture.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/default-texture.html
new file mode 100644
index 0000000000..0f8cd21cf6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/default-texture.html
@@ -0,0 +1,42 @@
+<!--
+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>Tests texture access with no texture bound</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="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example");
+var program = wtu.setupTexturedQuad(gl);
+
+gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+// When no texture is bound, it is considered an incomplete texture,
+// therefore, [0, 0, 0, 1] should be returned.
+// See OpenGL ES spec 2.0.25, section F.3.5.
+wtu.checkCanvas(gl, [0, 0, 0, 255]);
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/exif-orientation.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/exif-orientation.html
new file mode 100644
index 0000000000..3fd596d445
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/exif-orientation.html
@@ -0,0 +1,167 @@
+<!--
+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>Verifies EXIF orientation is respected when uploading images to WebGL textures</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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+</head>
+<body onload="run()">
+<canvas id="c" width="256" height="256"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description();
+let wtu = WebGLTestUtils;
+let tiu = TexImageUtils;
+let canvas = document.getElementById("c");
+let gl = wtu.create3DContext(canvas);
+let program = tiu.setupTexturedQuad(gl, gl.RGBA);
+const resourcePath = "../../../resources/";
+const tolerance = 5;
+
+// The locations are written assuming flipY = false. For flipY = true, y = 1.0-y.
+const expectedColors = {
+ top: { location: [ 0.5, 0.25 ], color: [ 255, 0, 0 ] },
+ left: { location: [ 0.4, 0.5 ], color: [ 0, 0, 255 ] },
+ right: { location: [ 0.6, 0.5 ], color: [ 255, 255, 0 ] },
+ bottom: { location: [ 0.5, 0.75 ], color: [ 0, 255, 0 ] },
+}
+
+function output(str)
+{
+ debug(str);
+ bufferedLogToConsole(str);
+}
+
+function checkPixels(flipY)
+{
+ for (let place in expectedColors) {
+ let color = expectedColors[place];
+ let loc = color.location;
+ let x = loc[0];
+ let y = (flipY ? 1.0 - loc[1] : loc[1]);
+ output(" Checking " + place);
+ wtu.checkCanvasRect(gl, Math.floor(canvas.width * x), Math.floor(canvas.height * y), 1, 1,
+ color.color, "shouldBe " + color.color + " +/-" + tolerance, tolerance);
+ }
+}
+
+async function testImageBitmapFromBlobWithFlipY(blob, flipY)
+{
+ let bitmap;
+ // As a concession to Firefox, which doesn't yet implement
+ // createImageBitmap with creation options, skip the tests
+ // involving flipY=true if ImageBitmap creation throws an
+ // exception, and use the single-argument constructor for the
+ // flipY=false case.
+ if (flipY) {
+ try {
+ bitmap = await createImageBitmap(blob, {imageOrientation: flipY});
+ } catch (e) {
+ output(" (createImageBitmap options not supported - skipping flipY=true case)");
+ return;
+ }
+ } else {
+ bitmap = await createImageBitmap(blob);
+ }
+
+ output(" Testing texImage2D, flipY = " + flipY);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ checkPixels(flipY);
+
+ output(" Testing texSubImage2D, flipY = " + flipY);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, bitmap.width, bitmap.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ checkPixels(flipY);
+}
+
+async function testImageBitmapFromBlob(filename)
+{
+ let response = await fetch(resourcePath + filename);
+ let blob = await response.blob();
+ output("----------------------------------------------------------------");
+ output("Testing " + filename + " via ImageBitmap from Blob");
+ await testImageBitmapFromBlobWithFlipY(blob, true);
+ await testImageBitmapFromBlobWithFlipY(blob, false);
+}
+
+async function testImageElementWithFlipY(image, flipY)
+{
+ output(" Testing texImage2D, flipY = " + flipY);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ checkPixels(flipY);
+
+ output(" Testing texSubImage2D, flipY = " + flipY);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ checkPixels(flipY);
+}
+
+async function testImageElement(filename)
+{
+ let image = new Image();
+ image.src = resourcePath + filename;
+ await image.decode();
+
+ output("----------------------------------------------------------------");
+ output("Testing " + filename + " via HTMLImageElement");
+
+ await testImageElementWithFlipY(image, true);
+ await testImageElementWithFlipY(image, false);
+}
+
+async function testSingleImage(filename)
+{
+ await testImageBitmapFromBlob(filename);
+ await testImageElement(filename);
+}
+
+async function run()
+{
+ let tex = gl.createTexture();
+ // Bind the texture to the default texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ // Set up texture parameters
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+ const filenames = [
+ "exif-orientation-test-1-normal.jpg",
+ "exif-orientation-test-2-mirror-horizontal.jpg",
+ "exif-orientation-test-3-rotate-180.jpg",
+ "exif-orientation-test-4-mirror-vertical.jpg",
+ "exif-orientation-test-5-mirror-horizontal-90-ccw.jpg",
+ "exif-orientation-test-6-90-ccw.jpg",
+ "exif-orientation-test-7-mirror-horizontal-90-cw.jpg",
+ "exif-orientation-test-8-90-cw.jpg",
+ ];
+
+ for (let fn of filenames) {
+ await testSingleImage(fn);
+ }
+
+ finishTest();
+}
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/format-filterable-renderable.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/format-filterable-renderable.html
new file mode 100644
index 0000000000..df7694b821
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/format-filterable-renderable.html
@@ -0,0 +1,378 @@
+<!--
+Copyright (c) 2021 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">
+<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>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+const wtu = WebGLTestUtils;
+description();
+
+const gl = wtu.create3DContext();
+gl.canvas.width = gl.canvas.height = 1;
+
+function makeTexImage(format, unpackFormat, unpackType, data) {
+ data = data || null;
+
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl[format], 2, 2, 0,
+ gl[unpackFormat], gl[unpackType], null);
+ return tex;
+}
+
+const DUMMY_COLOR = makeTexImage('RGBA', 'RGBA', 'UNSIGNED_BYTE');
+
+function makeProgram(gl, vsSrc, fsSrc) {
+ function makeShader(prog, type, src) {
+ const shader = gl.createShader(gl[type]);
+ gl.shaderSource(shader, src.trim());
+ gl.compileShader(shader);
+ gl.attachShader(prog, shader);
+ gl.deleteShader(shader);
+ };
+
+ const prog = gl.createProgram();
+ makeShader(prog, 'VERTEX_SHADER', vsSrc);
+ makeShader(prog, 'FRAGMENT_SHADER', fsSrc);
+ gl.linkProgram(prog);
+
+ if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
+ throw 'Program linking failed' + fsSrc;
+ }
+ return prog;
+}
+
+const TEX_FILTER_PROG_T = (version, samplerT) => makeProgram(gl, `\
+ ${version}
+ void main() {
+ gl_PointSize = 1.0;
+ gl_Position = vec4(0.5,0.5,0,1);
+ }`,`\
+ ${version}
+ precision mediump float;
+ uniform ${samplerT} u_tex0;
+ #if __VERSION__ == 300
+ out vec4 o_FragColor;
+ #else
+ #define o_FragColor gl_FragColor
+ #define texture texture2D
+ #endif
+ void main() {
+ o_FragColor = vec4(texture(u_tex0, vec2(0.8)));
+ }`);
+const TEX_FILTER_PROG_BY_TYPEISH = {
+ 'float': TEX_FILTER_PROG_T('', 'sampler2D'),
+};
+if (wtu.isWebGL2(gl)) {
+ TEX_FILTER_PROG_BY_TYPEISH['int'] =
+ TEX_FILTER_PROG_T('#version 300 es', 'highp isampler2D');
+ TEX_FILTER_PROG_BY_TYPEISH['uint'] =
+ TEX_FILTER_PROG_T('#version 300 es', 'highp usampler2D');
+}
+
+function runPixelProgram(gl, prog) {
+ gl.useProgram(prog);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ const bytes = new Uint8Array(4);
+ gl.readPixels(0,0,1,1,gl.RGBA, gl.UNSIGNED_BYTE, bytes);
+ return [].map.call(bytes, x => x/255.0);
+}
+
+// GLES 2.0.25 p63
+const FORMAT_INFO_WEBGL1 = {
+ RGBA8 : { filter: true, render: true , unpack: ['RGBA', 'UNSIGNED_BYTE'] },
+ RGB8 : { filter: true, render: undefined, unpack: ['RGB', 'UNSIGNED_BYTE'] },
+ RGBA4 : { filter: true, render: undefined, unpack: ['RGBA', 'UNSIGNED_SHORT_4_4_4_4'] },
+ RGB5_A1: { filter: true, render: undefined, unpack: ['RGBA', 'UNSIGNED_SHORT_5_5_5_1'] },
+ RGB565 : { filter: true, render: undefined, unpack: ['RGB', 'UNSIGNED_SHORT_5_6_5'] },
+ LA8 : { filter: true, render: false , unpack: ['LUMINANCE_ALPHA', 'UNSIGNED_BYTE'] },
+ L8 : { filter: true, render: false , unpack: ['LUMINANCE', 'UNSIGNED_BYTE'] },
+ A8 : { filter: true, render: false , unpack: ['ALPHA', 'UNSIGNED_BYTE'] },
+};
+
+// GLES 3.0.6 p130-132
+const FORMAT_INFO_WEBGL2 = {
+ R8 : { render: true , filter: true , unpack: ['RED', 'UNSIGNED_BYTE'] },
+ R8_SNORM : { render: false, filter: true , unpack: ['RED', 'BYTE'] },
+ RG8 : { render: true , filter: true , unpack: ['RG', 'UNSIGNED_BYTE'] },
+ RG8_SNORM : { render: false, filter: true , unpack: ['RG', 'BYTE'] },
+ RGB8 : { render: true , filter: true , unpack: ['RGB', 'UNSIGNED_BYTE'] },
+ RGB8_SNORM : { render: false, filter: true , unpack: ['RGB', 'BYTE'] },
+ RGB565 : { render: true , filter: true , unpack: ['RGB', 'UNSIGNED_SHORT_5_6_5'] },
+ RGBA4 : { render: true , filter: true , unpack: ['RGBA', 'UNSIGNED_SHORT_4_4_4_4'] },
+ RGB5_A1 : { render: true , filter: true , unpack: ['RGBA', 'UNSIGNED_SHORT_5_5_5_1'] },
+ RGBA8 : { render: true , filter: true , unpack: ['RGBA', 'UNSIGNED_BYTE'] },
+ RGBA8_SNORM : { render: false, filter: true , unpack: ['RGBA', 'BYTE'] },
+ RGB10_A2 : { render: true , filter: true , unpack: ['RGBA', 'UNSIGNED_INT_10_10_10_2'] },
+ RGB10_A2UI : { render: true , filter: false, unpack: ['RGBA', 'UNSIGNED_INT_10_10_10_2'] },
+ SRGB8 : { render: false, filter: true , unpack: ['RGB', 'UNSIGNED_BYTE'] },
+ SRGB8_ALPHA8 : { render: true , filter: true , unpack: ['RGBA', 'UNSIGNED_BYTE'] },
+ R16F : { render: false, filter: true , unpack: ['RED', 'FLOAT'] },
+ RG16F : { render: false, filter: true , unpack: ['RG', 'FLOAT'] },
+ RGB16F : { render: false, filter: true , unpack: ['RGB', 'FLOAT'] },
+ RGBA16F : { render: false, filter: true , unpack: ['RGBA', 'FLOAT'] },
+ R32F : { render: false, filter: false, unpack: ['RED', 'FLOAT'] },
+ RG32F : { render: false, filter: false, unpack: ['RG', 'FLOAT'] },
+ RGB32F : { render: false, filter: false, unpack: ['RGB', 'FLOAT'] },
+ RGBA32F : { render: false, filter: false, unpack: ['RGBA', 'FLOAT'] },
+ R11F_G11F_B10F: { render: false, filter: true , unpack: ['RGB', 'FLOAT'] },
+ RGB9_E5 : { render: false, filter: true , unpack: ['RGB', 'FLOAT'] },
+ R8I : { render: true , filter: false, unpack: ['RED', 'BYTE'] },
+ R8UI : { render: true , filter: false, unpack: ['RED', 'UNSIGNED_BYTE'] },
+ R16I : { render: true , filter: false, unpack: ['RED', 'BYTE'] },
+ R16UI : { render: true , filter: false, unpack: ['RED', 'UNSIGNED_BYTE'] },
+ R32I : { render: true , filter: false, unpack: ['RED', 'BYTE'] },
+ R32UI : { render: true , filter: false, unpack: ['RED', 'UNSIGNED_BYTE'] },
+ RG8I : { render: true , filter: false, unpack: ['RG', 'BYTE'] },
+ RG8UI : { render: true , filter: false, unpack: ['RG', 'UNSIGNED_BYTE'] },
+ RG16I : { render: true , filter: false, unpack: ['RG', 'SHORT'] },
+ RG16UI : { render: true , filter: false, unpack: ['RG', 'UNSIGNED_SHORT'] },
+ RG32I : { render: true , filter: false, unpack: ['RG', 'INT'] },
+ RG32UI : { render: true , filter: false, unpack: ['RG', 'UNSIGNED_INT'] },
+ RGB8I : { render: false, filter: false, unpack: ['RGB', 'BYTE'] },
+ RGB8UI : { render: false, filter: false, unpack: ['RGB', 'UNSIGNED_BYTE'] },
+ RGB16I : { render: false, filter: false, unpack: ['RGB', 'SHORT'] },
+ RGB16UI : { render: false, filter: false, unpack: ['RGB', 'UNSIGNED_SHORT'] },
+ RGB32I : { render: false, filter: false, unpack: ['RGB', 'INT'] },
+ RGB32UI : { render: false, filter: false, unpack: ['RGB', 'UNSIGNED_INT'] },
+ RGBA8I : { render: true , filter: false, unpack: ['RGBA', 'BYTE'] },
+ RGBA8UI : { render: true , filter: false, unpack: ['RGBA', 'UNSIGNED_BYTE'] },
+ RGBA16I : { render: true , filter: false, unpack: ['RGBA', 'SHORT'] },
+ RGBA16UI : { render: true , filter: false, unpack: ['RGBA', 'UNSIGNED_SHORT'] },
+ RGBA32I : { render: true , filter: false, unpack: ['RGBA', 'INT'] },
+ RGBA32UI : { render: true , filter: false, unpack: ['RGBA', 'UNSIGNED_INT'] },
+
+ DEPTH_COMPONENT16: { render: 'DEPTH_ATTACHMENT', filter: false },
+ DEPTH_COMPONENT24: { render: 'DEPTH_ATTACHMENT', filter: false },
+ DEPTH_COMPONENT32F: { render: 'DEPTH_ATTACHMENT', filter: false },
+ DEPTH24_STENCIL8: { render: 'DEPTH_STENCIL_ATTACHMENT', filter: false },
+ DEPTH32F_STENCIL8: { render: 'DEPTH_STENCIL_ATTACHMENT', filter: false },
+};
+
+const ONE_BY_TYPE = {
+ 'BYTE': (1<<7)-1,
+ 'UNSIGNED_BYTE': (1<<8)-1,
+ 'SHORT': (1<<15)-1,
+ 'UNSIGNED_SHORT': (1<<16)-1,
+ 'INT': (1<<31)-1,
+ 'UNSIGNED_INT': Math.pow(2,32)-1,
+ 'FLOAT': 1,
+};
+
+const ABV_BY_TYPE = {
+ 'BYTE': Int8Array,
+ 'UNSIGNED_BYTE': Uint8Array,
+ 'SHORT': Int16Array,
+ 'UNSIGNED_SHORT': Uint16Array,
+ 'INT': Int32Array,
+ 'UNSIGNED_INT': Uint32Array,
+ 'FLOAT': Float32Array,
+};
+
+function pushBitsUnorm(prev, bitCount, floatVal) {
+ let ret = prev << bitCount;
+ ret |= floatVal * ((1 << bitCount)-1);
+ return ret;
+}
+
+const CHANNELS_BY_FORMAT = {
+ 'RED': 1,
+ 'LUMINANCE': 1,
+ 'ALPHA': 1,
+ 'LUMINANCE_ALPHA': 2,
+ 'RG': 2,
+ 'RGB': 3,
+ 'RGBA': 4,
+};
+
+function throwv(val) {
+ throw val;
+}
+
+function pixelDataForUnpack(format, type, floatVal) {
+ switch (type) {
+ case 'UNSIGNED_SHORT_5_6_5': {
+ let bits = 0;
+ bits = pushBitsUnorm(bits, 5, floatVal);
+ bits = pushBitsUnorm(bits, 6, floatVal);
+ bits = pushBitsUnorm(bits, 5, floatVal);
+ return new Uint16Array([bits]);
+ }
+ case 'UNSIGNED_SHORT_4_4_4_4': {
+ let bits = 0;
+ bits = pushBitsUnorm(bits, 4, floatVal);
+ bits = pushBitsUnorm(bits, 4, floatVal);
+ bits = pushBitsUnorm(bits, 4, floatVal);
+ bits = pushBitsUnorm(bits, 4, floatVal);
+ return new Uint16Array([bits]);
+ }
+ case 'UNSIGNED_SHORT_5_5_5_1': {
+ let bits = 0;
+ bits = pushBitsUnorm(bits, 5, floatVal);
+ bits = pushBitsUnorm(bits, 5, floatVal);
+ bits = pushBitsUnorm(bits, 5, floatVal);
+ bits = pushBitsUnorm(bits, 1, floatVal); // Ok, silly for 1 bit here.
+ return new Uint16Array([bits]);
+ }
+ case 'UNSIGNED_INT_10_10_10_2': {
+ let bits = 0;
+ bits = pushBitsUnorm(bits, 10, floatVal);
+ bits = pushBitsUnorm(bits, 10, floatVal);
+ bits = pushBitsUnorm(bits, 10, floatVal);
+ bits = pushBitsUnorm(bits, 2, floatVal); // 2 bits isn't much more useful
+ return new Uint32Array([bits]);
+ }
+ }
+
+ const channels = CHANNELS_BY_FORMAT[format] || throwv(format);
+ const one = ONE_BY_TYPE[type] || throwv('240', type);
+ const abvType = ABV_BY_TYPE[type] || throwv('241', type);
+
+ const val = floatVal * one;
+ const arr = [];
+ for (const i of range(channels)) {
+ arr.push(val);
+ }
+ return new abvType(arr);
+}
+
+function expect(name, was, expected) {
+ let text = `${name} was ${was}`;
+ const cond = was == expected;
+ if (!cond) {
+ text += `, but expected ${expected}`;
+ }
+ expectTrue(cond, text);
+}
+
+function toTypeish(sizedFormat) {
+ if (sizedFormat.endsWith('UI')) {
+ return 'int';
+ } else if (sizedFormat.endsWith('I')) {
+ return 'uint';
+ }
+ return 'float';
+}
+
+call(async () => {
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ let formatList = FORMAT_INFO_WEBGL1;
+ if (wtu.isWebGL2(gl)) {
+ formatList = FORMAT_INFO_WEBGL2;
+ }
+ for (const [sizedFormat, info] of Object.entries(formatList)) {
+ await wtu.dispatchPromise();
+ debug(``);
+ debug(`${sizedFormat}: ${JSON.stringify(info)}`);
+
+ const typeish = toTypeish(sizedFormat);
+
+ // |---|---|
+ // | 0 | 1 |
+ // |---|---|
+ // 0| 0 | 0 |
+ // |---|---|
+ // 0
+ const tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ if (gl.texStorage2D) {
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl[sizedFormat], 2, 2);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl[info.unpack[0]],
+ 2, 2, 0, gl[info.unpack[0]], gl[info.unpack[1]], null);
+ }
+
+ if (info.unpack) {
+ const one = pixelDataForUnpack(...info.unpack, 1.0);
+ const data = new one.constructor(one.length*4);
+ data.set(one, one.length*3);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0,
+ 2,2, gl[info.unpack[0]], gl[info.unpack[1]], data);
+ } else {
+ info.render || throwv(`${sizedFormat} without unpack or render`);
+ }
+
+ // -
+ // color-renderable test
+
+ {
+ const fb = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+ let attach = info.render || true;
+ const isColor = (attach === true);
+ if (isColor) {
+ attach = 'COLOR_ATTACHMENT0';
+ } else {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, DUMMY_COLOR, 0);
+ }
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[attach],
+ gl.TEXTURE_2D, tex, 0);
+ const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ const wasRenderable = (status == gl.FRAMEBUFFER_COMPLETE);
+ if (info.render === undefined) {
+ debug(`Non-normative: color-renderable was ${wasRenderable}`);
+ } else {
+ expect('color-renderable', wasRenderable, !!info.render);
+ }
+ if (wasRenderable) {
+ gl.clearColor(0,0,0,0);
+ gl.clearDepth(0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.enable(gl.SCISSOR_TEST);
+ gl.scissor(1,1,1,1);
+ gl.clearColor(1,1,1,1);
+ gl.clearDepth(1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.disable(gl.SCISSOR_TEST);
+ }
+ gl.deleteFramebuffer(fb);
+ if (!wasRenderable && !info.unpack) {
+ testFailed('No unpack provided and !wasRenderable, skipping filtering subtest...');
+ continue;
+ }
+ }
+
+ // -
+ // filterable test
+
+ const prog = TEX_FILTER_PROG_BY_TYPEISH[typeish];
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.clearColor(0,0,0,0);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.viewport(0,0,1,1);
+ const v = runPixelProgram(gl, prog);
+ if (sizedFormat != 'A8') {
+ v[3] = 0; // Incomplete no-alpha formats put 1 in alpha.
+ }
+ const wasFilterable = v.some(x => !!x);
+ expect('filterable', wasFilterable, info.filter);
+ }
+
+ finishTest();
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-get-tex-parameter.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-get-tex-parameter.html
new file mode 100644
index 0000000000..fbfc2c510a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-get-tex-parameter.html
@@ -0,0 +1,27 @@
+<!--
+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 getTexParameter test</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="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 1;
+</script>
+<script src="../../../js/tests/gl-get-tex-parameter.js"></script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-pixelstorei.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-pixelstorei.html
new file mode 100644
index 0000000000..161a45271b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-pixelstorei.html
@@ -0,0 +1,96 @@
+<!--
+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 pixelStorei Test</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="example" width="50" height="50"></canvas>
+<canvas id="2d00" width="50" height="50"></canvas>
+<canvas id="2d01" width="50" height="50"></canvas>
+<canvas id="2d02" width="50" height="50"></canvas>
+<canvas id="2d03" width="50" height="50"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+void main() {
+ gl_Position = vPosition;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+void main() {
+ gl_FragColor = vec4(1.0,0.0,0.0,1.0);
+}
+</script>
+
+<script>
+"use strict";
+function init() {
+ description("This test checks that drawImage and readPixels are not effected by gl.Pixelstorei(gl.PACK_ALIGNMENT) and visa versa");
+
+ debug("There should be 5 red triangles on 5 black squares above");
+ debug("");
+
+ var wtu = WebGLTestUtils;
+ var canvas3d = document.getElementById("example");
+ var gl = wtu.create3DContext("example");
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ function checkData(ctx, name) {
+ // Test several locations
+ // First line should be all black
+ wtu.checkCanvasRect(ctx, 0, 0, 50, 1, [0, 0, 0, 0]);
+
+ // Line 25 should be red for at least 6 red pixels starting 22 pixels in
+ wtu.checkCanvasRect(ctx, 22, 25, 6, 1, [255, 0, 0, 255]);
+
+ // Last line should be all black
+ wtu.checkCanvasRect(ctx, 0, 49, 50, 1, [0, 0, 0, 0]);
+ }
+
+ var ctx2d;
+
+ function checkColors() {
+ checkData(gl, "3d context");
+ checkData(ctx2d, "2d context");
+ }
+
+ var table = [1, 2, 4, 8];
+ for (var ii = 0; ii < table.length; ++ii) {
+ gl.pixelStorei(gl.PACK_ALIGNMENT, table[ii]);
+ ctx2d = document.getElementById("2d0" + ii).getContext("2d");
+ ctx2d.globalCompositeOperation = 'copy';
+ ctx2d.drawImage(canvas3d, 0, 0);
+ checkColors();
+ assertMsg(gl.getParameter(gl.PACK_ALIGNMENT) == table[ii],
+ "PACK_ALIGNMENT is " + table[ii]);
+ }
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html
new file mode 100644
index 0000000000..897377534c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html
@@ -0,0 +1,406 @@
+<!--
+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 texImage2D conformance test.</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="example" width="256" height="16" style="width: 256px; height: 48px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+enableJSTestPreVerboseLogging();
+description("Test texImage2D conversions.");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+gl.disable(gl.DITHER);
+var program = wtu.setupTexturedQuad(gl);
+var successfullyParsed;
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var imgURLs = [
+ '../../../resources/1-channel.jpg',
+ '../../../resources/gray-ramp-256-with-128-alpha.png',
+ '../../../resources/gray-ramp-256.png',
+ '../../../resources/gray-ramp-default-gamma.png',
+ '../../../resources/gray-ramp-gamma0.1.png',
+ '../../../resources/gray-ramp-gamma1.0.png',
+ '../../../resources/gray-ramp-gamma2.0.png',
+ '../../../resources/gray-ramp-gamma4.0.png',
+ '../../../resources/gray-ramp-gamma9.0.png',
+ '../../../resources/gray-ramp.png',
+ '../../../resources/zero-alpha.png',
+ '../../../resources/3x3.png',
+ '../../../resources/blue-1x1.jpg',
+ '../../../resources/red-indexed.png',
+ '../../../resources/transparent-on-left-indexed.png',
+ '../../../resources/green-2x2-16bit.png',
+ '../../../resources/small-square-with-colorspin-profile.jpg',
+ '../../../resources/small-square-with-colorspin-profile.png',
+ '../../../resources/small-square-with-cie-rgb-profile.png',
+ '../../../resources/small-square-with-colormatch-profile.png',
+ '../../../resources/small-square-with-e-srgb-profile.png',
+ '../../../resources/small-square-with-smpte-c-profile.png',
+ '../../../resources/small-square-with-srgb-iec61966-2.1-profile.png'];
+
+
+wtu.loadImagesAsync(imgURLs, runTests);
+
+function runTests(imgs) {
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ gl.disable(gl.BLEND);
+ gl.disable(gl.DEPTH_TEST);
+
+ var width = gl.canvas.width;
+ var height = gl.canvas.height;
+
+ function checkPixel(x, y, color) {
+ wtu.checkCanvasRect(gl, x, y, 1, 1, color);
+ }
+
+ function checkPixelRange(x, y, color, allowedRange) {
+ var msg = "pixel " + x + ", " + y + " should be within " +
+ allowedRange + " units of " +
+ color[0] + ", " +
+ color[1] + ", " +
+ color[2] + ", " +
+ color[3];
+ wtu.checkCanvasRect(gl, x, y, 1, 1, color, msg, allowedRange);
+ }
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ var buf = new Uint8Array(width * height * 4);
+
+ debug("");
+ debug("check pixels are NOT pre-multiplied");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/zero-alpha.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+
+ var left = 0;
+ var middle = Math.floor(width / 2);
+ var right = width - 1;
+ var bottom = 0;
+ var center = Math.floor(height / 2);
+ var top = height - 1;
+ checkPixel(left, top, [ 0, 0, 0, 255]);
+ checkPixel(middle, top, [255, 0, 255, 255]);
+ checkPixel(right, top, [ 0, 0, 255, 255]);
+ checkPixel(left, center, [128, 128, 128, 255]);
+ checkPixel(middle, center, [255, 255, 255, 255]);
+ checkPixel(right, center, [ 0, 255, 255, 255]);
+ checkPixel(left, bottom, [255, 0, 0, 255]);
+ checkPixel(middle, bottom, [255, 255, 0, 255]);
+ checkPixel(right, bottom, [ 0, 255, 0, 255]);
+
+ debug("");
+ debug("check quantization");
+ var quantInfo = [
+ {format: gl.RGBA, type: gl.UNSIGNED_BYTE, counts: [256, 256, 256, 256]},
+ {format: gl.RGBA, type: gl.UNSIGNED_SHORT_4_4_4_4, counts: [ 16, 16, 16, 16]},
+ {format: gl.RGB, type: gl.UNSIGNED_SHORT_5_6_5, counts: [ 32, 64, 32, 1]},
+ {format: gl.RGBA, type: gl.UNSIGNED_SHORT_5_5_5_1, counts: [ 32, 32, 32, 2]}];
+ for (var qq = 0; qq < quantInfo.length; ++qq) {
+ var info = quantInfo[qq];
+ gl.texImage2D(
+ gl.TEXTURE_2D, 0, info.format, info.format, info.type,
+ imgs['../../../resources/gray-ramp-256.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+ wtu.clearAndDrawUnitQuad(gl);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var counts = [{ }, { }, { }, { }];
+ var numUniqueValues = [0, 0, 0, 0];
+ // Count the number of unique values in each channel.
+ for (var ii = 0; ii < width * height * 4; ii += 4) {
+ for (var jj = 0; jj < 4; ++jj) {
+ var v = buf[ii + jj];
+ if (!counts[jj][v]) {
+ counts[jj][v] = 1;
+ ++numUniqueValues[jj];
+ } else {
+ ++counts[jj][v];
+ }
+ }
+ }
+ for (var ii = 0; ii < 4; ++ii) {
+ assertMsg(numUniqueValues[ii] == info.counts[ii],
+ "There should be " + info.counts[ii] +
+ " unique values in channel " + ii + ". Found " +
+ numUniqueValues[ii]);
+ }
+ }
+
+ debug("");
+ debug("Check that gamma settings don't effect 8bit pngs");
+ wtu.failIfGLError(gl, 'gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/gray-ramp-default-gamma.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+ wtu.clearAndDrawUnitQuad(gl);
+ var ref = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, ref);
+
+ var gammaImages = [
+ '../../../resources/gray-ramp-gamma0.1.png',
+ '../../../resources/gray-ramp-gamma1.0.png',
+ '../../../resources/gray-ramp-gamma2.0.png',
+ '../../../resources/gray-ramp-gamma4.0.png',
+ '../../../resources/gray-ramp-gamma9.0.png'];
+ for (var ii = 0; ii < gammaImages.length; ++ii) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs[gammaImages[ii]]);
+ wtu.clearAndDrawUnitQuad(gl);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var same = true;
+ for (var jj = 0; jj < width * height * 4; ++jj) {
+ if (buf[jj] != ref[jj]) {
+ same = false;
+ break;
+ }
+ }
+ assertMsg(same, "pixels should be same regardless of gamma settings.");
+ }
+
+ debug("");
+ debug("check pixels are UN pre-multiplied");
+ for (var ii = 0; ii < 2; ++ii) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ if (ii == 0) {
+ var canvas2d = document.createElement("canvas");
+ canvas2d.width = 256;
+ canvas2d.height = 1;
+ var ctx = canvas2d.getContext("2d");
+ ctx.drawImage(imgs['../../../resources/gray-ramp-256-with-128-alpha.png'], 0, 0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, canvas2d);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/gray-ramp-256-with-128-alpha.png']);
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+ wtu.clearAndDrawUnitQuad(gl);
+ var buf = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var lt128Count = [0, 0, 0];
+ var ge128Count = [0, 0, 0];
+ for (var jj = 0; jj < width; ++jj) {
+ var off = jj * 4;
+ for (var cc = 0; cc < 3; ++cc) {
+ if (buf[off + cc] < 128) {
+ ++lt128Count[cc];
+ } else {
+ ++ge128Count[cc];
+ }
+ }
+ }
+ // Not sure the exact count here because gamma does effect drawing into the
+ // canvas but it should be close to 50% so I'll pass 45%
+ for (var jj = 0; jj < 3; ++jj) {
+ assertMsg(ge128Count[jj] > 256 * 0.45,
+ "Half the pixels in channel " + jj +
+ " should be >= 128,128,128. found " +
+ ((ge128Count[jj] / 256) * 100).toFixed() + "%");
+ assertMsg(lt128Count[jj] > 256 * 0.45,
+ "Half the pixels in channel " + jj +
+ " should be < 128,128,128. found " +
+ ((lt128Count[jj] / 256) * 100).toFixed() + "%");
+ }
+ }
+
+ debug("");
+ debug("check canvas pixels are UN pre-multiplied");
+ var canvas2d = document.createElement("canvas");
+ canvas2d.width = 1;
+ canvas2d.height = 1;
+ var ctx = canvas2d.getContext("2d");
+ ctx.fillStyle ="rgba(255,255,255,0.5)";
+ ctx.fillRect(0, 0, 256, 1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+ checkPixelRange(0, 0, [255, 255, 255, 127], 4);
+
+ debug("");
+ debug("check canvas pixels are pre-multiplied");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+ checkPixelRange(0, 0, [127, 127, 127, 127], 4);
+
+
+ debug("");
+ debug("check pixels are pre-multiplied");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+ // TODO(gman): use different texture that won't pass on failure
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/zero-alpha.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+
+ var same = true;
+ for (var jj = 0; jj < width * height * 4; ++jj) {
+ if (buf[jj] != 0) {
+ same = false;
+ break;
+ }
+ }
+ assertMsg(same, "pixels should all be 0.");
+
+ debug("");
+ debug("check pixels are flipped");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/3x3.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+
+ checkPixel(left, top, [255, 0, 0, 255]);
+ checkPixel(middle, top, [255, 255, 0, 255]);
+ checkPixel(right, top, [255, 0, 0, 255]);
+ checkPixel(left, center, [255, 0, 255, 255]);
+ checkPixel(middle, center, [255, 0, 0, 255]);
+ checkPixel(right, center, [ 0, 255, 0, 255]);
+ checkPixel(left, bottom, [ 0, 0, 0, 255]);
+ checkPixel(middle, bottom, [ 0, 0, 255, 255]);
+ checkPixel(right, bottom, [255, 0, 0, 255]);
+
+ debug("");
+ debug("check uploading of images with no alpha channel works");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/blue-1x1.jpg']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ checkPixelRange(middle, center, [ 0, 0, 255, 255], 10);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
+
+ debug("");
+ debug("check uploading of 16-bit images");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/green-2x2-16bit.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ checkPixelRange(middle, center, [ 15, 121, 0, 255], 10);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
+
+ debug("");
+ debug("check uploading of images with ICC profiles");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ wtu.failIfGLError(gl, 'gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);');
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/small-square-with-colorspin-profile.jpg']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ // The image is red. However, if we ignore the color profile, it is blue.
+ checkPixelRange(middle, center, [ 0, 0, 255, 255], 10);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/small-square-with-colorspin-profile.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ // The image is red. However, if we ignore the color profile, it is blue.
+ checkPixelRange(middle, center, [ 0, 0, 255, 255], 10);
+
+ var iccPNGs = [
+ '../../../resources/small-square-with-cie-rgb-profile.png',
+ '../../../resources/small-square-with-colormatch-profile.png',
+ '../../../resources/small-square-with-e-srgb-profile.png',
+ '../../../resources/small-square-with-smpte-c-profile.png',
+ '../../../resources/small-square-with-srgb-iec61966-2.1-profile.png'];
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ for (var ii = 0; ii < iccPNGs.length; ++ii) {
+ var buf2 = new Uint8Array(width * height * 4);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs[iccPNGs[ii]]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf2);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
+ var same = true;
+ for (var jj = 0; jj < buf.length; ++jj) {
+ if (buf[jj] != buf2[jj]) {
+ same = false;
+ break;
+ }
+ }
+ assertMsg(same, "uploading PNGs with same data but various ICC profiles should generate the same results");
+ }
+
+ debug("");
+ debug("check uploading of indexed PNG images");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/red-indexed.png']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ // The image should be red.
+ checkPixelRange(middle, center, [ 255, 0, 0, 255 ], 10);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/transparent-on-left-indexed.png']);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvasRect(gl, 0, 0, 128, 16, [255, 0, 255, 0], "should be transparent purple");
+ wtu.checkCanvasRect(gl, 128, 0,128, 16, [255, 255, 0, 255], "should be yellow");
+
+ debug("");
+ debug("check uploading of 1-channel JPG images");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['../../../resources/1-channel.jpg']);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ // The image should be gray.
+ checkPixelRange(middle, center, [ 128, 128, 128, 255 ], 28);
+
+ debug("")
+ debug("check calling texImage2D with NULL clears the texture");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB,
+ imgs['../../../resources/red-indexed.png'].width,
+ imgs['../../../resources/red-indexed.png'].height,
+ 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+ wtu.clearAndDrawUnitQuad(gl);
+ // The image should be white.
+ checkPixelRange(middle, center, [ 0, 0, 0, 255 ], 10);
+
+ debug("");
+ debug("check zero size cases");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, 2, 0, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, new Uint8Array());
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from zero sized textures");
+
+ debug("");
+ successfullyParsed = true;
+ shouldBeTrue("successfullyParsed");
+ debug('<br /><span class="pass">TEST COMPLETE</span>');
+ notifyFinishedToHarness();
+}
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/mipmap-fbo.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/mipmap-fbo.html
new file mode 100644
index 0000000000..1fe851d738
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/mipmap-fbo.html
@@ -0,0 +1,109 @@
+<!--
+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>Test if mipmap incomplete textures can be used as FBO attachments, and mipmap generation on a texture filled by an FBO works correctly</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="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+var wtu = WebGLTestUtils;
+description();
+
+var gl = wtu.create3DContext("example");
+
+function testMipmapGeneration() {
+ // setup render target texture //
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ // setup framebuffer //
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ // fill the framebuffer //
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.viewport(0, 0, 32, 32);
+ gl.clearColor(1, 0, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ // generate mipmap //
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.generateMipmap(gl.TEXTURE_2D);
+
+ var program = wtu.setupTexturedQuad(gl);
+ gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ // readback //
+ wtu.checkCanvas(gl, [255, 0, 255, 255]);
+}
+
+var testCubemapFaceWithIncompleteMipmapInFBO = function() {
+ // Create a cube map texture that's not mipmap complete.
+ var tex2 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex2);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+
+ var cube_map_faces = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ for (var i = 0; i < cube_map_faces.length; ++i) {
+ gl.texImage2D(cube_map_faces[i], 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+
+ var fb2 = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex2, 0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors after attaching cube map face.");
+ shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+
+ var colorProgram = wtu.setupColorQuad(gl);
+ var colorLocation = gl.getUniformLocation(colorProgram, 'u_color');
+ gl.uniform4f(colorLocation, 0.0, 1.0, 0.0, 1.0);
+ gl.viewport(0, 0, 32, 32);
+ wtu.drawUnitQuad(gl);
+ // Read what's in the framebuffer - note that we need to use checkCanvasRect since the
+ // FB dimensions are different from canvas dimensions.
+ wtu.checkCanvasRect(gl, 0, 0, 32, 32, [0, 255, 0, 255],
+ "Framebuffer with a non-mipmap complete cube map attachment should be green");
+}
+
+testMipmapGeneration();
+debug("");
+testCubemapFaceWithIncompleteMipmapInFBO();
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance-offscreencanvas.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance-offscreencanvas.html
new file mode 100644
index 0000000000..208696e98a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance-offscreencanvas.html
@@ -0,0 +1,125 @@
+<!--
+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 Origin Restrictions Conformance Tests for OffscreenCanvas</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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas"></canvas>
+<img id="img" style="display:none;">
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+
+// Checks if function throws an exception.
+function causedException(func) {
+ var hadException = false;
+ try {
+ func();
+ } catch(e) {
+ hadException = true;
+ }
+ return hadException;
+}
+
+var defaultImgUrl = "https://get.webgl.org/conformance-resources/opengl_logo.jpg";
+var localImgUrl = "../../../resources/opengl_logo.jpg";
+
+var imgDomain;
+var pageDomain;
+
+function imageLoaded(img) {
+ description("This test ensures WebGL implementations for OffscreenCanvas follow proper same-origin restrictions.");
+
+ if (!window.OffscreenCanvas) {
+ testPassed("No OffscreenCanvas support");
+ finishTest();
+ return;
+ }
+
+ assertMsg(img.width > 0 && img.height > 0, "img was loaded");
+ imgDomain = wtu.getBaseDomain(wtu.getHost(img.src));
+ pageDomain = wtu.getBaseDomain(window.location.host);
+ assertMsg(imgDomain != pageDomain,
+ "img domain (" + imgDomain + ") and page domain (" + pageDomain + ") are not the same.");
+
+ function makeTexImage2D(gl, src) {
+ return function() {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeTexSubImage2D(gl, src) {
+ return function() {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeReadPixels(gl) {
+ return function() {
+ var buf = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ };
+ }
+
+ var offscreencanvas = new OffscreenCanvas(10, 10);
+ var gl = wtu.create3DContext(offscreencanvas);
+
+ debug("");
+ debug("check that an attempt to upload an image from another origin throws an exception.");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ assertMsg(causedException(makeTexImage2D(gl, img)),
+ "texImage2D with cross-origin image should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, img)),
+ "texSubImage2D with cross-origin image should throw exception.");
+
+ debug("check that readPixels continues to work against this offscreencanvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+
+ debug("check that an attempt to upload a tainted canvas throws an exception.");
+ var canvas = document.getElementById("canvas");
+ var ctx2d = canvas.getContext("2d");
+ ctx2d.drawImage(img, 0, 0);
+ assertMsg(causedException(makeTexImage2D(gl, canvas)),
+ "texImage2D with NON origin clean canvas should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, canvas)),
+ "texSubImage2D with NON origin clean canvas should throw exception.");
+
+ debug("check that readPixels continues to work against this offscreencanvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+
+ // TODO: Should check video.
+ // TODO: Should check CORS support.
+
+ finishTest();
+}
+
+(async function() {
+ const img = document.getElementById('img');
+ try {
+ await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
+ } catch (e) {
+ testFailed(`Image setup failed (${e}).`);
+ finishTest();
+ return;
+ }
+ imageLoaded(img);
+})();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance.html
new file mode 100644
index 0000000000..fb7f572173
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance.html
@@ -0,0 +1,137 @@
+<!--
+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 Origin Restrictions Conformance 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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas1"></canvas>
+<canvas id="canvas2"></canvas>
+<img id="img" style="display:none;">
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+
+// Checks if function throws an exception.
+function causedException(func) {
+ var hadException = false;
+ try {
+ func();
+ } catch(e) {
+ hadException = true;
+ }
+ return hadException;
+}
+
+var defaultImgUrl = "https://get.webgl.org/conformance-resources/opengl_logo.jpg";
+var localImgUrl = "../../../resources/opengl_logo.jpg";
+
+var imgDomain;
+var pageDomain;
+var successfullyParsed;
+
+function imageLoaded(img) {
+ description("This test ensures WebGL implementations follow proper same-origin restrictions.");
+
+ assertMsg(img.width > 0 && img.height > 0, "img was loaded");
+ imgDomain = wtu.getBaseDomain(wtu.getHost(img.src));
+ pageDomain = wtu.getBaseDomain(window.location.host);
+ assertMsg(imgDomain != pageDomain,
+ "img domain (" + imgDomain + ") and page domain (" + pageDomain + ") are not the same.");
+
+ function makeTexImage2D(gl, src) {
+ return function() {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeTexSubImage2D(gl, src) {
+ return function() {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeReadPixels(gl) {
+ return function() {
+ var buf = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ };
+ }
+
+ function makeToDataURL(canvas) {
+ return function() {
+ var data = canvas.toDataURL();
+ }
+ }
+
+ var canvas1 = document.getElementById("canvas1");
+ var gl = wtu.create3DContext(canvas1);
+
+ debug("");
+ debug("check that an attempt to upload an image from another origin throws an exception.");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ assertMsg(causedException(makeTexImage2D(gl, img)),
+ "texImage2D with cross-origin image should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, img)),
+ "texSubImage2D with cross-origin image should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+
+ debug("check that an attempt to upload a tainted canvas throws an exception.");
+ var canvas2 = document.getElementById("canvas2");
+ var ctx2d = canvas2.getContext("2d");
+ ctx2d.drawImage(img, 0, 0);
+ assertMsg(causedException(makeToDataURL(canvas2)),
+ "should throw exception by toDataURL for NON origin clean canvas.");
+ assertMsg(causedException(makeTexImage2D(gl, canvas2)),
+ "texImage2D with NON origin clean canvas should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, canvas2)),
+ "texSubImage2D with NON origin clean canvas should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+
+ // TODO: Should check video.
+ // TODO: Should check CORS support.
+
+ debug("");
+ successfullyParsed = true;
+ shouldBeTrue("successfullyParsed");
+ debug('<br /><span class="pass">TEST COMPLETE</span>');
+ notifyFinishedToHarness();
+}
+
+(async function() {
+ const img = document.getElementById('img');
+ try {
+ await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
+ } catch (e) {
+ testFailed(`Image setup failed (${e}).`);
+ finishTest();
+ return;
+ }
+ imageLoaded(img);
+})();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/png-image-types.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/png-image-types.html
new file mode 100644
index 0000000000..4eb98b1405
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/png-image-types.html
@@ -0,0 +1,164 @@
+<!--
+Copyright (c) 2021 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">
+ <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>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script>
+"use strict";
+description("This test verifies correct channel mapping of different PNG image types.");
+
+const testData = {
+ "Grayscale": {
+ src: [
+ // [0x40]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NwAAAAQgBBg7nsrQAAAABJRU5ErkJggg==",
+ // [0x4040]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAAAAABq7kcWAAAAC0lEQVQI12NwcAAAAMMAgUenLEIAAAAASUVORK5CYII="
+ ],
+ expectations: [
+ { color: [0x00, 0x00, 0x00, 0xFF], format: "ALPHA" },
+ { color: [0x40, 0x40, 0x40, 0xFF], format: "RGB" },
+ { color: [0x40, 0x40, 0x40, 0xFF], format: "RGBA" },
+ { color: [0x40, 0x40, 0x40, 0xFF], format: "LUMINANCE" },
+ { color: [0x40, 0x40, 0x40, 0xFF], format: "LUMINANCE_ALPHA" },
+ { color: [0x40, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
+ { color: [0x40, 0x40, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
+ ]
+ },
+ "Grayscale Alpha": {
+ src: [
+ // [0x40, 0x80]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQI12NwaAAAAQMAwUxZTl4AAAAASUVORK5CYII=",
+ // [0x4040, 0x8080]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAQAAADljNBBAAAADUlEQVQI12NwcGhoAAADRQGBoxssPgAAAABJRU5ErkJggg=="
+ ],
+ expectations: [
+ { color: [0x00, 0x00, 0x00, 0x80], format: "ALPHA" },
+ { color: [0x40, 0x40, 0x40, 0xFF], format: "RGB" },
+ { color: [0x40, 0x40, 0x40, 0x80], format: "RGBA" },
+ { color: [0x40, 0x40, 0x40, 0xFF], format: "LUMINANCE" },
+ { color: [0x40, 0x40, 0x40, 0x80], format: "LUMINANCE_ALPHA" },
+ { color: [0x40, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
+ { color: [0x40, 0x40, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
+ ]
+ },
+ "Color": {
+ src: [
+ // [0xBF, 0x7F, 0xFF]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12PYX/8fAAQ+Aj5BqwprAAAAAElFTkSuQmCC",
+ // [0xBFBF, 0x7F7F, 0xFFFF]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAIAAADA54+dAAAAD0lEQVQI12PYv7++/v9/AA6yBHvtbgBNAAAAAElFTkSuQmCC"
+ ],
+ expectations: [
+ { color: [0x00, 0x00, 0x00, 0xFF], format: "ALPHA" },
+ { color: [0xBF, 0x7F, 0xFF, 0xFF], format: "RGB" },
+ { color: [0xBF, 0x7F, 0xFF, 0xFF], format: "RGBA" },
+ { color: [0xBF, 0xBF, 0xBF, 0xFF], format: "LUMINANCE" },
+ { color: [0xBF, 0xBF, 0xBF, 0xFF], format: "LUMINANCE_ALPHA" },
+ { color: [0xBF, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
+ { color: [0xBF, 0x7F, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
+ ]
+
+ },
+ "Color Alpha": {
+ src: [
+ // [0xBF, 0x7F, 0xFF, 0x40]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQI12PYX//fAQAGvAJ+xPMwKQAAAABJRU5ErkJggg==",
+ // [0xBFBF, 0x7F7F, 0xFFFF, 0x4040]
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAYAAABPhRjKAAAAEUlEQVQI12PYv7++/v9/BwcAGGgE+8YN4XUAAAAASUVORK5CYII="
+ ],
+ expectations: [
+ { color: [0x00, 0x00, 0x00, 0x40], format: "ALPHA" },
+ { color: [0xBF, 0x7F, 0xFF, 0xFF], format: "RGB" },
+ { color: [0xBF, 0x7F, 0xFF, 0x40], format: "RGBA" },
+ { color: [0xBF, 0xBF, 0xBF, 0xFF], format: "LUMINANCE" },
+ { color: [0xBF, 0xBF, 0xBF, 0x40], format: "LUMINANCE_ALPHA" },
+ { color: [0xBF, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
+ { color: [0xBF, 0x7F, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
+ ]
+ }
+};
+
+const wtu = WebGLTestUtils;
+const gl = wtu.create3DContext();
+
+wtu.setupTexturedQuad(gl);
+gl.bindTexture(gl.TEXTURE_2D, gl.createTexture());
+
+(async () => {
+ for (const [type, testCase] of Object.entries(testData)) {
+ if (testCase.src.length != 2) throw new Error('testCase.src.length != 2');
+ let images = testCase.src.map(src => loadImage(src));
+ images = await Promise.all(images);
+ debug("");
+ debug("");
+ debug(`PNG image type ${type} with RGBA values of ${testCase.expectations[2].color}`);
+ let formats = testCase.expectations;
+ if (!wtu.isWebGL2(gl)) {
+ formats = formats.filter((f) => !f.internalformat);
+ }
+ for (const f of formats) {
+ debug("");
+ debug(`GL format: ${f.format}`);
+
+ function check(data, description) {
+ debug(`Upload ${description}`);
+ gl.texImage2D(
+ gl.TEXTURE_2D,
+ 0,
+ gl[f.internalformat || f.format],
+ gl[f.format],
+ gl.UNSIGNED_BYTE,
+ data
+ );
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, f.color, undefined, 1);
+ }
+
+ check(images[0].image, "8-bit PNG from Image");
+ check(images[1].image, "16-bit PNG from Image");
+
+ if (images[0].bitmap) {
+ check(images[0].bitmap, "8-bit PNG from ImageBitmap");
+ check(images[1].bitmap, "16-bit PNG from ImageBitmap");
+ }
+ }
+ }
+ finishTest();
+})();
+
+async function loadImage(src) {
+ const img = new Image();
+ img.src = src;
+ await img.decode();
+ const ret = { image: img };
+ if (self.createImageBitmap) {
+ try {
+ ret.bitmap = await createImageBitmap(img, {
+ premultiplyAlpha: "none",
+ });
+ } catch {}
+ }
+ return ret;
+}
+
+var successfullyParsed = true;
+ </script>
+</body>
+
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html
new file mode 100644
index 0000000000..34c94a68a7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html
@@ -0,0 +1,304 @@
+<!--
+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">
+<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="example" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Verifies texImage2D and texSubImage2D code paths taking ArrayBufferView');
+
+var wtu = WebGLTestUtils;
+
+function roundUpToAlignment(value, alignment) {
+ return Math.floor((value + alignment - 1) / alignment) * alignment;
+}
+
+function generateRGBAData(type, unpackAlignment, sourceData, width, height)
+{
+ var numColors = sourceData.length / 4;
+ var colorOffset = function(y) {
+ return 4 * Math.floor(y * numColors / height);
+ };
+
+ switch (type) {
+ case gl.UNSIGNED_BYTE: {
+ var rowWidth = roundUpToAlignment(width * 4, unpackAlignment);
+ var data = new Uint8Array(height * rowWidth);
+ for (var y = 0; y < height; ++y) {
+ var index = y * rowWidth;
+ var offset = colorOffset(y);
+ for (var element = 0; element < width * 4; ++element) {
+ data[index + element] = sourceData[offset + element % 4];
+ }
+ }
+ return data;
+ }
+ case gl.UNSIGNED_SHORT_4_4_4_4: {
+ var rowWidth = roundUpToAlignment(width * 2, unpackAlignment) / 2;
+ var data = new Uint16Array(height * rowWidth);
+ for (var y = 0; y < height; ++y) {
+ var offset = colorOffset(y);
+ for (var x = 0; x < width; ++x) {
+ var index = y * rowWidth + x;
+ data[index] = (((sourceData[offset + 0] & 0xF0) << 8)
+ | ((sourceData[offset + 1] & 0xF0) << 4)
+ | ((sourceData[offset + 2] & 0xF0) >> 0)
+ | ((sourceData[offset + 3] & 0xF0) >> 4));
+ }
+ }
+ return data;
+ }
+ case gl.UNSIGNED_SHORT_5_5_5_1: {
+ var rowWidth = roundUpToAlignment(width * 2, unpackAlignment) / 2;
+ var data = new Uint16Array(height * rowWidth);
+ for (var y = 0; y < height; ++y) {
+ var offset = colorOffset(y);
+ for (var x = 0; x < width; ++x) {
+ var index = y * rowWidth + x;
+ data[index] = (((sourceData[offset + 0] & 0xF8) << 8)
+ | ((sourceData[offset + 1] & 0xF8) << 3)
+ | ((sourceData[offset + 2] & 0xF8) >> 2)
+ | ((sourceData[offset + 3] & 0x80) >> 7));
+ }
+ }
+ return data;
+ }
+ }
+}
+
+function typeToString(type)
+{
+ switch (type) {
+ case gl.UNSIGNED_BYTE: return 'UNSIGNED_BYTE';
+ case gl.UNSIGNED_SHORT_5_5_5_1: return 'UNSIGNED_SHORT_5_5_5_1';
+ case gl.UNSIGNED_SHORT_4_4_4_4: return 'UNSIGNED_SHORT_4_4_4_4';
+ }
+ return 'Unknown type ' + type;
+}
+
+function runOneIteration(useTexSubImage2D, type, unpackAlignment, flipY, premultiplyAlpha,
+ topColor, bottomColor, extraColor, bindingTarget, program)
+{
+ debug('Testing ' + (useTexSubImage2D ? 'texSubImage2D' : 'texImage2D') +
+ ' with type=' + typeToString(type) +
+ ', unpackAlignment=' + unpackAlignment +
+ ', flipY=' + flipY + ', premultiplyAlpha=' + premultiplyAlpha +
+ ', bindingTarget=' + (bindingTarget == gl.TEXTURE_2D ? 'TEXTURE_2D' : 'TEXTURE_CUBE_MAP'));
+ gl.colorMask(true, true, true, true);
+ gl.clearColor(0, 0, 0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ // Enable writes to the RGB channels
+ gl.colorMask(true, true, true, false);
+ var texture = gl.createTexture();
+ // Bind the texture to texture unit 0
+ gl.bindTexture(bindingTarget, texture);
+ // Set up texture parameters
+ gl.texParameteri(bindingTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(bindingTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(bindingTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ // Set up pixel store parameters
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, unpackAlignment);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha);
+ // Generate the data
+ var sourceData = [ 255, 0, 0, 255,
+ 0, 255, 0, 0 ];
+ var texWidth = 5; // this must be mod 4 + 1 to test unpackAlignment
+ // cube map texture must be square.
+ if (bindingTarget == gl.TEXTURE_CUBE_MAP)
+ texWidth = 16;
+ var texHeight = 16;
+ var data = generateRGBAData(type, unpackAlignment, sourceData, texWidth, texHeight);
+ if (gl.getError() != gl.NO_ERROR)
+ testFailed("GL error before texture upload");
+ var targets = [gl.TEXTURE_2D];
+ if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
+ targets = [gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
+ }
+ // Upload the image into the texture
+ for (var tt = 0; tt < targets.length; ++tt) {
+ if (useTexSubImage2D) {
+ // Initialize the texture to black first
+ gl.texImage2D(targets[tt], 0, gl.RGBA, texWidth, texHeight, 0,
+ gl.RGBA, type, null);
+ if (gl.getError() != gl.NO_ERROR)
+ testFailed("GL error after texImage2D(null)");
+ gl.texSubImage2D(targets[tt], 0, 0, 0, texWidth, texHeight, gl.RGBA, type, data);
+ if (gl.getError() != gl.NO_ERROR)
+ testFailed("GL error after texSubImage2D");
+ } else {
+ gl.texImage2D(targets[tt], 0, gl.RGBA, texWidth, texHeight, 0, gl.RGBA, type, data);
+ if (gl.getError() != gl.NO_ERROR)
+ testFailed("GL error after texImage2D");
+ }
+ }
+
+ var testWidth = gl.drawingBufferWidth;
+ var testHeight = gl.drawingBufferHeight / 2;
+
+ var loc;
+ if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
+ loc = gl.getUniformLocation(program, "face");
+ }
+
+ for (var tt = 0; tt < targets.length; ++tt) {
+ if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
+ gl.uniform1i(loc, targets[tt]);
+ }
+
+ // Draw the triangles
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+
+ // Check the top pixel and bottom pixel and make sure they have
+ // the right color.
+ var rects = [wtu.makeCheckRect(0, 0, testWidth, testHeight, bottomColor, "bottom pixel should be " + bottomColor, 0),
+ wtu.makeCheckRect(0, testHeight, testWidth, testHeight, topColor, "top pixel should be " + topColor, 0)];
+ wtu.checkCanvasRects(gl, rects);
+ }
+
+ // Change part of the texture.
+ var partWidth = 16;
+ var partHeight = 16;
+ // make texture double res of part.
+ var data = generateRGBAData(type, unpackAlignment, sourceData, partWidth * 2, partHeight * 2);
+ for (var tt = 0; tt < targets.length; ++tt) {
+ gl.texImage2D(targets[tt], 0, gl.RGBA, partWidth * 2, partHeight * 2, 0, gl.RGBA, type, data);
+ }
+ // set part.
+ var extraData = [
+ 255, 0, 0, 255,
+ 0, 0, 255, 0
+ ];
+ var data = generateRGBAData(type, unpackAlignment, extraData, partWidth, partHeight);
+ for (var tt = 0; tt < targets.length; ++tt) {
+ gl.texSubImage2D(targets[tt], 0, 0, 0, partWidth, partHeight, gl.RGBA, type, data);
+ }
+ var halfWidth = gl.drawingBufferWidth / 2;
+ var halfHeight = gl.drawingBufferHeight / 2;
+ var quarterHeight = gl.drawingBufferHeight / 4;
+ var red = [255, 0, 0, 255];
+ var tcolor0 = flipY ? extraColor : red;
+ var tcolor1 = flipY ? red : extraColor;
+
+ for (var tt = 0; tt < targets.length; ++tt) {
+ if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
+ gl.uniform1i(loc, targets[tt]);
+ }
+
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ var rects = [wtu.makeCheckRect(0, 0, halfWidth, quarterHeight, tcolor0, "bottom left bottom pixels should be " + tcolor0, 0),
+ wtu.makeCheckRect(0, quarterHeight, halfWidth, quarterHeight, tcolor1, "bottom left top pixels should be " + tcolor1, 0),
+ wtu.makeCheckRect(halfWidth, 0, halfWidth, halfHeight, bottomColor, "bottom right pixels should be " + bottomColor, 0),
+ wtu.makeCheckRect(0, halfHeight, testWidth, halfHeight, topColor, "top pixels should be " + topColor, 0)];
+ wtu.checkCanvasRects(gl, rects);
+ }
+
+ // set far corner.
+ for (var tt = 0; tt < targets.length; ++tt) {
+ gl.texSubImage2D(targets[tt], 0, partWidth, partHeight, partWidth, partHeight, gl.RGBA, type, data);
+ }
+ for (var tt = 0; tt < targets.length; ++tt) {
+ if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
+ gl.uniform1i(loc, targets[tt]);
+ }
+
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ var rects = [wtu.makeCheckRect(0, 0, halfWidth, quarterHeight, tcolor0, "bottom left bottom pixels should be " + tcolor0, 0),
+ wtu.makeCheckRect(0, quarterHeight, halfWidth, quarterHeight, tcolor1, "bottom left top pixels should be " + tcolor1, 0),
+ wtu.makeCheckRect(halfWidth, 0, halfWidth, halfHeight, bottomColor, "bottom left pixels should be " + bottomColor, 0),
+ wtu.makeCheckRect(0, halfHeight, halfWidth, halfHeight, topColor, "top right pixels should be " + topColor, 0),
+ wtu.makeCheckRect(halfWidth, halfHeight, halfWidth, quarterHeight, tcolor0, "top right bottom pixels should be " + tcolor0, 0),
+ wtu.makeCheckRect(halfWidth, halfHeight + quarterHeight, halfWidth, quarterHeight, tcolor1, "top right top pixels should be " + tcolor1, 0)];
+ wtu.checkCanvasRects(gl, rects);
+ }
+}
+
+function runTest(bindingTarget, program)
+{
+ var red = [255, 0, 0, 255];
+ var green = [0, 255, 0, 255];
+ var blue = [0, 0, 255, 255];
+ var redPremultiplyAlpha = [255, 0, 0, 255];
+ var greenPremultiplyAlpha = [0, 0, 0, 255];
+ var bluePremultiplyAlpha = [0, 0, 0, 255];
+
+ var types = [ gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_5_5_1, gl.UNSIGNED_SHORT_4_4_4_4 ];
+ var unpackAlignments = [ 1, 2, 4, 8 ];
+
+ var cases = [
+ { sub: false, flipY: true, premultiplyAlpha: false, topColor: red, bottomColor: green, extraColor: blue },
+ { sub: false, flipY: false, premultiplyAlpha: false, topColor: green, bottomColor: red, extraColor: blue },
+ { sub: false, flipY: true, premultiplyAlpha: true, topColor: redPremultiplyAlpha, bottomColor: greenPremultiplyAlpha, extraColor: bluePremultiplyAlpha },
+ { sub: false, flipY: false, premultiplyAlpha: true, topColor: greenPremultiplyAlpha, bottomColor: redPremultiplyAlpha, extraColor: bluePremultiplyAlpha },
+ { sub: true, flipY: true, premultiplyAlpha: false, topColor: red, bottomColor: green, extraColor: blue },
+ { sub: true, flipY: false, premultiplyAlpha: false, topColor: green, bottomColor: red, extraColor: blue },
+ { sub: true, flipY: true, premultiplyAlpha: true, topColor: redPremultiplyAlpha, bottomColor: greenPremultiplyAlpha, extraColor: bluePremultiplyAlpha },
+ { sub: true, flipY: false, premultiplyAlpha: true, topColor: greenPremultiplyAlpha, bottomColor: redPremultiplyAlpha, extraColor: bluePremultiplyAlpha },
+ ];
+
+ for (var i in types) {
+ for (var j in unpackAlignments) {
+ for (var k in cases) {
+ runOneIteration(cases[k].sub, types[i], unpackAlignments[j], cases[k].flipY, cases[k].premultiplyAlpha,
+ cases[k].topColor, cases[k].bottomColor, cases[k].extraColor, bindingTarget, program);
+ }
+ }
+ }
+}
+
+var gl = wtu.create3DContext("example");
+
+var program = wtu.setupTexturedQuad(gl);
+runTest(gl.TEXTURE_2D, program);
+program = wtu.setupTexturedQuadWithCubeMap(gl);
+runTest(gl.TEXTURE_CUBE_MAP, program);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+
+const tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+
+const validDatas = [
+ `new Uint8Array(4)`,
+ `new Uint8Array(new ArrayBuffer(4))`,
+ `new Uint8ClampedArray(4)`,
+ `new Uint8ClampedArray(new ArrayBuffer(4))`,
+];
+if (window.SharedArrayBuffer) {
+ validDatas.push(
+ `new Uint8Array(new SharedArrayBuffer(4))`,
+ `new Uint8ClampedArray(new SharedArrayBuffer(4))`
+ );
+}
+for (const x of validDatas) {
+ shouldNotThrow(`gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1, 0, gl.RGBA, gl.UNSIGNED_BYTE, ${x});`);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ shouldNotThrow(`gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1, gl.RGBA, gl.UNSIGNED_BYTE, ${x});`);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-uniform-binding-bugs.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-uniform-binding-bugs.html
new file mode 100644
index 0000000000..292f94a8b8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-uniform-binding-bugs.html
@@ -0,0 +1,44 @@
+<!--
+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">
+<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>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+
+description('Tests passing a vec4 to a uniform and a canvas to texImage2D');
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+var floatProgram = wtu.loadProgramFromFile(gl, "../../../resources/floatUniformShader.vert", "../../../resources/noopUniformShader.frag");
+shouldBeUndefined("gl.useProgram(floatProgram)");
+var fval4Loc = gl.getUniformLocation(floatProgram, "fval4");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+shouldBeUndefined("gl.uniform4fv(fval4Loc, new Float32Array([0.1, 0.2, 0.4, 1.0]));");
+
+var tmpcanvas = document.createElement("canvas");
+tmpcanvas.width = 2;
+tmpcanvas.height = 2;
+var texture = gl.createTexture();
+shouldBeUndefined("gl.bindTexture(gl.TEXTURE_2D, texture)");
+shouldBeUndefined("gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tmpcanvas)");
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-canvas-corruption.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-canvas-corruption.html
new file mode 100644
index 0000000000..4277917644
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-canvas-corruption.html
@@ -0,0 +1,51 @@
+<!--
+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>Testing 3D canvas is usable after being used as texImage2D source</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="example" width="512" height="512"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+// Regression test for http://crbug.com/368582
+description();
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+var ctx = canvas.getContext("2d");
+
+var gl = wtu.create3DContext();
+var texture = gl.createTexture();
+
+var image = wtu.makeImage('../../../resources/blue-1x1.jpg', function() {
+ renderToCanvas();
+ renderToCanvas();
+ wtu.checkCanvas(ctx, [0, 0, 255, 255], "All pixels should be blue", 2);
+ finishTest();
+});
+
+function renderToCanvas() {
+ // Clear the 2d canvas then draw the image to it (a blue pixel)
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
+
+ // Upload the results to a WebGL texture
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+}
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-webgl.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-webgl.html
new file mode 100644
index 0000000000..653f8d9820
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-webgl.html
@@ -0,0 +1,78 @@
+<!--
+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 texImage2D from WebGL conformance test.</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="example" width="256" height="16" style="width: 256px; height: 48px;"></canvas>
+<canvas id="source" width="256" height="16" style="width: 256px; height: 48px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Test texImage2D from a webgl canvas.");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+gl.disable(gl.DITHER);
+var program = wtu.setupTexturedQuad(gl);
+var gl1 = wtu.create3DContext("source");
+gl1.disable(gl.DITHER);
+gl1.disable(gl.BLEND);
+gl1.disable(gl.DEPTH_TEST);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+wtu.glErrorShouldBe(gl1, gl1.NO_ERROR, "Should be no errors from setup.");
+
+gl.disable(gl.BLEND);
+gl.disable(gl.DEPTH_TEST);
+
+gl1.clearColor(1.0, 0.0, 0.0, 1.0);
+gl1.clear(gl1.COLOR_BUFFER_BIT);
+
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, gl1.canvas);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+wtu.clearAndDrawUnitQuad(gl);
+
+wtu.checkCanvas(gl, [255, 0, 0, 255], "Canvas should be red");
+
+gl1.clearColor(0.0, 1.0, 0.0, 1.0);
+gl1.clear(gl1.COLOR_BUFFER_BIT);
+
+var program1 = wtu.setupTexturedQuad(gl1);
+var tex1 = gl1.createTexture();
+gl1.bindTexture(gl.TEXTURE_2D, tex1);
+gl1.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255]));
+
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, gl1.canvas);
+wtu.clearAndDrawUnitQuad(gl);
+
+wtu.checkCanvas(gl, [0, 255, 0, 255], "Canvas should be green");
+
+// Test a scenario from Chrome where a WebGL context would lose its active texture binding when its
+// canvas was used as the texture source for another WebGL context.
+wtu.clearAndDrawUnitQuad(gl1);
+
+wtu.checkCanvas(gl1, [0, 0, 255, 255], "Canvas should be blue");
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-format-and-type.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-format-and-type.html
new file mode 100644
index 0000000000..1fbf4c6ccb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-format-and-type.html
@@ -0,0 +1,722 @@
+<!--
+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">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/pnglib.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = null;
+var textureLoc = null;
+var successfullyParsed = false;
+
+//----------------------------------------------------------------------
+// Harness
+
+var testCases = [];
+
+var DataMode = {
+ IMAGE: 0,
+ IMAGE_DATA: 1,
+
+ NUM_HTML_MODES: 2,
+
+ RAW_DATA: 2,
+
+ // This must remain the last mode.
+ NUM_MODES: 3
+};
+
+function init()
+{
+ description('Verify texImage2D and texSubImage2D code paths taking both HTML and user-specified data with all format/type combinations');
+
+ var canvas = document.getElementById("example");
+ gl = wtu.create3DContext(canvas);
+ gl.disable(gl.DITHER);
+ var program = wtu.setupTexturedQuad(gl);
+
+ gl.clearColor(0,0,0,1);
+ gl.clearDepth(1);
+ gl.disable(gl.BLEND);
+
+ textureLoc = gl.getUniformLocation(program, "tex");
+
+ initializeTests();
+}
+
+function initializeTests()
+{
+ // Verify that uploading to packed pixel formats performs the
+ // required conversion and associated loss of precision.
+ for (var dataMode = 0; dataMode < DataMode.NUM_HTML_MODES; ++dataMode) {
+ for (var useTexSubImage2D = 0; useTexSubImage2D < 2; ++useTexSubImage2D) {
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateOpaqueGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ verifier: allChannelsIncreaseByNoMoreThan,
+ threshold: 1,
+ numOccurrences: 1,
+ description: "RGBA/UNSIGNED_BYTE should maintain full precision of data"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateOpaqueGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.RGBA,
+ type: gl.UNSIGNED_SHORT_4_4_4_4,
+ verifier: allChannelsIncreaseByAtLeast,
+ threshold: 15,
+ numOccurrences: 10,
+ description: "RGBA/UNSIGNED_SHORT_4_4_4_4 must drop low four bits of precision"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateOpaqueGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.RGBA,
+ type: gl.UNSIGNED_SHORT_5_5_5_1,
+ verifier: allChannelsIncreaseByAtLeast,
+ threshold: 7,
+ numOccurrences: 20,
+ description: "RGBA/UNSIGNED_SHORT_5_5_5_1 must drop low three bits of precision"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateOpaqueGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.RGB,
+ type: gl.UNSIGNED_BYTE,
+ verifier: allChannelsIncreaseByNoMoreThan,
+ threshold: 1,
+ numOccurrences: 1,
+ description: "RGB/UNSIGNED_BYTE should maintain full precision of data"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateOpaqueGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.RGB,
+ type: gl.UNSIGNED_SHORT_5_6_5,
+ verifier: allChannelsIncreaseByAtLeast,
+ threshold: 3,
+ numOccurrences: 20,
+ description: "RGB/UNSIGNED_SHORT_5_6_5 must drop low two or three bits of precision"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTranslucentGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ verifier: alphaChannelIncreasesByNoMoreThan,
+ threshold: 1,
+ numOccurrences: 1,
+ description: "ALPHA/UNSIGNED_BYTE should maintain full precision of data"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateOpaqueGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.LUMINANCE,
+ type: gl.UNSIGNED_BYTE,
+ verifier: allChannelsIncreaseByNoMoreThan,
+ threshold: 1,
+ numOccurrences: 1,
+ description: "LUMINANCE/UNSIGNED_BYTE should maintain full precision of data"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateOpaqueGrayscaleRamp,
+ premultiplyAlpha: false,
+ format: gl.LUMINANCE_ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ verifier: allChannelsIncreaseByNoMoreThan,
+ threshold: 1,
+ numOccurrences: 1,
+ description: "LUMINANCE_ALPHA/UNSIGNED_BYTE should maintain full precision of data"
+ });
+ }
+ }
+
+ // Verify that setting the UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel
+ // store parameter and sending down a zero alpha causes the color
+ // channels to go to zero.
+ for (var dataMode = 0; dataMode < DataMode.NUM_MODES; ++dataMode) {
+ for (var useTexSubImage2D = 0; useTexSubImage2D < 2; ++useTexSubImage2D) {
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_BYTE"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.RGBA,
+ type: gl.UNSIGNED_SHORT_4_4_4_4,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_4_4_4_4"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.RGBA,
+ type: gl.UNSIGNED_SHORT_5_5_5_1,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_5_5_5_1"
+ });
+ // The following few tests are invalid for the raw data
+ // mode because there is either no alpha channel or no
+ // separate alpha channel.
+ if (dataMode != DataMode.RAW_DATA) {
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.RGB,
+ type: gl.UNSIGNED_BYTE,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_BYTE"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.RGB,
+ type: gl.UNSIGNED_SHORT_5_6_5,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_SHORT_5_6_5"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with ALPHA/UNSIGNED_BYTE"
+ });
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.LUMINANCE,
+ type: gl.UNSIGNED_BYTE,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE/UNSIGNED_BYTE"
+ });
+ }
+ testCases.push({
+ dataMode: dataMode,
+ useTexSubImage2D: !!useTexSubImage2D,
+ width: 256,
+ height: 1,
+ generator: generateTransparentGrayscaleRamp,
+ premultiplyAlpha: true,
+ format: gl.LUMINANCE_ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ verifier: colorChannelsAreZero,
+ description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE_ALPHA/UNSIGNED_BYTE"
+ });
+ }
+ }
+
+ // Produce data for all testcases. Because we load images, some of
+ // these may generate their data asynchronously.
+ generateTestData();
+}
+
+function generateTestData()
+{
+ for (var i = 0; i < testCases.length; i++) {
+ var testCase = testCases[i];
+ var wrapper = null;
+ switch (testCase.dataMode) {
+ case DataMode.IMAGE:
+ wrapper = new ImageWrapper(testCase.width, testCase.height);
+ break;
+ case DataMode.IMAGE_DATA:
+ wrapper = new ImageDataWrapper(testCase.width, testCase.height);
+ break;
+ case DataMode.RAW_DATA:
+ switch (testCase.type) {
+ case gl.UNSIGNED_BYTE:
+ switch (testCase.format) {
+ case gl.RGBA:
+ wrapper = new RGBA8DataWrapper(testCase.width, testCase.height);
+ break;
+ case gl.RGB:
+ wrapper = new RGB8DataWrapper(testCase.width, testCase.height);
+ break;
+ case gl.ALPHA:
+ wrapper = new A8DataWrapper(testCase.width, testCase.height);
+ break;
+ case gl.LUMINANCE:
+ wrapper = new L8DataWrapper(testCase.width, testCase.height);
+ break;
+ case gl.LUMINANCE_ALPHA:
+ wrapper = new LA8DataWrapper(testCase.width, testCase.height);
+ break;
+ }
+ break;
+ case gl.UNSIGNED_SHORT_4_4_4_4:
+ wrapper = new RGBA4444DataWrapper(testCase.width, testCase.height);
+ break;
+ case gl.UNSIGNED_SHORT_5_5_5_1:
+ wrapper = new RGBA5551DataWrapper(testCase.width, testCase.height);
+ break;
+ case gl.UNSIGNED_SHORT_5_6_5:
+ wrapper = new RGB565DataWrapper(testCase.width, testCase.height);
+ break;
+ }
+ }
+ testCase.wrapper = wrapper;
+ testCase.generator(wrapper);
+ testCase.wrapper.generateData();
+ }
+
+ // See whether we need to run the tests, in case all of them
+ // generated their results synchronously.
+ maybeRunTests();
+}
+
+var ranTests = false;
+
+function maybeRunTests()
+{
+ if (!ranTests)
+ for (var i = 0; i < testCases.length; ++i)
+ if (!testCases[i].wrapper || !testCases[i].wrapper.data)
+ return;
+
+ ranTests = true;
+
+ for (var i = 0; i < testCases.length; ++i)
+ runOneTest(testCases[i]);
+
+ finishTest();
+}
+
+function testCaseToString(testCase)
+{
+ var mode;
+ switch (testCase.dataMode) {
+ case DataMode.IMAGE:
+ mode = "Image";
+ break;
+ case DataMode.IMAGE_DATA:
+ mode = "ImageData";
+ break;
+ case DataMode.RAW_DATA:
+ mode = "raw data";
+ break;
+ }
+ return (testCase.useTexSubImage2D ? "texSubImage2D" : "texImage2D") +
+ " with " + mode + " at " + testCase.width + "x" + testCase.height;
+}
+
+function runOneTest(testCase)
+{
+ debug("Testing " + testCaseToString(testCase));
+ var data = testCase.wrapper.data;
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ var texture = gl.createTexture();
+ // Bind the texture to texture unit 0.
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ // Set up texture parameters.
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ // Set up pixel store parameters.
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, testCase.premultiplyAlpha);
+ // Upload the image into the texture.
+ if (testCase.useTexSubImage2D) {
+ // Initialize the texture to black first.
+ gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.width, testCase.height, 0,
+ testCase.format, testCase.type, null);
+ }
+ switch (testCase.dataMode) {
+ case DataMode.IMAGE:
+ case DataMode.IMAGE_DATA:
+ if (testCase.useTexSubImage2D)
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, testCase.format, testCase.type, data);
+ else
+ gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.format, testCase.type, data);
+ break;
+ case DataMode.RAW_DATA:
+ if (testCase.useTexSubImage2D)
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, testCase.width, testCase.height, testCase.format, testCase.type, data);
+ else
+ gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.width, testCase.height, 0, testCase.format, testCase.type, data);
+ break;
+ }
+ // Point the uniform sampler to texture unit 0.
+ gl.uniform1i(textureLoc, 0);
+ // Draw the triangles.
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ // Clean up the texture.
+ gl.deleteTexture(texture);
+
+ // Read back the rendering results.
+ var buf = new Uint8Array(testCase.width * testCase.height * 4);
+ gl.readPixels(0, 0, testCase.width, testCase.height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ // Run the verification routine.
+ if (testCase.verifier(buf, testCase.threshold, testCase.numOccurrences))
+ testPassed(testCase.description);
+ else
+ testFailed(testCase.description);
+}
+
+//----------------------------------------------------------------------
+// Wrappers for programmatic construction of Image, ImageData and raw texture data
+//
+
+function ImageWrapper(width, height)
+{
+ this.pngBuilder_ = new PNGlib(width, height, 256);
+}
+
+ImageWrapper.prototype.getWidth = function() {
+ return this.pngBuilder_.width;
+};
+
+ImageWrapper.prototype.getHeight = function() {
+ return this.pngBuilder_.height;
+};
+
+ImageWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ this.pngBuilder_.buffer[this.pngBuilder_.index(x, y)] = this.pngBuilder_.color(r, g, b, a);
+};
+
+// Generates data into "data" property, possibly asynchronously.
+ImageWrapper.prototype.generateData = function() {
+ var that = this;
+ var url = "data:image/png;base64," + this.pngBuilder_.getBase64();
+ var img = wtu.makeImage(url, function() {
+ that.data = img;
+ maybeRunTests();
+ });
+};
+
+function ImageDataWrapper(width, height)
+{
+ if (!ImageDataWrapper.tempCanvas) {
+ ImageDataWrapper.tempCanvas = document.createElement("canvas");
+ }
+ this.imageData_ = ImageDataWrapper.tempCanvas.getContext("2d").createImageData(width, height);
+}
+
+ImageDataWrapper.tempCanvas = null;
+
+ImageDataWrapper.prototype.getWidth = function() {
+ return this.imageData_.width;
+};
+
+ImageDataWrapper.prototype.getHeight = function() {
+ return this.imageData_.height;
+};
+
+ImageDataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ var index = 4 * (this.imageData_.width * y + x);
+ this.imageData_.data[index] = r;
+ this.imageData_.data[index + 1] = g;
+ this.imageData_.data[index + 2] = b;
+ this.imageData_.data[index + 3] = a;
+};
+
+ImageDataWrapper.prototype.generateData = function() {
+ this.data = this.imageData_;
+ maybeRunTests();
+};
+
+function TextureDataWrapper(width, height)
+{
+ this.width_ = width;
+ this.height_ = height;
+}
+
+TextureDataWrapper.prototype.getWidth = function() {
+ return this.width_;
+};
+
+TextureDataWrapper.prototype.getHeight = function() {
+ return this.height_;
+};
+
+TextureDataWrapper.prototype.generateData = function() {
+ this.data = this.data_;
+ maybeRunTests();
+};
+
+function RGBA8DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint8Array(4 * width * height);
+}
+
+RGBA8DataWrapper.prototype = new TextureDataWrapper;
+
+RGBA8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ var index = 4 * (this.width_ * y + x);
+ this.data_[index] = r;
+ this.data_[index + 1] = g;
+ this.data_[index + 2] = b;
+ this.data_[index + 3] = a;
+};
+
+function RGBA5551DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint16Array(width * height);
+}
+
+RGBA5551DataWrapper.prototype = new TextureDataWrapper;
+
+RGBA5551DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ var value = (((r & 0xF8) << 8)
+ | ((g & 0xF8) << 3)
+ | ((b & 0xF8) >> 2)
+ | (a >> 7));
+ this.data_[this.width_ * y + x] = value;
+};
+
+function RGBA4444DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint16Array(width * height);
+}
+
+RGBA4444DataWrapper.prototype = new TextureDataWrapper;
+
+RGBA4444DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ var value = (((r & 0xF0) << 8)
+ | ((g & 0xF0) << 4)
+ | (b & 0xF0)
+ | (a >> 4));
+ this.data_[this.width_ * y + x] = value;
+};
+
+function RGB8DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint8Array(3 * width * height);
+}
+
+RGB8DataWrapper.prototype = new TextureDataWrapper;
+
+RGB8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ var index = 3 * (this.width_ * y + x);
+ this.data_[index] = r;
+ this.data_[index + 1] = g;
+ this.data_[index + 2] = b;
+};
+
+function RGB565DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint16Array(width * height);
+}
+
+RGB565DataWrapper.prototype = new TextureDataWrapper;
+
+RGB565DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ var value = (((r & 0xF8) << 8)
+ | ((g & 0xFC) << 3)
+ | ((b & 0xF8) >> 3));
+ this.data_[this.width_ * y + x] = value;
+};
+
+function A8DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint8Array(width * height);
+}
+
+A8DataWrapper.prototype = new TextureDataWrapper;
+
+A8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ this.data_[this.width_ * y + x] = a;
+};
+
+function L8DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint8Array(width * height);
+}
+
+L8DataWrapper.prototype = new TextureDataWrapper;
+
+L8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ this.data_[this.width_ * y + x] = r;
+};
+
+function LA8DataWrapper(width, height)
+{
+ TextureDataWrapper.call(this, width, height);
+ this.data_ = new Uint8Array(2 * width * height);
+}
+
+LA8DataWrapper.prototype = new TextureDataWrapper;
+
+LA8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
+ var index = 2 * (this.width_ * y + x);
+ this.data_[index] = r;
+ this.data_[index + 1] = a;
+};
+
+//----------------------------------------------------------------------
+// Color ramp generation functions
+//
+
+function generateOpaqueGrayscaleRamp(wrapper)
+{
+ var width = wrapper.getWidth();
+ var height = wrapper.getHeight();
+ for (var x = 0; x < width; ++x) {
+ var value = Math.round(255.0 * x / width);
+ for (var y = 0; y < height; ++y)
+ wrapper.setPixel(x, y, value, value, value, 255);
+ }
+}
+
+function generateTranslucentGrayscaleRamp(wrapper)
+{
+ var width = wrapper.getWidth();
+ var height = wrapper.getHeight();
+ for (var x = 0; x < width; ++x) {
+ var value = Math.round(255.0 * x / width);
+ for (var y = 0; y < height; ++y)
+ wrapper.setPixel(x, y, value, value, value, value);
+ }
+}
+
+function generateTransparentGrayscaleRamp(wrapper)
+{
+ var width = wrapper.getWidth();
+ var height = wrapper.getHeight();
+ for (var x = 0; x < width; ++x) {
+ var value = Math.round(255.0 * x / width);
+ for (var y = 0; y < height; ++y)
+ wrapper.setPixel(x, y, value, value, value, 0);
+ }
+}
+
+//----------------------------------------------------------------------
+// Verification routines
+//
+
+function allChannelsIncreaseByNoMoreThan(array, threshold, numOccurrences) {
+ var numFound = 0;
+ for (var i = 4; i < array.length; i += 4)
+ for (var j = 0; j < 4; j++)
+ if (array[i + j] - array[i + j - 4] > threshold)
+ ++numFound;
+
+ return numFound < numOccurrences;
+}
+
+function alphaChannelIncreasesByNoMoreThan(array, threshold, numOccurrences) {
+ var numFound = 0;
+ for (var i = 7; i < array.length; i += 4)
+ if (array[i] - array[i - 4] > threshold)
+ ++numFound;
+
+ return numFound < numOccurrences;
+}
+
+function allChannelsIncreaseByAtLeast(array, threshold, numOccurrences) {
+ var numFound = 0;
+ for (var i = 4; i < array.length; i += 4)
+ for (var j = 0; j < 4; ++j)
+ if (array[i + j] - array[i + j - 4] > threshold)
+ ++numFound;
+
+ return numFound > numOccurrences;
+}
+
+function colorChannelsAreZero(array, threshold, numOccurrences) {
+ var passed = true;
+ var numFailures = 0;
+
+ for (var i = 4; i < array.length; i += 4)
+ for (var j = 0; j < 3; ++j)
+ if (array[i + j] != 0) {
+ passed = false;
+ if (++numFailures <= 5)
+ debug(" array[" + (i + j) + "] should have been 0, was " + array[i + j]);
+ }
+
+ return passed;
+}
+
+</script>
+</head>
+<body onload="init()">
+<canvas id="example" width="256" height="1"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-invalid-data.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-invalid-data.html
new file mode 100644
index 0000000000..4500624c81
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-invalid-data.html
@@ -0,0 +1,158 @@
+<!--
+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>texImage2D and texSubImage2D tests with invalid data</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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script type="application/javascript">
+description("texImage2D and texSubImage2D tests with invalid data");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var contextVersion = wtu.getDefault3DContextVersion();
+var gl = wtu.create3DContext(canvas);
+if (!gl)
+ testFailed("Context created.");
+else
+ testPassed("Context created.");
+
+var tex;
+
+function setup() {
+ tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+}
+
+function teardown() {
+ gl.deleteTexture(tex);
+}
+
+function test(desc, func, expected) {
+ debug(desc);
+
+ var exc = null;
+ try {
+ func();
+ } catch (x) {
+ exc = x;
+ }
+
+ if (expected == gl.INVALID_OPERATION) {
+ wtu.glErrorShouldBe(gl, expected);
+ } else if (expected == "exception") {
+ if (exc) {
+ testPassed("threw exception");
+ } else {
+ testFailed("did not throw exception");
+ }
+ }
+}
+
+test("Calling texImage2D with no WebGLTexture bound generates INVALID_OPERATION",
+ function () {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ },
+ gl.INVALID_OPERATION);
+
+test("Calling texSubImage2D with no WebGLTexture bound generates INVALID_OPERATION",
+ function () {
+ var buffer = new Uint8Array(4);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buffer);
+ },
+ gl.INVALID_OPERATION);
+
+setup();
+
+test("Passing a buffer not large enough to texImage2D should generate an INVALID_OPERATION",
+ function () {
+ var tooSmall = new Uint8Array(64);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, tooSmall);
+ },
+ gl.INVALID_OPERATION);
+
+if (contextVersion < 2) {
+ test("Passing texImage2D parameter data of Number type should throw an exception",
+ function () {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, 42);
+ },
+ "exception");
+} else {
+ test("Passing texImage2D parameter data of Number type should generate an INVALID_OPERATION",
+ function () {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, 42);
+ },
+ gl.INVALID_OPERATION);
+}
+
+if (contextVersion < 2) {
+ test("Passing texImage2D parameter data of String type should throw a TypeError",
+ function () {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
+ },
+ "exception");
+} else {
+ test("Passing texImage2D parameter data of String type should generate an INVALID_OPERATION",
+ function () {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
+ },
+ gl.INVALID_OPERATION);
+}
+
+test("Passing a buffer not large enough to texSubImage2D should generate an INVALID_OPERATION",
+ function () {
+ var tooSmall = new Uint8Array(64);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, tooSmall);
+ },
+ gl.INVALID_OPERATION);
+
+if (contextVersion < 2) {
+ test("Passing texSubImage2D parameter data of Number type should throw a TypeError",
+ function () {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, 42);
+ },
+ "exception");
+} else {
+ test("Passing texSubImage2D parameter data of Number type should generate an INVALID_OPERATION",
+ function () {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, 42);
+ },
+ gl.INVALID_OPERATION);
+}
+
+if (contextVersion < 2) {
+ test("Passing texSubImage2D parameter data of String type should throw a TypeError",
+ function () {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
+ },
+ "exception");
+} else {
+ test("Passing texSubImage2D parameter data of String type should generate an INVALID_OPERATION",
+ function () {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
+ },
+ gl.INVALID_OPERATION);
+}
+
+teardown();
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-input-validation.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-input-validation.html
new file mode 100644
index 0000000000..b0910422f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-input-validation.html
@@ -0,0 +1,24 @@
+<!--
+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">
+<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>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+var contextVersion = 1;
+</script>
+<script src="../../../js/tests/tex-input-validation.js"></script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d-bad-args.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d-bad-args.html
new file mode 100644
index 0000000000..8cbd00cce9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d-bad-args.html
@@ -0,0 +1,133 @@
+<!--
+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">
+<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="testbed" width="16" height="16"></canvas>
+<canvas id="c" width="16" height="16"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Tests texSubImage2D with bad arguments');
+
+var wtu = WebGLTestUtils;
+var contextVersion = wtu.getDefault3DContextVersion();
+var c = document.getElementById("c");
+
+var gl = wtu.create3DContext("testbed");
+var tex = gl.createTexture();
+var maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
+var maxTextureLevel = Math.floor(Math.log2(maxTextureSize)) + 1;
+
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 1, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "no previously defined texture image");
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Setup should succeed");
+
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 1, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "y + height > texture height");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "x + width > texture width");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "negative x");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, -1, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "negative y");
+gl.texSubImage2D(gl.TEXTURE_2D, -1, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "negative level");
+shouldThrow("gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "null pixels");
+
+// GL_INVALID_VALUE may be generated if level is greater than log 2 max, where max is the returned value of GL_MAX_TEXTURE_SIZE.
+// GL_INVALID_OPERATION is generated if the texture array has not been defined by a previous glTexImage2D or glCopyTexImage2D operation whose internalformat matches the format of glTexSubImage2D.
+gl.texSubImage2D(gl.TEXTURE_2D, maxTextureLevel + 1, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_OPERATION], "too high level");
+
+gl.texSubImage2D(gl.FLOAT, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "bad target");
+if (contextVersion > 1) {
+ gl.texSubImage2D(gl.TEXTURE_3D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+ wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "bad target");
+}
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "good args");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "format not same as original");
+if (contextVersion < 2) {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, c);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type not same as original");
+}
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "make texture RGB");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "format same as original RGB");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "format not same as original RGB");
+if (contextVersion < 2) {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, c);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type not same as original RGB");
+}
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "make texture RGBA UNSIGNED_BYTE");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "format same as original");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "format not same as original");
+if (contextVersion < 2) {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, c);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type not same as original");
+}
+
+// Large canvas will trigger GPU-to-GPU fast path in chrome,
+// while small canvas will go into normal path, i.e. read pixles from canvas then upload to texture.
+var largeCanvas = document.createElement("canvas");
+largeCanvas.width = 257;
+largeCanvas.height = 257;
+var largeCanvasContext = largeCanvas.getContext("2d");
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, largeCanvas);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "make texture RGBA UNSIGNED_BYTE");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "format same as original");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, c);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "format not same as original");
+if (contextVersion < 2) {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, c);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type not same as original");
+}
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, largeCanvas);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "format same as original");
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, largeCanvas);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "format not same as original");
+if (contextVersion < 2) {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, largeCanvas);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "type not same as original");
+}
+
+var maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
+var maxCubeMapTextureLevel = Math.floor(Math.log2(maxCubeMapTextureSize)) + 1;
+for (var f = 0; f < 6; f++) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, c);
+ gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + f, maxCubeMapTextureLevel + 1, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, c);
+ wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_OPERATION], "too high level");
+ gl.deleteTexture(tex);
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d.html
new file mode 100644
index 0000000000..0d72946613
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d.html
@@ -0,0 +1,101 @@
+<!--
+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">
+<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="fshader" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform sampler2D tex;
+varying vec2 texCoord;
+
+void main()
+{
+ float intensity = texture2D(tex, texCoord).a;
+ gl_FragColor = vec4(intensity, intensity, intensity, 1.0);
+}
+</script>
+
+</head>
+<body>
+<canvas id="example" width="256" height="1"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Tests texSubImage2D upload path from Uint8Array');
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas);
+gl.disable(gl.DITHER);
+var program = wtu.setupProgram(
+ gl,
+ [wtu.simpleTextureVertexShader, "fshader"],
+ ['vPosition', 'texCoord0']);
+wtu.setupUnitQuad(gl);
+var textureWidth = 256;
+var textureHeight = 1;
+
+var textureLoc = gl.getUniformLocation(program, "tex");
+
+var texture = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+// Allocate the texture object
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, textureWidth, textureHeight, 0, gl.ALPHA, gl.UNSIGNED_BYTE, null);
+// Prepare the image data
+var array = new Uint8Array(textureWidth);
+for (var i = 0; i < textureWidth; i++)
+ array[i] = i;
+// Fill the texture object with data -- this is actually the code path being tested
+gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, gl.ALPHA, gl.UNSIGNED_BYTE, array);
+
+// Clear and set up
+gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.useProgram(program);
+gl.uniform1i(textureLoc, 0);
+// Draw the texture to the frame buffer
+gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+// Read back the frame buffer
+var buf = new Uint8Array(textureWidth * textureHeight * 4);
+gl.readPixels(0, 0, textureWidth, textureHeight, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+
+// Verify the frame buffer's contents
+var passed = true;
+for (var i = 0; i < textureWidth; i++) {
+ var val = i;
+ if (buf[4 * i + 0] != val ||
+ buf[4 * i + 1] != val ||
+ buf[4 * i + 2] != val) {
+ testFailed("pixel at (" + i + ", 0) was (" +
+ buf[4 * i + 0] + ", " +
+ buf[4 * i + 1] + ", " +
+ buf[4 * i + 2] + "), should be (" +
+ val + ", " + val + ", " + val + ")");
+ passed = false;
+ break;
+ }
+}
+
+if (passed)
+ testPassed("");
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html
new file mode 100644
index 0000000000..ee9bad4341
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html
@@ -0,0 +1,191 @@
+<!--
+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>Texture uploading from video through tex unit 1 bug</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="example" width="640" height="480"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<img id="src-image">
+<script id="shader-fs" type="x-shader/x-fragment">
+ precision mediump float;
+
+ uniform sampler2D uTexture0;
+ uniform sampler2D uTexture1;
+
+ varying vec2 vUV;
+
+ void main(void) {
+ vec4 texture0Color = texture2D(uTexture0, vUV);
+ vec4 texture1Color = texture2D(uTexture1, vUV);
+
+ gl_FragColor = mix(texture0Color, texture1Color, 0.5);
+ }
+</script>
+<script id="shader-vs" type="x-shader/x-vertex">
+ attribute vec3 aVertexPosition;
+ attribute vec2 aTextureCoord;
+
+ varying vec2 vUV;
+
+ void main(void) {
+ vUV = aTextureCoord;
+ gl_Position = vec4(aVertexPosition, 1.0);
+ }
+</script>
+
+<script>
+"use strict";
+
+(async function test() {
+ var wtu = WebGLTestUtils;
+ description("Regression test for crbug.com/676719");
+
+ var gl = wtu.create3DContext("example", {preserveDrawingBuffer: true});
+
+ if (!gl) {
+ testFailed("context does not exist");
+ finishTest();
+ return;
+ }
+
+ var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"],
+ ["aVertexPosition", "aTextureCoord"], [0, 1]);
+
+ if (!program) {
+ testFailed("program does not exist");
+ finishTest();
+ return;
+ }
+
+ var loc0 = gl.getUniformLocation(program, "uTexture0");
+ var loc1 = gl.getUniformLocation(program, "uTexture1");
+ if (!loc0 || !loc1) {
+ testFailed("Failed to query uniform locations");
+ finishTest();
+ return;
+ }
+ gl.uniform1i(loc0, 0);
+ gl.uniform1i(loc1, 1);
+
+ wtu.setupUnitQuad(gl, 0, 1);
+
+ // Load textures
+ var imageSrc = "data:type/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AwVEx4QrzHJHAAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAABm4SURBVHja7d15eN11nejxT3KSnGxN2qbpku5JWwpdkIIszuCwWWxlExFx7kVleUYF1OHqPMgz3AsyzAVRmasiijrORR2duV4Z2gLKUugIc1kKLWhZuqTQtE26pm3S7Nv9Q6cPe5vfSdq05/V6Hv6g7e8sv3PO97zPb/n+cqpufbovAICskmsVAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAAAQAFYBAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAABYBUAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAANkq70h4Epu/elJWvFjjb3vGOxbIekV5OTF3bEnMqyqN4/70X1VZ2tiajQEAwJEpJ/pixqiifV/27xtXGkeNKoq8lA3YAgAOA5lspbLlh2wypiQv3ldVuu8L/9ixJVGa9lUlAAA4oq34wvFWwkFiGwoACAAAQAAAAAIAABAAAIAAAAAEAAAwZJkHAIDDyt6O7vj9lpZYWd8SK+qbY2X9XvMHZGsADMZMaZleX8DsbQCZ6+7pjTU722Jl/d4//dcSq3e0Rl/kWDkCAIAjRUNTR6xs2Bsr/vRl/2LD3mjr7nvLv/LlLwAAOKKccNcLVoIAIKmRRamYO7YkZo8piemjimLcsIIYW1oQ5YWpKMzLjcK83Ojp64u2rt5o6eyNhubO2NzUEWvfsJltT0evFQkJDSvIjTNrhse88aVx1KjimDw8HaXpVJQWpKKnty9au3qisbU76vZ0xKW/WmMMQACQ3FGjCuP8Y0bFmdXlMXts6QG98Om8VAwvihhfno4TYti+v+vu6Y3lm5vjwdW74tertg/oQPC/PlIdH59TmWjZ2p2tMf8nq6K9py+jx1CYlxMPXzYnaiqKEi3/f/6wPa59YP3b/jzT40bezWBfSfBQX6nwUNz/YN3n8VUlcfXJVXF6dXkU5KXe8d/kpyIK81Mxsrggxg0ryLoxAAHAAMiJvjj/6Iq4/ISxcfz4YQP3pkjlximTyuOUSeVx/V9MjHtf2hHf/n+bo765K+Pbvv6h12JeVUnUVBT3e9maiuK44YxJccMjGzJ6DDeeMTnxl//aHa1x/UOvefPxJmNK8uL2BdVx1rQR/fsM52TfGMDQYR6Aw9TpU8vj0cvnxPfOnz6gH/y3Ki5IxX89bkz87q+Ojes+OCEKMnzHtHX3xefuWxftXT2Jlv/0caPjzycnf75nVJfHp+aNSfbYu3r++Ni7+7wB2eesmvJ47Mq5/f7y/8+v8GwbAxAAJFSezo1vn1MdP//EzJg5uuSg3W9Rfiq++IHx8dvL5sTRlUUZ3dbL29vi5sfqkr1hc3PjjoU1MSzBKDSiMBXfWlid+HHftHRDvLqjzZuQfT45d1T844UzYnhRfrJf8DnZOQYgAOin6RWF8ZvPzImLZlcessdwVGVxLL50VsyfNjyj27ln5bZ4cPXORMuOL0/H38+f0u/lvrGgOkaXJtvnuuSVnfHzF7Z7E7LPR48ZGd9cWBN5qeTDaE4WjwEIAA7QSRNKY/Gls2LyiMJD/liKC1Lx4wunxyVzRmV0O19+cH1s3N2eaNmPza6MhTMOfJPrJ+aMigVHjUx0X6/vaouv/Ga9NyH7nDihNKOtScYABAAHZN64kvjpx4+KssKhc8xmKjc3bl8wNRbMSP4roKmjN65atC66epIdYfz1D0+JUcX7XycTywvia2dOTnQfnd098flF62Jvp6Og36q3NzvXSVk6N+46b1qk3+Uo/35tAcjJ7jEAAcB7qBqWH/d8/KgoTQ+9EzZSublx57nTYs6Y4sS3saKhJb7+u42Jlh1ZXBDf3M+vsJzoi++cUxPDEg6c/3PZxvj9llZvxHeQrYdC3nb21BhXlh6Q28oxBiAAeCd5ORE//Oj0GFmcP2QfY2F+Ku46f1oU5yc/mvn7TzfEsvW7Ey37oWkj4pNz330z5NUnV8WJE8sS3fYjaxvjR89t9UZ8twDI0gI4/5iB2+yds59NANkyBnCIvmOsgqHr6pPHxXFVmZ3e09vbG8te2xOP1e6O5zbvjYbmztjd1h3pvNyoKM6L46pK44ya4XHezJHvOnHJ/lSPLIrrPjgxblya7Mj+yMmJLyxZF49ePifGDOv/L6ubzpwcT25oio17Ot/057NGF8WX/3x8ooe0eU9H/PUD9vvbAjC4cowBCADeqmpYflxzyviMbmPZ+t1xw8Ovx2u7O972d91dvdGypzPq9jTGolca4/bfbYrbzp4SZ9SMSHRfn543Jn66cmvUNnYkWr6xrSe+sKQ2fnnJzEjl9m/DVGk6L759Tk187J9f3neFsHQqJ+48d1qiAa27pzeuXrwudrf3eCO+5xYACZD5FgBjAAKAt/jiB8ZHcUHyg4xuXVYXdz7dcOC/eJs641O/Wh1fO2tyXHHCuH7fX34qN679swlxzZLaxI/5P+qa486n6uNLfzah38ueNLEsPnfiuPj+s1siIuJvT58YMyqT7Zf81pObYvnmvf1e7r2miD3U0+0Ohl7f/2/S09sbyzftjcfX746n65piW0tX7Gjtis7uvigvzIuqsoKYPaY4TplUFmfWDI/hRfnvuQUgG8cABEDWG1mUiotmJ9/PeMeTm/r1wd/3iy5y4sZHN8TE8nTMn97/U+bOmTkybnm8LrbsTT5d6Dee2BQnTyqLkxLst//KqRPisfW7Y0xpQVyWcLa/J17bHd99qj5cblQA9MdjtbvilsfrYvWOdz6tdWdbd+xs644/bG2NX/5+R6RyIs6ePiI+e+JYYwCHjIMAh6CPzRoVRfnJyn/F5ua448lNie+7L3Li+odeTzRVb34qNy7O8LzgvsiJqxeti8bW/g8ghfmpuPO8aXHHwurIze3/W3vb3s64enHtvt0I7Oe1sgsgenp747rfro9Lf7XmXb/833G5vogH1+yK83/+ijEAAcAbK7oi8bI3P1aX8RfYlr1dce9LyWbpW5hwsp03atjbFf/tgWSbEY8ZXZLoFK2e3t744pLa2NnW7Q1oC8CBPf/e3rh6ce2gzBCZ7WMAAiArjShMxbyqZPN7v7KtJdG+63eytHZXouXmjC2NMSWZ71l6pHZP/Gh5w0Fb73c+3RBPbGjyBuzXL8Xs9o/Pb40lrzYaAwZpDEAAZJ0Txpcm2nwdEfHw2l0D9jj+sDX55DfzxpcOyGO45bG6eLFh76Cv82c3NsU3n9jkzdfvLQDZmwCvNbbFrcs2GgMGeQxAAGSV4zK4rOezm5oH7HHsbE1+EM+8qoG5NGl3X8TnF62N5vbB2yzf2NoVVy1a54A2WwD69+v/uS3R0dNnDBjkMYDBZTvNEFMzMvmFPv75E0cPiecwdQAvVrJhd2d89aHX4nvnTx+Ux3rtA7XR4IjlZAGQpQXQ2tkd/3fVDmPAQRoDsAUga0wsTx/2z2FCecGA3t59rzTGL1/cNuCP84fPNsSjtXu86WwD6Jf/2NAUzYN4cShjAAIgS40pzT/sn8PokoF/Djc8/Hqs2T5wF+V5ob45/v5x05bSfyvr9xoDDsEYgAA44pXkpw7751A8CM+hvacvPnvf2mjtzHx63qb27vj8onXRbb8/SQKgocUYcAjGAATAEa8w//B/SYoG6Tms2dke//Zy5vteH1jdGHVvuXAQSWTnhEmb9nQYAw7RGIAAYIjLSw3O2+rYscXx8dmZzzJ28ZxRccpERyln/PU/AN//RXmHX0Q0dbhI1KEaAxAAR7S2rl4r4R2UpXPjBxdMT3y50jdK5ebGnefVxMgimykzGuQHoADK0offa9A8yAFgDEAAZKnWLr8u3skdC2ti0vCBO7Vo7LB0fPfcadl7LtsAKBiAX+9lhYffmciDdf6/MQABkOW2OSf9bS4/fkwsGIT5xU+rHh7XnFJlBSeUzktFToanAs4YVWRFGgM4REwENMRs3NMRc8clm0bz2O88Hztaj6yL2cwZUxw3nD5x0G7/b06dEM9sbB6w+dOzTVF+brR2JY+A2WNKrERjALYAEBGxfld74mVnjSk+otZFaUFu3H3B9EjnDd5+4rxUbtx1/rQYXpi9xwP09Cbf51yezuw3xIkTHIxpDEAAEBERKzL4JXqkDabfWlgdkw/ClKJVZen49jk1WXs8QEcGEyKMzmDSmvFlBXHiBBeNMQYgAIiIiOcz+PBfNHtUxvtkh4rPHDc6o2ui99dZ00bE504aN2i339WT/Fd2YWpwT5XL5KCzmork+/A/Obcy8VXvjAFH/hiAAMg6O9u6Y2V9sit6TSgvjAUzRh6Sxz1rdFH84uKjBuy2/vsZkxIt+1pjWzS2Jpvk57oPTojjxg3OPunO7uQBMG7Y4M6rvr0l+UFnSX9xVg3Lj8+eONYH3hiAAOCNlrzSmHjZv/vQ5BhWcPBe1hkVhfG9c2vit5+ZHX9RPTzj2yvJ/+N+/8IEU4l29fTGNUtq48sPvpbovgvyUvH986dFWXrg19+eDM4d/8DkskF9DRuak8+KuHDGiCjs5+mAOdEXt509NYoLHINsDEAA8Ca/fmlHtCfcLDt2WDp+9NHpg77Z+P3jS+MnF06PpVfMiQtmjRqwTbnfXDA1po5Mtln5H57cFC80tMTD63bHz1ZuTXQbE4cXxj98pGbA19eODH5lX3XyuChPD95Hde3O5AedVZQUxK1nTz3wBfr64o6F1XHmtBE+6MYABABv+7Jo7Y57X9qZePlTpw6Pf7lkZowvG9hNxyMKU3HZvNGx9PLZcd+ls+LsGSMH9EN/6fsq47xjkk31u3xjU3znqfp9/3/Toxti3Y5kVw/88IyRcfnxYwZ03dVlMH/8lBFFsfSKuXHNyePi+KqSqCjKi4H8gffy1swubnPxnMq45UOTY3/Tv08sL4hfXjIzLp472ofcGMAQYBvcEPXdpzbHhbMqEm0Kj4h4/8SyWHbl3Pj+Mw3xs5VbY3vCc4OrR6Tj1CnlsWDGiDhlUtmgzfF9TGVR3HTm5ETLNrd3xzVLaqPvDRenae/pi6sWr4sln5qV6DTCG06fGMs3Nccftg7MJYjX7mjLaPlxZem4/rT+HRcx/rZnDujfPbWxOePnd9nxY+ODU8rj5y9sjcdq90R9c0f09UWMKS2ImZVFce7Mipg/fUQUF5h+2Rjw3jZ/9aSDvq6T3ueBfsYEAP38xdgZdz5dH185NfkkOMUFqfjyqRPiSx+oiic3NMXTdU2xamtrrN/VFk3tPbG3syd6+iKK8nKjtCA3xpWlY3xZQcwYVRSzRpfEseNKoqosPejPtTg/J36QcL9/RMTfPvJ6bGp6+37sl7a1xdf/fVP8jwRhkc5LxQ8umBbzf7IqWgZgbvblm5uH7Httc1NnrNneGjMqMzuHvKaiKG48c0rceKbPrzEAAUBG7nyqPuZPG5F4VrB9L3IqN06rHh6nDdEDdG7/cHXi08kWv7wjfv0em0rvfrYhTqsujw9O7f9znzKiKL61sDo+t2hdxs/xmY3N0drZM2R/AS96ZWf8TaVJZIwBZBM7b4awrt6IK+5dk/i0tsPBXx5bGR+dlWy//+Y9HXHdQ/s54j8nJ750f23idXju0RXxqeMy32fd3t0Xj67bNWRfh1+8uC06ul2ExhiAAGDIqG/uik//ak00tx9583vPHFUUN5+VbL9/T29vfOn+2mjq2P/m+W0t3YlPDYyIuPGMSXFMZeYXrfnxc1uG7GuxraU7/uX32w/6/d79TL0PeRaPAQgA9mNFQ0v85b++GrvbjpyrhBXl5cTdF0yLooT7/e9+dku/Dl57eN3u+OmKZF/Ahfmp+MEF06Mow8vfPl/fEr9Z3ThkX5Pbf7fpoP7SvO+lHXHzY3U+4Fk6BiAA6McA8JF7XorV21uPiOdz24enxrRRyfY5r9qyN77+7xv7vdxNS+tiTcL1V1NRFLcvmJrx877+odeivqljSL4mu9t74q/vXx+9vb2Dfl/3vrQ9vnB/bUROjg93lo4BCAD64fXdHfGRe1bFPz2/JaMruA20rp7eWPTyjjjnnlUH9O8vmTMqLppdmei+Wjt74qrF6yLJ9Ws6evri6sXrEu/rvnBWZXxy7qiM1tX21u74L//66pCNgKXr98TXBvlX+Y+XN8QXl9RGrynrs3YMQACQQFt3X9zwyIY496cvxVN1ew7pY1nf2Ba3LauLk+5aGVctro2VDfufUGZGRWH83YemJL7PWx6vi9rG5F+eL29vi1uXbUy8/M1nTYkZFZldoXDNzvZY+L9XDdndAT9+bmt89bfro3OADwrc29EdVy1aGzcurXvTnA1k1xjA0OE0wMPUi1ta46JfvBonTSiNvzpxXJxRXR4FeYN/ilnd7vb4zerGuP/VxljRzw97YV5O3H3B9MSnwi1dtyvuWbkt4+fwo+Vb4vTq4YnmLS8uSMXdF0yPBfesivYMLqO7vbU7rvy3tXF8VUlcecLYOGva0Jok52cvbI9VW1vjGwumxtGjM79A0v2v7oyvLd0Q9c32YWfzGIAAYAA9s2lvPLNpbYwoTMW5R1fEGdXlccqksihND8xLu6OlM1bU740nX2+KJ17fE2symDf+1vlTEk82s6OlM659YP3ArLQ/nRq49Io5UVHS/6lSZ1QWx63zp8S1GZxZ8J+er2+J5xfXRmFeTpw4YVi8f8KwmF5RFJOGp6OyJD/K06koyMuN/NTB31i3sqEl5v/TqrjwmIq48v1jY87Y/p2L3tndEw+u3hU/XN4QL26x39oYwFCTU3Xr0/bEHWFSOREzK/84k9fM0cUxqTwdY0rzY3RpfpQUpCKdyo10Xk709kV0dPdGW1dv7Gjtih0tXbG5qTPWN7ZHbWNbrNra+o4z7JGdpg5Px2nV5TFvfGlUjyiMqrJ0lBakIp2XE21dvbGnvSfq9rTHq9vb4qm6pli2fs+AzKKIMQABAAAMEAcBAoAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAgAAEAAAAACAAAQAACAAAAABAAAIAAAAAEAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAABAAAIAAAAAEAAAgAAAAAQAACAAAQAAAAAIAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAAQAACAAAAABAAAIAABAAAAAAgAAEAAAgAAAAN7o/wMPKI9LWOVgigAAAABJRU5ErkJggg==";
+ var imageElement = document.getElementById("src-image");
+ imageElement.src = imageSrc;
+ await imageElement.decode();
+
+ var resourcePath = "../../../resources/";
+
+ var videos = [
+ { src: resourcePath + "red-green.mp4",
+ type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' },
+ { src: resourcePath + "red-green.webmvp8.webm",
+ type: 'video/webm; codecs="vp8, vorbis"' },
+ { src: resourcePath + "red-green.bt601.vp9.webm",
+ type: 'video/webm; codecs="vp9"' },
+ { src: resourcePath + "red-green.theora.ogv",
+ type: 'video/ogg; codecs="theora, vorbis"' },
+ ];
+ var currentVideo = null;
+
+ for (const info of videos) {
+ currentVideo = info;
+ debug("");
+ debug("testing: " + info.type);
+ const video = document.createElement("video");
+ video.muted = true;
+ var canPlay = true;
+ if (!video.canPlayType) {
+ testFailed("video.canPlayType required method missing");
+ continue;
+ }
+ if(!video.canPlayType(info.type).replace(/no/, '')) {
+ debug(info.type + " unsupported");
+ continue;
+ }
+ document.body.appendChild(video);
+ video.type = info.type;
+ video.src = info.src;
+ await new Promise(res => {
+ wtu.startPlayingAndWaitForVideo(video, res);
+ });
+ video.pause();
+
+ var texture0 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ var texture1 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageElement);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ // <-- Begin Observed -->
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, texture1);
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
+
+ wtu.clearAndDrawUnitQuad(gl, [255, 0, 255, 255]);
+
+ var observedPixels = new Uint8Array(640 * 480 * 4);
+ gl.readPixels(0, 0, 640, 480, gl.RGBA, gl.UNSIGNED_BYTE, observedPixels);
+ // <-- End Observed -->
+
+ // <-- Begin Expected -->
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture0);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
+
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, texture1);
+
+ wtu.clearAndDrawUnitQuad(gl, [255, 0, 255, 255]);
+
+ var expectedPixels = new Uint8Array(640 * 480 * 4);
+ gl.readPixels(0, 0, 640, 480, gl.RGBA, gl.UNSIGNED_BYTE, expectedPixels);
+ // <-- End Expected -->
+
+ // Compare results
+ const tolerance = 1;
+ var numDifferentPixels = wtu.comparePixels(observedPixels, expectedPixels, tolerance, undefined);
+ if (numDifferentPixels) {
+ testFailed("Texture states were incorrect for " + currentVideo.type +
+ ", rendering was wrong: found " + numDifferentPixels + " differing pixels");
+ } else {
+ testPassed(`Texture states were correct +/-${tolerance}, rendering as expected`);
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+ }
+
+ debug("");
+ finishTest();
+})();
+</script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texparameter-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texparameter-test.html
new file mode 100644
index 0000000000..e6e33874cf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texparameter-test.html
@@ -0,0 +1,129 @@
+<!--
+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 TexParameter conformance test.</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_drawing" width="12" height="12"></canvas>
+<canvas id="canvas_texture" width="2" height="2"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Tests TexParameter works as expected");
+debug("");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas_drawing");
+var canvas_texture = null;
+var texParam = [
+ gl.REPEAT,
+ gl.CLAMP_TO_EDGE,
+ gl.MIRRORED_REPEAT,
+];
+var color = [200, 0, 254, 255];
+var textures = [];
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ wtu.setupTexturedQuadWithTexCoords(gl, [-2.5, -2.5], [3.5, 3.5]);
+
+ setupCanvasTexture();
+ setupTextures();
+ for (var ii = 0; ii < texParam.length; ++ii) {
+ runDrawingTest(textures[ii], texParam[ii]);
+ }
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+function setupCanvasTexture() {
+ canvas_texture = document.getElementById("canvas_texture");
+ var ctx2d = canvas_texture.getContext("2d");
+ ctx2d.fillStyle = "rgba(" + color[0] + "," + color[1] + "," + color[2] + "," + color[3] + ")";
+ ctx2d.fillRect(0, 0, 1, 1);
+}
+
+function setupTextures() {
+ for (var ii = 0; ii < texParam.length; ++ii) {
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas_texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texParam[ii]);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texParam[ii]);
+ textures[ii] = texture;
+ }
+}
+
+function runDrawingTest(texture, param) {
+ gl.clearColor(1, 1, 1, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ checkPixels(param);
+}
+
+function checkPixels(param) {
+ var buf = new Uint8Array(12 * 12 * 4);
+ gl.readPixels(0, 0, 12, 12, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var passed = true;
+ for (var yy = 0; yy < 12; ++yy) {
+ for (var xx = 0; xx < 12; ++xx) {
+ var ec = [0, 0, 0, 0];
+ switch (param) {
+ case gl.REPEAT:
+ if (xx % 2 == 1 && yy % 2 == 1) {
+ ec = color;
+ }
+ break;
+ case gl.CLAMP_TO_EDGE:
+ if (xx < 6 && yy < 6) {
+ ec = color;
+ }
+ break;
+ case gl.MIRRORED_REPEAT:
+ if (xx % 4 < 2 && yy % 4 < 2) {
+ ec = color;
+ }
+ break;
+ }
+ var off = (yy * 12 + xx) * 4;
+ if (buf[off + 0] != ec[0] || buf[off + 1] != ec[1] ||
+ buf[off + 2] != ec[2] || buf[off + 3] != ec[3]) {
+ var msg = 'at (' + xx + ', ' + yy + ') expected: ' +
+ ec[0] + ', ' + ec[1] + ', ' + ec[2] + ', ' + ec[3] + ' found: ' +
+ buf[off + 0] + ', ' + buf[off + 1] + ', ' + buf[off + 2] + ', ' + buf[off + 3];
+ testFailed(msg);
+ passed = false;
+ }
+ }
+ }
+ if (passed) {
+ testPassed("Drawing with wrap " + wtu.glEnumToString(gl, param) + " as expected");
+ }
+}
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind-2.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind-2.html
new file mode 100644
index 0000000000..f459924ad1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind-2.html
@@ -0,0 +1,210 @@
+<!--
+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 ActiveTexture BindTexture conformance test #2</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="example" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<canvas id="canvas2d" width="1" height="1" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+uniform mat4 world;
+attribute vec3 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = world * vec4(vPosition, 1);
+ texCoord = texCoord0;
+}
+</script>
+<script id="fshader2d" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform sampler2D tex2d;
+varying vec2 texCoord;
+void main()
+{
+ gl_FragColor = texture2D(tex2d, texCoord);
+}
+</script>
+<script id="fshaderCube" type="x-shader/x-fragment">
+precision mediump float;
+
+uniform samplerCube texCube;
+void main()
+{
+ gl_FragColor = textureCube(texCube, vec3(0,1,0));
+}
+</script>
+
+<script>
+"use strict";
+function init()
+{
+ description(
+ "Tests that binding both TEXTURE_2D and TEXTURE_CUBE_MAP to the same " +
+ "active texture unit works as long as they are not used " +
+ "simultaneously in the same shader program.");
+
+ var canvas2d = document.getElementById("canvas2d");
+ var ctx2d = canvas2d.getContext("2d");
+ ctx2d.globalCompositeOperation = "copy";
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext("example");
+ var program = wtu.setupProgram(
+ gl, ["vshader", "fshader2d"], ["vPosition", "texCoord0"]);
+
+ var program2d = program;
+ var programCube = wtu.setupProgram(
+ gl, ["vshader", "fshaderCube"], ["vPosition", "texCoord0"]);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array([-1, 1,0, 1,1,0, -1,-1,0,
+ -1,-1,0, 1,1,0, 1,-1,0]),
+ gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ new Float32Array([ 0,0, 1,0, 0,1,
+ 0,1, 1,0, 1,1]),
+ gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+
+ // Make texture unit 1 active.
+ gl.activeTexture(gl.TEXTURE1);
+
+ // Make a 2d texture
+ var tex2d = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+ ctx2d.fillStyle = "rgba(0, 0, 255, 255)";
+ ctx2d.fillRect(0, 0, 1, 1);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+
+ // make a cube texture
+ var texCube = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCube);
+ ctx2d.fillStyle = "rgba(255, 0, 255, 255)";
+ ctx2d.fillRect(0, 0, 1, 1);
+ var targets = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
+ for (var ii = 0; ii < targets.length; ++ii) {
+ gl.texImage2D(targets[ii], 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+ }
+
+ // Setup program2d and programCube
+ var tex2dLoc = gl.getUniformLocation(program2d, "tex2d");
+ var world2dLoc = gl.getUniformLocation(program2d, "world");
+ var texCubeLoc = gl.getUniformLocation(programCube, "texCube");
+ var worldCubeLoc = gl.getUniformLocation(programCube, "world");
+
+ gl.useProgram(program2d);
+ gl.uniform1i(tex2dLoc, 1);
+ gl.useProgram(programCube);
+ gl.uniform1i(texCubeLoc, 1);
+
+ gl.clearColor(1,0,0,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ var programs = [program2d, programCube];
+ var worldLocs = [world2dLoc, worldCubeLoc];
+ for (var ii = 0; ii < 4; ++ii) {
+ var x = ii % 2;
+ var y = Math.floor(ii / 2);
+ gl.useProgram(programs[x]);
+ gl.uniformMatrix4fv(
+ worldLocs[x], false,
+ [0.5, 0, 0, 0,
+ 0, 0.5, 0, 0,
+ 0, 0, 1, 0,
+ -0.5 + x, -0.5 + y, 0, 1]);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+
+ var colors = [
+ [0,0,255,255],
+ [255,0,255,255],
+ [0,0,255,255],
+ [255,0,255,255]];
+
+ for (var ii = 0; ii < colors.length; ++ii) {
+ var c = colors[ii];
+ var x = ii % 2;
+ var y = Math.floor(ii / 2);
+ wtu.checkCanvasRect(gl, x, y, 1, 1, c);
+ }
+
+ // Test that binding to one target does not affect the other
+ debug("");
+ debug("Testing texture target binding/unbinding");
+
+ var worldMatrix = [
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1];
+
+ gl.activeTexture(gl.TEXTURE2);
+
+ // Unbinding the TEXTURE_CUBE_MAP target should not affect the TEXTURE_2D target
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCube);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+
+ gl.useProgram(program2d);
+ gl.uniform1i(tex2dLoc, 2);
+ gl.uniformMatrix4fv(world2dLoc, false, worldMatrix);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ wtu.checkCanvasRect(gl, 0, 0, 2, 2, [0,0,255,255]);
+
+ // Unbinding the TEXTURE_2D target should not affect the TEXTURE_CUBE_MAP target
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCube);
+ gl.bindTexture(gl.TEXTURE_2D, tex2d);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ gl.useProgram(programCube);
+ gl.uniform1i(texCubeLoc, 2);
+ gl.uniformMatrix4fv(worldCubeLoc, false, worldMatrix);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ wtu.checkCanvasRect(gl, 0, 0, 2, 2, [255,0,255,255]);
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind.html
new file mode 100644
index 0000000000..f24bd9b1f3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind.html
@@ -0,0 +1,179 @@
+<!--
+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 ActiveTexture BindTexture conformance test.</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="example" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<canvas id="canvas2d" width="1" height="1" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+uniform mat4 world;
+attribute vec3 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = world * vec4(vPosition, 1);
+ texCoord = texCoord0;
+}
+</script>
+<script id="trivial-vs" type="text/plain">
+void main()
+{
+ gl_Position = vec4(0,0,0,1);
+ gl_PointSize = 1.0;
+}
+</script>
+<script id="tex-point-fs" type="text/plain">
+precision mediump float;
+uniform sampler2D uSampler;
+void main()
+{
+ gl_FragColor = texture2D(uSampler, vec2(0));
+}
+</script>
+<script>
+"use strict";
+var gl;
+
+function init()
+{
+ description(
+ "Tests that glActiveTexture and glBindTexture work as expected" +
+ "Specifically texture targets are per active texture unit.");
+
+ var canvas2d = document.getElementById("canvas2d");
+ var ctx2d = canvas2d.getContext("2d");
+
+ var wtu = WebGLTestUtils;
+ gl = wtu.create3DContext("example");
+ var program = wtu.setupProgram(
+ gl,
+ ["vshader", wtu.simpleTextureFragmentShader],
+ ['vPosition', 'texCoord0']);
+ wtu.setupUnitQuad(gl);
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var colors = [
+ [0,192,128,255],
+ [128,64,255,255],
+ [192,255,64,255],
+ [200,0,255,255]];
+
+ // Make 4 textures by using 4 active texture units if available.
+ var texunits = Math.min(colors.length, gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS))
+ var textures = [];
+ for (var ii = 0; ii < texunits; ++ii) {
+ var tex = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0 + ii);
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ textures[ii] = tex;
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ // now use each texture unit to write into the textures,
+ for (var ii = 0; ii < texunits; ++ii) {
+ var c = colors[ii];
+ ctx2d.fillStyle =
+ "rgba(" + c[0] + "," + c[1] + "," + c[2] + "," + c[3] + ")";
+ ctx2d.fillRect(0, 0, 1, 1);
+ gl.activeTexture(gl.TEXTURE0 + ii);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var textureLoc = gl.getUniformLocation(program, "tex");
+ var worldLoc = gl.getUniformLocation(program, "world");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.clearColor(1,0,0,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ for (var ii = 0; ii < texunits; ++ii) {
+ var x = ii % 2;
+ var y = Math.floor(ii / 2);
+ gl.uniform1i(textureLoc, ii);
+ gl.uniformMatrix4fv(
+ worldLoc, false,
+ [0.5, 0, 0, 0,
+ 0, 0.5, 0, 0,
+ 0, 0, 1, 0,
+ -0.5 + x, -0.5 + y, 0, 1]);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ for (var ii = 0; ii < texunits; ++ii) {
+ var x = ii % 2;
+ var y = Math.floor(ii / 2);
+ wtu.checkCanvasRect(gl, x, y, 1, 1, colors[ii]);
+ }
+
+ debug("");
+ debug("Swizzle applied to correct ActiveTexture index");
+
+ {
+ const prog = wtu.setupProgram(
+ gl,
+ ["trivial-vs", "tex-point-fs"]);
+ prog.uSampler = gl.getUniformLocation(prog, "uSampler");
+ gl.useProgram(prog);
+ gl.viewport(0, 0, 1, 1);
+ gl.activeTexture(gl.TEXTURE0);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ const tex0_rgba8 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex0_rgba8);
+ const tex0_rgba8_data = new Uint8Array([10, 20, 30, 40]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0_rgba8_data);
+
+ const tex2_a8 = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex2_a8);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, 1, 1, 0, gl.ALPHA, gl.UNSIGNED_BYTE, null);
+
+ window.control = new Uint8Array(4);
+ window.after_swizzle_applied = new Uint8Array(4);
+
+ gl.bindTexture(gl.TEXTURE_2D, tex0_rgba8);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, window.control);
+ shouldBeString("window.control", tex0_rgba8_data.toString());
+
+ gl.activeTexture(gl.TEXTURE2);
+ gl.bindTexture(gl.TEXTURE_2D, tex2_a8);
+ gl.uniform1i(prog.uSampler, 2);
+ gl.activeTexture(gl.TEXTURE0);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ // Firefox would apply the A8-on-R8 swizzle to whatever tex-unit was active.
+
+ gl.uniform1i(prog.uSampler, 0);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, window.after_swizzle_applied);
+ shouldBeString("window.after_swizzle_applied", tex0_rgba8_data.toString());
+ // Firefox would then get 0,0,0,10 here, as the [ZERO,ZERO,ZERO,RED] swizzle was applied to our
+ // 10,20,30,40 texture.
+ }
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-attachment-formats.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-attachment-formats.html
new file mode 100644
index 0000000000..b569ca061d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-attachment-formats.html
@@ -0,0 +1,176 @@
+<!--
+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 Texture Attachment Format Conformance 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>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2" style="width: 100px; height:100px; border: 1px solid black;"> </canvas>
+<script>
+"use strict";
+description();
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking texture formats.");
+
+ var numValidFormats = 0;
+ var clearColor = [0.25, 0.5, 0.75, 0.25];
+
+ var floatToBits = function(value, bits) {
+ var range = (1 << bits) - 1;
+ var result = 0;
+ if (range > 0) {
+ result = Math.floor(Math.floor(value * range) * 255 / range);
+ }
+
+ //debug("v = " + value + ", bits = " + bits + ", range = " + range + ", result = " + result);
+ return result;
+ }
+
+ var testFormat = function(info) {
+ debug("");
+ debug("testing: " + info.format + ", " + info.type);
+
+ var format = gl[info.format];
+ var type = gl[info.type];
+
+ gl.texImage2D(gl.TEXTURE_2D,
+ 0, // level
+ format, // internalFormat
+ 16, // width
+ 16, // height
+ 0, // border
+ format, // format
+ type, // type
+ null); // data
+ var fbStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ debug(wtu.glEnumToString(gl, fbStatus));
+ if (fbStatus != gl.FRAMEBUFFER_COMPLETE) {
+ debug("format unsupported");
+ if (info.mustBeFramebufferComplete) {
+ testFailed(info.format + " must be FRAMEBUFFER_COMPLETE");
+ }
+ return;
+ }
+
+ ++numValidFormats;
+
+ var startExpected = [0, 0, 0, info.channels[3] < 0 ? 255 : 0];
+
+ var expected = [];
+ var tolerance = [];
+ for (var ii = 0; ii < 4; ++ii) {
+ var color = 0;
+ var channel = info.channels[ii];
+ if (channel < 0) {
+ color = ii < 3 ? 0 : 255
+ } else {
+ color = floatToBits(clearColor[channel], info.bits[ii]);
+ }
+ expected.push(color);
+ tolerance.push(channel < 0 ? 0 : (1 + (1 << (8 - info.bits[ii]))));
+ }
+
+ wtu.checkCanvas(gl, startExpected, "should be " + startExpected);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ wtu.checkCanvas(gl, expected, "should be " + expected + " with tolerance " + tolerance, tolerance);
+ }
+
+ var validFormats = [
+ { format: 'RGBA',
+ type: 'UNSIGNED_BYTE',
+ channels: [0, 1, 2, 3],
+ bits: [8, 8, 8, 8],
+ mustBeFramebufferComplete: true
+ },
+ { format: 'ALPHA',
+ type: 'UNSIGNED_BYTE',
+ channels: [-1, -1, -1, 3],
+ bits: [0, 0, 0, 8],
+ mustBeFramebufferComplete: false
+ },
+ { format: 'RGB',
+ type: 'UNSIGNED_BYTE',
+ channels: [0, 1, 2, -1],
+ bits: [8, 8, 8, 0],
+ mustBeFramebufferComplete: false
+ },
+ { format: 'RGB',
+ type: 'UNSIGNED_SHORT_5_6_5',
+ channels: [0, 1, 2, -1],
+ bits: [5, 6, 5, 0],
+ mustBeFramebufferComplete: false
+ },
+ { format: 'RGBA',
+ type: 'UNSIGNED_SHORT_5_5_5_1',
+ channels: [0, 1, 2, 3],
+ bits: [5, 5, 5, 1],
+ mustBeFramebufferComplete: false
+ },
+ { format: 'RGBA',
+ type: 'UNSIGNED_SHORT_4_4_4_4',
+ channels: [0, 1, 2, 3],
+ bits: [4, 4, 4, 4],
+ mustBeFramebufferComplete: false
+ },
+ { format: 'LUMINANCE',
+ type: 'UNSIGNED_BYTE',
+ channels: [0, 0, 0, -1],
+ bits: [8, 8, 8, -1],
+ mustBeFramebufferComplete: false
+ },
+ { format: 'LUMINANCE_ALPHA',
+ type: 'UNSIGNED_BYTE',
+ channels: [0, 0, 0, 3],
+ bits: [8, 8, 8, 8],
+ mustBeFramebufferComplete: false
+ }
+ ];
+
+ gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.framebufferTexture2D(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+
+ for (var ii = 0; ii < validFormats.length; ++ii) {
+ var info = validFormats[ii];
+ testFormat(info);
+ }
+
+ debug("");
+ shouldBeTrue("numValidFormats > 0");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-clear.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-clear.html
new file mode 100644
index 0000000000..6e658f5b4e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-clear.html
@@ -0,0 +1,43 @@
+<!--
+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 texture clear conformance test.</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="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description(document.title);
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var program = wtu.setupTexturedQuad(gl);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0,255,0,255]));
+wtu.clearAndDrawUnitQuad(gl);
+wtu.checkCanvas(
+ gl, [0, 255, 0, 255], "should be green");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-complete.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-complete.html
new file mode 100644
index 0000000000..370f6d5fa2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-complete.html
@@ -0,0 +1,63 @@
+<!--
+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 "Texture Complete" texture conformance test.</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="example" width="40" height="40" style="width: 40px; height: 40px;"></canvas>
+<canvas id="canvas2d" width="16" height="16" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function init()
+{
+ description(
+ "Checks that a texture that is not -texture-complete- does not draw if"+
+ " filtering needs mips");
+
+ var canvas2d = document.getElementById("canvas2d");
+ var ctx2d = canvas2d.getContext("2d");
+ ctx2d.fillStyle = "rgba(0,192,128,1)";
+ ctx2d.fillRect(0, 0, 16, 16);
+
+ var wtu = WebGLTestUtils;
+ var canvas = document.getElementById("example");
+ var gl = wtu.create3DContext(canvas);
+ var program = wtu.setupTexturedQuad(gl);
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ // 16x16 texture no mips
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0,0,0,255],
+ "texture that is not -texture-complete- when " +
+ "TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255");
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-and-deletion.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-and-deletion.html
new file mode 100644
index 0000000000..1caff3d224
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-and-deletion.html
@@ -0,0 +1,91 @@
+<!--
+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>WebGL Texture Copying and Deletion Test</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="example" width="1" height="1" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description('Checks that texture copying and deletion work correctly together.');
+debug('Regression test for <a href="http://anglebug.com/4267">http://anglebug.com/4267</a>');
+const wtu = WebGLTestUtils;
+const canvas = document.getElementById("example");
+canvas.addEventListener('webglcontextlost', contextLost, false);
+
+let contextWasLost = false;
+function contextLost(e) {
+ e.preventDefault();
+ contextWasLost = true;
+ debug("***context lost -- should not happen***");
+}
+
+const gl = wtu.create3DContext(canvas);
+
+const texture = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+const texture2 = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, texture2);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+const framebuffer = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+assertMsg(gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE,
+ "framebuffer should be FRAMEBUFFER_COMPLETE.");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setup");
+
+// This test does not call getError, because doing so seems to cause
+// an implicit flush which intermittently masks the bug.
+
+debug("");
+debug("testing copyTexImage2D");
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.copyTexImage2D(gl.TEXTURE_2D, 1, gl.RGBA, 0, 0, 2, 2, 0);
+// Not necessary to do any CopyTexImage2D operations to texture2.
+
+debug("");
+debug("testing copyTexSubImage2D");
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.copyTexSubImage2D(gl.TEXTURE_2D, 1, 0, 0, 0, 0, 1, 1);
+gl.bindTexture(gl.TEXTURE_2D, texture2);
+gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+
+debug('deleting framebuffer');
+gl.deleteFramebuffer(framebuffer);
+debug('deleting texture');
+gl.deleteTexture(texture);
+debug('deleting texture2');
+// On buggy driver, crashes during this deleteTexture call.
+gl.deleteTexture(texture2);
+
+setTimeout(function() {
+ shouldBe("contextWasLost", "false");
+ finishTest();
+}, 1000);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-feedback-loops.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-feedback-loops.html
new file mode 100644
index 0000000000..0ff4e0ec4c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-feedback-loops.html
@@ -0,0 +1,82 @@
+<!--
+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 Texture Copying Feedback Loops Test</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="example" width="1" height="1" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+"use strict";
+description("Checks that texture copying feedback loops fail correctly.");
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+
+var texture = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+var texture2 = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, texture2);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+var framebuffer = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+assertMsg(gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE,
+ "framebuffer should be FRAMEBUFFER_COMPLETE.");
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setup");
+
+debug("");
+debug("testing copyTexImage2D");
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.copyTexImage2D(gl.TEXTURE_2D, 1, gl.RGBA, 0, 0, 2, 2, 0);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "after copyTexImage2D to same texture but different level");
+gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 2, 2, 0);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "after copyTexImage2D to same texture same level, invalid feedback loop");
+gl.bindTexture(gl.TEXTURE_2D, texture2);
+gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 2, 2, 0);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "after copyTexImage2D to different texture");
+
+debug("");
+debug("testing copyTexSubImage2D");
+gl.bindTexture(gl.TEXTURE_2D, texture);
+gl.copyTexSubImage2D(gl.TEXTURE_2D, 1, 0, 0, 0, 0, 1, 1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "after copyTexSubImage2D to same texture but different level");
+gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "after copyTexSubImage2D to same texture same level, invalid feedback loop");
+gl.bindTexture(gl.TEXTURE_2D, texture2);
+gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "after copyTexSubImage2D to different texture");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-corner-case-videos.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-corner-case-videos.html
new file mode 100644
index 0000000000..0d7061c83f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-corner-case-videos.html
@@ -0,0 +1,47 @@
+<!--
+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">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/texture-corner-case-videos.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<canvas id="c2d" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest(
+ 'Verify uploading various corner-case videos to 2D textures',
+ "RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "", 1,
+ [
+ // Regression test for http://crbug.com/701060.
+ // Generated with the following command line:
+ // ffmpeg -r 25 -i red-green-480-272.png -vframes 10 -vcodec h264 -vf setsar=136:135,setdar=16:9 -pix_fmt yuv420p ...
+ {
+ comment: "Video whose natural size is larger than coded size due to uncommon pixel shape (Sample Aspect Ratio)",
+ src: "../../../resources/red-green-480x272-sar-136x135-dar-16x9.mp4",
+ type: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
+ // A fairly high tolerance is used because colorspace conversion seems to differ widely between
+ // hardware-accelerated video decoders. At least on Windows / NVIDIA, this test was seen to convert
+ // (0,255,0) to (13,238,14), and (255,0,0) to (238,14,14).
+ tolerance: 18,
+ }
+ ])();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-cube-as-fbo-attachment.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-cube-as-fbo-attachment.html
new file mode 100644
index 0000000000..5e09d3240f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-cube-as-fbo-attachment.html
@@ -0,0 +1,65 @@
+<!--
+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 texture cube as FBO color attachment</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="example" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+var gl;
+
+function run()
+{
+ description(
+ "Tests using a cube map face as the color attachment of a framebuffer object. " +
+ "This test covers an ANGLE validation bug. See https://code.google.com/p/angleproject/issues/detail?id=849 .");
+
+ var wtu = WebGLTestUtils;
+ gl = wtu.create3DContext("example");
+ var textureCube = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, textureCube);
+ var faces = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ for (var ii = 0; ii < faces.length; ++ii) {
+ gl.texImage2D(faces[ii], 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ }
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ for (var ii = 0; ii < faces.length; ++ii) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, faces[ii], textureCube, 0);
+ shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors for face " + wtu.glEnumToString(gl, faces[ii]));
+ }
+}
+
+run();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-draw-with-2d-and-cube.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-draw-with-2d-and-cube.html
new file mode 100644
index 0000000000..c905c5595a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-draw-with-2d-and-cube.html
@@ -0,0 +1,103 @@
+<!--
+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 ActiveTexture BindTexture conformance test.</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="example" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<canvas id="canvas2d" width="1" height="1" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec3 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vec4(vPosition, 1);
+ texCoord = texCoord0;
+}
+</script>
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+varying vec2 texCoord;
+uniform sampler2D tex2D;
+uniform samplerCube texCube;
+void main()
+{
+ gl_FragColor = texture2D(tex2D, texCoord);
+ gl_FragColor += textureCube(texCube, vec3(texCoord, 0));
+}
+</script>
+<script>
+"use strict";
+var gl;
+
+function init()
+{
+ description(
+ "Tests drawing with two textures of different type. " +
+ "This test covers an ANGLE validation bug. See http://crbug.com/390412.");
+
+ var canvas2d = document.getElementById("canvas2d");
+ var ctx2d = canvas2d.getContext("2d");
+
+ var wtu = WebGLTestUtils;
+ gl = wtu.create3DContext("example");
+ var program = wtu.setupProgram(
+ gl,
+ ["vshader", "fshader"],
+ ['vPosition', 'texCoord0']);
+ wtu.setupUnitQuad(gl);
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var texture2D = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture2D);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var textureCube = gl.createTexture();
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, textureCube);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ var texture2DLoc = gl.getUniformLocation(program, "tex2D");
+ var textureCubeLoc = gl.getUniformLocation(program, "texCube");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+
+ gl.clearColor(1,0,0,1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ gl.uniform1i(texture2DLoc, 0);
+ gl.uniform1i(textureCubeLoc, 1);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR);
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-fakeblack.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-fakeblack.html
new file mode 100644
index 0000000000..ecd1d40ca5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-fakeblack.html
@@ -0,0 +1,94 @@
+<!--
+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>Tests if fake black textures are corectly implemented on desktops</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="example" width="24" height="24"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+
+function createTexture(gl,r,g,b,a) {
+ // setup render target texture //
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 3, 3, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ // setup framebuffer //
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ // fill the framebuffer //
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.clearColor(r, g, b, a);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ gl.deleteFramebuffer(fbo);
+
+ return texture;
+}
+
+function init() {
+ /*
+ * This test has been written due to a bug found in firefox's code
+ * and fixed in the following patch :
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=879952#c5
+ */
+ var wtu = WebGLTestUtils;
+ description();
+
+ var gl = wtu.create3DContext("example");
+ var program = wtu.setupTexturedQuad(gl);
+
+ var texture0 = createTexture(gl,1,0,0,1);
+ var texture1 = createTexture(gl,0,1,0,1);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.checkCanvas(gl, [255, 0, 0, 255]);
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.checkCanvas(gl, [0, 0, 0, 255]);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture1);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.checkCanvas(gl, [0, 255, 0, 255]);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture0);
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ wtu.checkCanvas(gl, [0, 0, 0, 255]);
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-formats-test.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-formats-test.html
new file mode 100644
index 0000000000..863ab53a0b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-formats-test.html
@@ -0,0 +1,274 @@
+<!--
+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 Texture Format Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/desktop-gl-constants.js"></script>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas2d" width="2" height="2" style="width: 50px; height: 50px; border: 1px solid black;"></canvas>
+<canvas id="canvas" width="2" height="2" style="width: 100px; height:100px; border: 1px solid black;"></canvas>
+<script>
+"use strict";
+description("This test ensures WebGL implementations allow the OpenGL ES 2.0 texture formats and do not allow DesktopGL texture formats.");
+
+debug("");
+debug("Canvas.getContext");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+if (!gl) {
+ testFailed("context does not exist");
+} else {
+ testPassed("context exists");
+
+ debug("");
+ debug("Checking texture formats.");
+
+ var createTexture = function(internalFormat, format, opt_border) {
+ var border = (opt_border === undefined) ? 0 : opt_border;
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D,
+ 0, // level
+ internalFormat, // internalFormat
+ 16, // width
+ 16, // height
+ border, // border
+ format, // format
+ gl.UNSIGNED_BYTE, // type
+ null); // data
+ }
+
+ var testValidFormat = function(internalFormat, formatName) {
+ createTexture(internalFormat, internalFormat);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "was able to create texture of " + formatName);
+ }
+
+ var testInvalidFormat = function(internalFormat, formatName) {
+ createTexture(internalFormat, internalFormat);
+ var err = gl.getError();
+ if (err == gl.NO_ERROR) {
+ testFailed("should NOT be able to create texture of type " + formatName);
+ } else if (err == gl.INVALID_ENUM || err == gl.INVALID_VALUE) {
+ testPassed("not able to create invalid format: " + formatName);
+ }
+ }
+
+ var invalidEnums = [
+ '1',
+ '2',
+ '3',
+ '4',
+ 'RGB4',
+ 'RGB5',
+ 'RGB8',
+ 'RGB10',
+ 'RGB12',
+ 'RGB16',
+ 'RGBA2',
+ 'RGBA4',
+ 'RGB5_A1',
+ 'RGBA8',
+ 'RGB10_A2',
+ 'RGBA12',
+ 'RGBA16',
+ 'BGR',
+ 'BGRA',
+ 'ALPHA4_EXT',
+ 'ALPHA8_EXT',
+ 'ALPHA12_EXT',
+ 'ALPHA16_EXT',
+ 'COMPRESSED_ALPHA',
+ 'COMPRESSED_LUMINANCE',
+ 'COMPRESSED_LUMINANCE_ALPHA',
+ 'COMPRESSED_INTENSITY',
+ 'COMPRESSED_RGB',
+ 'COMPRESSED_RGBA',
+ 'DEPTH_COMPONENT16',
+ 'DEPTH_COMPONENT24',
+ 'DEPTH_COMPONENT32',
+ 'LUMINANCE4_EXT',
+ 'LUMINANCE8_EXT',
+ 'LUMINANCE12_EXT',
+ 'LUMINANCE16_EXT',
+ 'LUMINANCE4_ALPHA4_EXT',
+ 'LUMINANCE6_ALPHA2_EXT',
+ 'LUMINANCE8_ALPHA8_EXT',
+ 'LUMINANCE12_ALPHA4_EXT',
+ 'LUMINANCE12_ALPHA12_EXT',
+ 'LUMINANCE16_ALPHA16_EXT',
+ 'INTENSITY_EXT',
+ 'INTENSITY4_EXT',
+ 'INTENSITY8_EXT',
+ 'INTENSITY12_EXT',
+ 'INTENSITY16_EXT',
+ 'RGB4_EXT',
+ 'RGB5_EXT',
+ 'RGB8_EXT',
+ 'RGB10_EXT',
+ 'RGB12_EXT',
+ 'RGB16_EXT',
+ 'RGBA2_EXT',
+ 'RGBA4_EXT',
+ 'RGB5_A1_EXT',
+ 'RGBA8_EXT',
+ 'RGB10_A2_EXT',
+ 'RGBA12_EXT',
+ 'RGBA16_EXT',
+ 'SLUMINANCE_EXT',
+ 'SLUMINANCE8_EXT',
+ 'SLUMINANCE_ALPHA_EXT',
+ 'SLUMINANCE8_ALPHA8_EXT',
+ 'SRGB_EXT',
+ 'SRGB8_EXT',
+ 'SRGB_ALPHA_EXT',
+ 'SRGB8_ALPHA8'
+ ];
+
+ for (var ii = 0; ii < invalidEnums.length; ++ii) {
+ var formatName = invalidEnums[ii]
+ if (desktopGL[formatName] === undefined) {
+ debug("bad format" + formatName)
+ } else {
+ testInvalidFormat(desktopGL[formatName], "GL_" + formatName);
+ }
+ }
+
+ var validEnums = [
+ 'ALPHA',
+ 'RGB',
+ 'RGBA',
+ 'LUMINANCE',
+ 'LUMINANCE_ALPHA'
+ ];
+
+ for (var ii = 0; ii < validEnums.length; ++ii) {
+ var formatName = validEnums[ii]
+ testValidFormat(gl[formatName], "gl." + formatName);
+ }
+
+ debug("");
+ debug("checking non 0 border parameter to gl.TexImage2D");
+ createTexture(gl['RGBA'], gl['RGBA'], 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "non 0 border to gl.TexImage2D should return INVALID_VALUE");
+
+
+ var checkTypes = function() {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ var checkType = function(r, g, b, a, type, format, buf) {
+ var typeName = wtu.glEnumToString(gl, type);
+ var formatName = wtu.glEnumToString(gl, format);
+ var desc = "format: " + formatName + ", type: " + typeName;
+ debug("");
+ debug("checking gl.texImage2D with " + desc + " and buffer type " +
+ buf.constructor.name);
+ gl.texImage2D(gl.TEXTURE_2D,
+ 0, // level
+ format, // internalFormat
+ 2, // width
+ 2, // height
+ 0, // border
+ format, // format
+ type, // type
+ buf); // data
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D with " + desc + " should generate NO_ERROR");
+
+ wtu.clearAndDrawUnitQuad(gl, [255, 0, 0, 255]);
+ wtu.checkCanvas(gl, [r,g,b,a],
+ "texture " + desc + " should draw with " +
+ r + ", " + g + ", " + b + ", " + a);
+
+ }
+ checkType(
+ 0, 255, 0, 255, gl.UNSIGNED_BYTE, gl.RGBA,
+ new Uint8Array(
+ [ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255]));
+ checkType(
+ 0, 255, 0, 255, gl.UNSIGNED_BYTE, gl.RGBA,
+ new Uint8ClampedArray(
+ [ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255,
+ 0, 255, 0, 255]));
+ checkType(
+ 0, 0, 255, 255, gl.UNSIGNED_SHORT_4_4_4_4, gl.RGBA,
+ new Uint16Array(
+ [ 255, 255,
+ 255, 255,
+ 255, 255,
+ 255, 255]));
+ checkType(
+ 0, 255, 0, 255, gl.UNSIGNED_SHORT_5_6_5, gl.RGB,
+ new Uint16Array(
+ [ 2016, 2016,
+ 2016, 2016,
+ 2016, 2016,
+ 2016, 2016]));
+ checkType(
+ 0, 0, 255, 255, gl.UNSIGNED_SHORT_5_5_5_1, gl.RGBA,
+ new Uint16Array(
+ [ 63, 63,
+ 63, 63,
+ 63, 63,
+ 63, 63]));
+ checkType(
+ 255, 255, 255, 255, gl.UNSIGNED_BYTE, gl.LUMINANCE,
+ new Uint8Array([
+ 255,
+ 255,
+ 255,
+ 255]));
+ checkType(
+ 0, 0, 0, 128, gl.UNSIGNED_BYTE, gl.ALPHA,
+ new Uint8Array([
+ 128,
+ 128,
+ 128,
+ 128]));
+ checkType(
+ 128, 128, 128, 192, gl.UNSIGNED_BYTE, gl.LUMINANCE_ALPHA,
+ new Uint8Array([
+ 128, 192,
+ 128, 192,
+ 128, 192,
+ 128, 192]));
+ }
+ var program = wtu.setupTexturedQuad(gl);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+ checkTypes();
+}
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-hd-dpi.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-hd-dpi.html
new file mode 100644
index 0000000000..5126fad9f7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-hd-dpi.html
@@ -0,0 +1,117 @@
+<!--
+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 HD-DPI issues texture conformance test.</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="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description();
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var program = wtu.setupTexturedQuad(gl);
+
+function fillInMips(gl, size) {
+ // fill in the mips
+ var level = 1;
+ for (;;) {
+ size /= 2;
+ if (size < 1) {
+ break;
+ }
+ var numBytes = size * size * 4;
+ var pixels = new Uint8Array(numBytes);
+ for (var jj = 0; jj < numBytes; jj += 4) {
+ pixels[jj + 0] = 0;
+ pixels[jj + 1] = 255;
+ pixels[jj + 2] = 0;
+ pixels[jj + 3] = 255;
+ }
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ }
+}
+
+function testCanvas(size) {
+ debug("");
+ debug("testing 2D canvas size " + size + ", " + size);
+
+ var canvas = document.createElement("canvas");
+ canvas.width = size;
+ canvas.height = size;
+ var ctx = canvas.getContext("2d");
+ ctx.fillStyle = "rgb(0,255,0)";
+ ctx.fillRect(0, 0, size, size);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+
+ fillInMips(gl, size);
+
+ // Draw. If this an HD-DPI device and the 2d canvas is double res or larger
+ // the implementation must scale to CSS pixels (ie, canvas.width, canvas.height)(
+ // when doing the copy in texImage2D. If it has not scaled and instead done
+ // a direct copy of the larger texture this test will not have created enough mips
+ // and will therefore not be "texture complete" and will render in black.
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+function testWebGL(size) {
+ debug("");
+ debug("testing WebGL canvas size " + size + ", " + size);
+
+ var canvas = document.createElement("canvas");
+ canvas.width = size;
+ canvas.height = size;
+ var gl2 = wtu.create3DContext(canvas);
+ gl2.clearColor(0,1,0,1);
+ gl2.clear(gl.COLOR_BUFFER_BIT);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+
+ fillInMips(gl, size);
+
+ // Draw. If this an HD-DPI device check for 2 possible bugs.
+ //
+ // 1) the WebGL canvas is double res or larger. That's just a bug period and
+ // is checked for in another test but would also fail here.
+ //
+ // 2) the WebGL canvas is single res but the code the scales a double res
+ // 2d canvas also mistakenly scales a single res WebGL canvas.
+ //
+ // If it has been scaled then we'll have the wrong kind of mips chain here.
+ // Level 0 will be half resolution. Level 1 will be the same resolution
+ // and will therefore not be "texture complete" and will render in black.
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
+}
+
+testCanvas(4);
+testCanvas(512);
+testWebGL(4);
+testWebGL(512);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-mips.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-mips.html
new file mode 100644
index 0000000000..6f038b8475
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-mips.html
@@ -0,0 +1,297 @@
+<!--
+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 texture mips conformance test.</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="example" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+uniform vec4 uMult;
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition * uMult;
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform sampler2D tex;
+varying vec2 texCoord;
+void main()
+{
+ gl_FragColor = texture2D(tex, texCoord);
+}
+</script>
+<script>
+"use strict";
+var canvas;
+var wtu = WebGLTestUtils;
+function init()
+{
+ description("Checks mip issues");
+
+ canvas = document.getElementById("example");
+ shouldBe("canvas.width", "2");
+ shouldBe("canvas.height", "2");
+
+ var gl = wtu.create3DContext(canvas);
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "for generateMipmap with mip 0 is 0x0");
+ gl.texImage2D(
+ gl.TEXTURE_2D, 1, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4));
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "for generateMipmap with mip 0 is 0x0");
+
+ tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "for generateMipmap with mip 0 is 0x0");
+
+ var faces = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+ for (var ii = 0; ii < faces.length; ++ii) {
+ gl.texImage2D(
+ faces[ii], 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE,
+ new Uint8Array(4 * 2 * 2));
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ wtu.glErrorShouldBe(gl, ii == 5 ? gl.NO_ERROR : gl.INVALID_OPERATION, "for generateMipmap with " + (ii + 1) + " faces");
+ }
+
+ wtu.setupUnitQuad(gl, 0, 1);
+ var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ var colors = {
+ blue: [0, 0, 255, 255],
+ red: [255, 0, 0, 255],
+ green: [0, 255, 0, 255],
+ cyan: [128, 255, 255, 255],
+ black: [0, 0, 0, 255],
+ blank: [0, 0, 0, 0]
+ };
+
+ var mips = [
+ ];
+
+ var texLoc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(texLoc, 0);
+ var multLoc = gl.getUniformLocation(program, "uMult");
+
+ // ----------------------------------------------------
+ var clearTex = createTexture();
+ gl.uniform4f(multLoc, 1, 1, 1, 1);
+ gl.bindTexture(gl.TEXTURE_2D, clearTex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ debug('gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);');
+ setMipData(0, 16, 'blank');
+ makeDivMipChain();
+ generateMipmap();
+ check('blank', "texture created with null that has all mips");
+
+ // ----------------------------------------------------
+ var tex = createTexture();
+ gl.uniform4f(multLoc, 1, 1, 1, 1);
+
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ // 16x16 texture no mips
+ fillLevel(tex, 0, 16, 'cyan');
+
+ check('black',
+ "texture that is missing mips when TEXTURE_MIN_FILTER not NEAREST or LINEAR");
+
+ generateMipmap();
+
+ check('cyan', "texture that has all mips");
+
+ // Fill in the bottom 2 mips with a different color.
+ fillLevel(tex, 4, 1, 'green');
+ fillLevel(tex, 3, 2, 'green');
+
+ // Choose the nearest mip
+ texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+
+ check('green', "texture that is only using the smallest 2 mips");
+
+ gl.uniform4f(multLoc, 16, 16, 1, 1);
+
+ check('cyan', "texture that is using only the largest 2 mips");
+
+ // Set the top level
+ fillLevel(tex, 0, 1, 'red');
+ check('red',
+ "texture that is only using the top level even though other levels are defined");
+
+ // Set the top 2 levels using generateMipmap
+ fillLevel(tex, 0, 2, 'blue');
+ generateMipmap();
+
+ check('blue',
+ "texture that is only using the top 2 levels even though other levels are defined");
+
+ // Set the top 2 levels back to sizes that end up using levels 2, 3, and 4 again.
+ fillLevel(tex, 0, 16, 'blue');
+ fillLevel(tex, 1, 8, 'blue');
+ check('blue', "texture that is only using the largest 2 mips");
+ gl.uniform4f(multLoc, 1, 1, 1, 1);
+ check('green', "texture that is only using the smallest 2 mips");
+
+ // ----------------------------------------------------
+ var tex = createTexture();
+ gl.uniform4f(multLoc, 1, 1, 1, 1);
+ fillLevel(tex, 0, 8, 'cyan');
+ generateMipmap();
+ check('cyan', "texture that has 3 mips");
+
+ fillLevel(tex, 0, 16, 'blue');
+ texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ check('blue', "texture that is only using top mips");
+
+ fillLevel(tex, 0, 8, 'red');
+ texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+ check('cyan', "texture that is only using smallest mips");
+
+ gl.uniform4f(multLoc, 16, 16, 1, 1);
+ check('red', "texture that is using only the largest mip");
+
+ // ----------------------------------------------------
+ var tex = createTexture();
+ gl.uniform4f(multLoc, 1, 1, 1, 1);
+ fillLevel(tex, 2, 1, 'green');
+ fillLevel(tex, 1, 2, 'green');
+ fillLevel(tex, 0, 4, 'green');
+ check('green', "texture that was built smallest mip first");
+
+ // ----------------------------------------------------
+ var tex = createTexture();
+ gl.uniform4f(multLoc, 1, 1, 1, 1);
+ fillLevel(tex, 0, 16, 'red');
+ generateMipmap();
+ check('red', "texture with 1 genmipmaps");
+ fillLevel(tex, 0, 16, 'blue');
+ generateMipmap();
+ fillLevel(tex, 0, 16, 'green');
+ generateMipmap();
+ check('green', "texture with 2 genmipmaps");
+
+ // ----------------------------------------------------
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+
+ function createTexture() {
+ debug("<hr/>gl.createTexture()");
+ mips = [];
+ makeDivMipChain();
+ return gl.createTexture();
+ }
+
+ function texParameteri(target, pname, value) {
+ debug("gl.texParameteri(" +
+ wtu.glEnumToString(gl, target) + ", " +
+ wtu.glEnumToString(gl, pname) + ", " +
+ wtu.glEnumToString(gl, value) + ")")
+ gl.texParameteri(target, pname, value);
+ }
+
+ function generateMipmap() {
+ debug("gl.generateMipmap(gl.TEXTURE_2D)");
+ gl.generateMipmap(gl.TEXTURE_2D);
+ var mip0 = mips[0];
+ var size = mip0.size;
+ var level = 1;
+ for(;;) {
+ size = Math.floor(size / 2);
+ if (!size) {
+ break;
+ }
+ setMipData(level, size, mip0.color);
+ ++level;
+ }
+ makeDivMipChain();
+ }
+
+ function check(color, msg) {
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, colors[color], msg + " should draw with " + color);
+ }
+
+ function fillLevel(tex, level, size, color) {
+ setMipData(level, size, color);
+ debug("gl.texImage2D(gl.TEXTURE_2D, " + level + ", gl.RGBA, " + size + ", " + size +
+ ", 0, gl.RGBA, gl.UNSIGNED_BYTE, " + color + ");");
+ wtu.fillTexture(gl, tex, size, size, colors[color], level);
+ makeDivMipChain();
+ }
+
+ function setMipData(level, size, color) {
+ mips[level] = {
+ size: size,
+ color: color
+ };
+ }
+
+ function makeDivMipChain(color) {
+ var html = [
+ '<div style="height: 68px; margin-top: 5px">',
+ '<div style="float:left;">mips: </div>'];
+ for (var ii = 0; ii < 5; ++ii) {
+ var mip = mips[ii];
+ if (mip) {
+ html.push(makeDivSquare(mip.size, mip.color));
+ } else {
+ html.push(makeDivSquare(16, undefined));
+ }
+ }
+ html.push("</div>");
+ debug(html.join(""));
+ }
+
+ function makeDivSquare(size, color) {
+ size *= 4;
+ var c = color ? colors[color] : [255,255,255];
+ var border = color ? 'solid' : 'dashed';
+ return '<div style="float:left; width: ' + size + 'px; height: ' + size +
+ 'px; background-color: ' + rgb(c) +
+ '; border: 1px ' + border + ' black; margin-right: 3px;"></div>';
+ }
+
+ function rgb(c) {
+ return 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] +')';
+ }
+}
+
+init();
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot-video.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot-video.html
new file mode 100644
index 0000000000..ef979d4c5a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot-video.html
@@ -0,0 +1,160 @@
+<!--
+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">
+<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>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = null;
+var textureLoc = null;
+var successfullyParsed = false;
+
+initTestingHarness();
+
+function logVisibility(isOnload)
+{
+ let prefix = '';
+ if (isOnload)
+ prefix = 'Upon load: ';
+ if (document.hidden) {
+ console.log(prefix + '*** Tab was backgrounded (if running in automated test harness, why?) ***');
+ } else {
+ console.log(prefix + 'Tab was foregrounded');
+ }
+}
+
+function init()
+{
+ description('Verify npot video');
+
+ document.addEventListener("visibilitychange", visibilityChanged, false);
+
+ logVisibility(true);
+
+ var canvas = document.getElementById("example");
+ gl = wtu.create3DContext(canvas);
+ var program = wtu.setupTexturedQuad(gl);
+
+ gl.clearColor(0,0,0,1);
+ gl.clearDepth(1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ // Disable any writes to the alpha channel
+ gl.colorMask(1, 1, 1, 0);
+
+ textureLoc = gl.getUniformLocation(program, "tex");
+
+ var video = document.getElementById("vid");
+ wtu.startPlayingAndWaitForVideo(video, runTest);
+}
+
+function visibilityChanged() {
+ logVisibility(false);
+}
+
+function runOneIteration(videoElement, useTexSubImage2D, flipY, topColor, bottomColor, badMinFilter, badClamp, genMips)
+{
+ debug('Testing ' + (useTexSubImage2D ? 'texSubImage2D' : 'texImage2D') +
+ ' with flipY=' + flipY);
+ var texture = gl.createTexture();
+ // Bind the texture to texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ // Set up pixel store parameters
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
+ // Upload the videoElement into the texture
+ debug("size: " + videoElement.videoWidth + "x" + videoElement.videoHeight);
+ if (useTexSubImage2D) {
+ // Initialize the texture to black first
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
+ videoElement.videoWidth, videoElement.videoHeight, 0,
+ gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
+ }
+
+ // Set up texture parameters
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ if (badMinFilter) {
+ debug("bad min filter");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+ } else {
+ debug("good min filter");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ }
+ if (badClamp) {
+ debug("bad clamp");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+ } else {
+ debug("good clamp");
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ }
+ if (genMips) {
+ debug("generate mips");
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should be INVALID_OPERATION");
+ }
+
+// var c = document.createElement("canvas");
+// c.width = 16;
+// c.height = 16;
+// c.style.border = "1px solid black";
+// var ctx = c.getContext("2d");
+// ctx.drawImage(videoElement, 0, 0, 16, 16);
+// document.body.appendChild(c);
+
+ // Point the uniform sampler to texture unit 0
+ gl.uniform1i(textureLoc, 0);
+ // Draw the triangles
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ // Check a few pixels near the top and bottom and make sure they have
+ // the right color.
+ var tolerance = 5;
+ debug("Checking lower left corner");
+ wtu.checkCanvasRect(gl, 4, 4, 2, 2, bottomColor,
+ "shouldBe " + bottomColor, tolerance);
+ debug("Checking upper left corner");
+ wtu.checkCanvasRect(gl, 4, gl.canvas.height - 8, 2, 2, topColor,
+ "shouldBe " + topColor, tolerance);
+ debug("");
+}
+
+function runTest(videoElement)
+{
+ var red = [255, 0, 0];
+ var green = [0, 255, 0];
+ var black = [0, 0, 0];
+ runOneIteration(videoElement, false, true, black, black, true, true, true);
+ runOneIteration(videoElement, false, true, black, black, true, false, false);
+ runOneIteration(videoElement, false, true, black, black, false, true, false);
+ runOneIteration(videoElement, false, true, black, black, true, true, false);
+ runOneIteration(videoElement, false, true, green, red, false, false, false);
+ runOneIteration(videoElement, false, false, red, green, false, false, false);
+ runOneIteration(videoElement, true, true, green, red, false, false, false);
+ runOneIteration(videoElement, true, false, red, green, false, false, false);
+
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ finishTest();
+}
+</script>
+</head>
+<body onload="init()">
+<canvas id="example" width="64" height="48"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<video id="vid" style="display:none;" muted>
+ <source src="../../../resources/npot-video.mp4" type='video/mp4; codecs="avc1.42E01E"' />
+ <source src="../../../resources/npot-video.webmvp8.webm" type='video/webm; codecs="vp8"' />
+ <source src="../../../resources/npot-video.theora.ogv" type='video/ogg; codecs="theora"' />
+</video>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot.html
new file mode 100644
index 0000000000..73ea4011f1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot.html
@@ -0,0 +1,305 @@
+<!--
+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 Non-Power of 2 texture conformance test.</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="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec2 texCoord0;
+varying vec2 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform samplerCube tex;
+varying vec2 texCoord;
+void main()
+{
+ gl_FragColor = textureCube(tex, normalize(vec3(texCoord, 1)));
+}
+</script>
+<script>
+"use strict";
+description(document.title);
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var program = wtu.setupTexturedQuad(gl);
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var tests = [
+ { format: gl.RGBA,
+ type: gl.UNSIGNED_BYTE,
+ color: [192, 0, 128, 64],
+ expected: [192, 0, 128, 64],
+ tolerance: 0,
+ },
+ { format: gl.RGB,
+ type: gl.UNSIGNED_BYTE,
+ color: [192, 0, 128],
+ expected: [192, 0, 128, 255],
+ tolerance: 0,
+ },
+ { format: gl.LUMINANCE,
+ type: gl.UNSIGNED_BYTE,
+ color: [192],
+ expected: [192, 192, 192, 255],
+ tolerance: 0,
+ },
+ { format: gl.ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ color: [64],
+ expected: [0, 0, 0, 64],
+ tolerance: 0,
+ },
+ { format: gl.LUMINANCE_ALPHA,
+ type: gl.UNSIGNED_BYTE,
+ color: [192, 64],
+ expected: [192, 192, 192, 64],
+ tolerance: 0,
+ },
+ // { format: gl.RGBA,
+ // type: gl.UNSIGNED_SHORT_4_4_4_4,
+ // color: [0x48FC],
+ // expected: [0x44, 0x88, 0xFF, 0xCC],
+ // tolerance: 16,
+ // },
+ // { format: gl.RGBA,
+ // type: gl.UNSIGNED_SHORT_5_5_5_1,
+ // color: [0x8309], // 10000 01000 00100 1
+ // expected: [128, 64, 32, 255],
+ // tolerance: 16,
+ // },
+ // { format: gl.RGB,
+ // type: gl.UNSIGNED_SHORT_5_6_5,
+ // color: [0x8404], // 10000 010000 00100
+ // expected: [128, 64, 32],
+ // tolerance: 16,
+ // },
+];
+
+tests.forEach(function(test) {
+ debug("");
+ debug("test " + wtu.glEnumToString(gl, test.format) + "/" + wtu.glEnumToString(gl, test.type));
+ var tex = gl.createTexture();
+
+ // Check that an NPOT texture not on level 0 generates INVALID_VALUE
+ wtu.fillTexture(gl, tex, 5, 3, test.color, 1, test.format, test.type);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "gl.texImage2D with NPOT texture with level > 0 should return INVALID_VALUE");
+
+ // Check that an NPOT texture on level 0 succeeds
+ wtu.fillTexture(gl, tex, 5, 3, test.color, 0, test.format, test.type);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D with NPOT texture at level 0 should succeed");
+
+ // Check that generateMipmap fails on NPOT
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "gl.generateMipmap with NPOT texture should return INVALID_OPERATION");
+
+ // Check that nothing is drawn if filtering is not correct for NPOT
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, [0, 0, 0, 255],
+ "NPOT texture with TEXTURE_WRAP set to REPEAT should draw with 0,0,0,255");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, [0, 0, 0, 255],
+ "NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, test.expected,
+ "NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw.");
+
+ gl.copyTexImage2D(gl.TEXTURE_2D, 1, test.format, 0, 0, 5, 3, 0);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "copyTexImage2D with NPOT texture with level > 0 should return INVALID_VALUE.");
+
+ // Check that generateMipmap for an POT texture succeeds
+ wtu.fillTexture(gl, tex, 4, 4, test.color, 0, test.format);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D and gl.generateMipmap with POT texture at level 0 should succeed");
+
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, test.expected,
+ "POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw.");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+});
+
+var testCubemap = function(switchTextureUnitBeforeDraw) {
+ debug("");
+ var title = "check using cubemap";
+ if (switchTextureUnitBeforeDraw) {
+ title += " and switch texture unit before draw to check for Chromium bug";
+ }
+ debug(title);
+ var program = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
+ var tex = gl.createTexture();
+
+ // Check that an NPOT texture not on level 0 generates INVALID_VALUE
+ fillCubeTexture(gl, tex, 5, 3, [0, 192, 128, 255], 1);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
+ "gl.texImage2D with NPOT texture with level > 0 should return INVALID_VALUE");
+
+ // Check that an NPOT texture on level 0 succeeds
+ fillCubeTexture(gl, tex, 5, 5, [0, 192, 128, 255]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D with NPOT texture at level 0 should succeed");
+
+ // Check that generateMipmap fails on NPOT
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
+ "gl.generateMipmap with NPOT texture should return INVALID_OPERATION");
+
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ // Check that nothing is drawn if filtering is not correct for NPOT
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+ if (switchTextureUnitBeforeDraw) {
+ debug("Switching active texture unit to gl.TEXTURE1");
+ // Test for http://crbug.com/390514
+ gl.activeTexture(gl.TEXTURE1);
+ }
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, [0, 0, 0, 255],
+ "NPOT cubemap with TEXTURE_WRAP set to REPEAT should draw with 0,0,0,255");
+
+ if (switchTextureUnitBeforeDraw) {
+ var error = gl.getError();
+ if (error === gl.NO_ERROR) {
+ testPassed("getError was expected value: NO_ERROR : Should be no errors from draw.");
+ } else if (error === gl.INVALID_ENUM) {
+ testFailed("getError returned INVALID_ENUM. Possibly Chromium bug where texture unit is set to 0 instead of GL_TEXTURE0.");
+ } else {
+ testFailed("Drawing resulted in error: " + wtu.glEnumToString(gl, error));
+ }
+ gl.activeTexture(gl.TEXTURE0);
+ } else {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from draw.");
+ }
+
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, [0, 0, 0, 255],
+ "NPOT cubemap with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255");
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, [0, 192, 128, 255],
+ "NPOT cubemap with TEXTURE_MIN_FILTER set to LINEAR should draw.");
+
+ // Check that an POT texture on level 0 succeeds
+ fillCubeTexture(gl, tex, 4, 4, [0, 192, 128, 255]);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.texImage2D with POT texture at level 0 should succeed");
+
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.REPEAT);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, [0, 0, 0, 255],
+ "POT cubemap with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR but no mips draw with 0,0,0,255");
+
+ // Check that generateMipmap succeeds on POT
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR,
+ "gl.generateMipmap with POT texture should return succeed");
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, [0, 192, 128, 255],
+ "POT cubemap with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw.");
+};
+
+testCubemap(false);
+testCubemap(true);
+
+var successfullyParsed = true;
+
+function fillCubeTexture(gl, tex, width, height, color, opt_level) {
+ opt_level = opt_level || 0;
+ var canvas = document.createElement('canvas');
+ canvas.width = width;
+ canvas.height = height;
+ var ctx2d = canvas.getContext('2d');
+ ctx2d.fillStyle = "rgba(" + color[0] + "," + color[1] + "," + color[2] + "," + color[3] + ")";
+ ctx2d.fillRect(0, 0, width, height);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ var targets = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
+ for (var tt = 0; tt < targets.length; ++tt) {
+ gl.texImage2D(
+ targets[tt], opt_level, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
+ }
+};
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-cube-maps.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-cube-maps.html
new file mode 100644
index 0000000000..c38d897e18
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-cube-maps.html
@@ -0,0 +1,331 @@
+<!--
+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 texture size cube map conformance test.</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="example" width="256" height="256" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+uniform mat4 rotation;
+varying vec3 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+ vec4 direction = vec4(vPosition.x * 0.5, vPosition.y * 0.5, 1, 1);
+ texCoord = normalize((rotation * direction).xyz);
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform samplerCube tex;
+varying vec3 texCoord;
+void main()
+{
+ gl_FragColor = textureCube(tex, normalize(texCoord));
+}
+</script>
+<script>
+"use strict";
+var canvas;
+description("Checks issues with size of cube map textures");
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+
+var gl = wtu.create3DContext(canvas);
+wtu.setupUnitQuad(gl, 0, 1);
+var program = wtu.setupProgram(
+ gl,
+ ['vshader', 'fshader'],
+ ['vPosition', 'texCoord0'], [0, 1]);
+var rotLoc = gl.getUniformLocation(program, "rotation");
+
+gl.disable(gl.DEPTH_TEST);
+gl.disable(gl.BLEND);
+
+var maxSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
+debug("max cube map size: " + maxSize);
+maxSize = Math.min(512, maxSize);
+
+// a cube map of 512x512 takes 6meg. I'm assuming it's not
+// unreasonable to expect to be able to allocate a 6meg texture
+
+var colors = [
+ {name: 'red', color: [255, 0, 0, 255]},
+ {name: 'green', color: [ 0, 255, 0, 255]},
+ {name: 'blue', color: [ 0, 0, 255, 255]},
+ {name: 'yellow', color: [255, 255, 0, 255]},
+ {name: 'cyan', color: [ 0, 255, 255, 255]},
+ {name: 'magenta', color: [255, 0, 255, 255]}
+];
+
+var targets = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
+
+var rotations = [
+ {axis: [0, 1, 0], angle: Math.PI / 2},
+ {axis: [0, 1, 0], angle: -Math.PI / 2},
+ {axis: [1, 0, 0], angle: -Math.PI / 2},
+ {axis: [1, 0, 0], angle: Math.PI / 2},
+ {axis: [0, 1, 0], angle: 0},
+ {axis: [0, 1, 0], angle: Math.PI},
+];
+
+var halfRotations = [
+ {colors: [3, 4], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4}]},
+ {colors: [4, 2], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4}]},
+ {colors: [5, 3], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4 * 3}]},
+ {colors: [2, 5], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4 * 3}]},
+ {colors: [3, 0], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
+ {axis: [1, 0, 0], angle: Math.PI / 4}]},
+ {colors: [0, 2], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
+ {axis: [1, 0, 0], angle: -Math.PI / 4}]},
+];
+
+var count = 0;
+var sizeCount = 0;
+
+test();
+
+function test() {
+ var size = Math.pow(2, sizeCount);
+ if (size > maxSize || !testSize(size)) {
+ finishTest();
+ } else {
+ ++sizeCount;
+ setTimeout(test, 0);
+ }
+}
+
+function testSize(size) {
+ debug("");
+ debug("testing size: " + size);
+ var canvasSize = Math.max(size / 4, 2);
+ canvas.width = canvasSize;
+ canvas.height = canvasSize;
+ gl.viewport(0, 0, canvasSize, canvasSize);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+
+ // Seems like I should be using LINEAR here with some other math
+ // to make sure I get more mip coverage but that's easier said
+ // than done.
+
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ for (var jj = 0; jj < 2; ++jj) {
+ for (var tt = 0; tt < targets.length; ++tt) {
+ var color = colors[(tt + count) % colors.length];
+ fillLevel(targets[tt], 0, size, color.color);
+ }
+ if (jj == 1) {
+ debug("use mipmap");
+ gl.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER,
+ gl.NEAREST_MIPMAP_NEAREST);
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ }
+
+ var err = gl.getError();
+ if (err == gl.OUT_OF_MEMORY) {
+ debug("out of memory");
+ return false;
+ }
+ if (err != gl.NO_ERROR) {
+ testFailed("unexpected gl error: " + wtu.glEnumToString(gl, err));
+ }
+
+
+ for (var rr = 0; rr < rotations.length; ++rr) {
+ var rot = rotations[rr];
+ var color = colors[(rr + count) % colors.length];
+ var rotMat = axisRotation(rot.axis, rot.angle);
+ gl.uniformMatrix4fv(rotLoc, false, rotMat);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, color.color,
+ wtu.glEnumToString(gl, targets[rr]) + " should be " + color.name);
+ }
+
+ for (var rr = 0; rr < halfRotations.length; ++rr) {
+ var h = halfRotations[rr];
+ var rots = h.rotations;
+ var rotMat = axisRotation(rots[0].axis, rots[0].angle);
+ for (var ii = 1; ii < rots.length; ++ii) {
+ var tmpMat = axisRotation(rots[ii].axis, rots[ii].angle);
+ var rotMat = mulMatrix(tmpMat, rotMat);
+ }
+ gl.uniformMatrix4fv(rotLoc, false, rotMat);
+ wtu.clearAndDrawUnitQuad(gl);
+
+ for (var ii = 0; ii < 2; ++ii) {
+ checkRect(
+ 0,
+ canvasSize / 2 * ii,
+ canvasSize,
+ canvasSize / 2,
+ colors[(h.colors[ii] + count) % colors.length]);
+ }
+ }
+ ++count;
+ }
+
+ gl.deleteTexture(tex);
+ return true;
+}
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+
+function checkRect(x, y, width, height, color) {
+ wtu.checkCanvasRect(
+ gl,
+ x,
+ y,
+ width,
+ height,
+ color.color,
+ "" + x + ", " + y + ", " + width + ", " + height +
+ " should be " + color.name);
+}
+
+function fillLevel(target, level, size, color) {
+ var numPixels = size * size;
+ var pixels = new Uint8Array(numPixels * 4);
+ var pixelRow = new Uint8Array(size * 4);
+ for (var jj = 0; jj < size; ++jj) {
+ var off = jj * 4;
+ pixelRow[off + 0] = color[0];
+ pixelRow[off + 1] = color[1];
+ pixelRow[off + 2] = color[2];
+ pixelRow[off + 3] = color[3];
+ }
+ for (var jj = 0; jj < size; ++jj) {
+ var off = jj * size * 4;
+ pixels.set(pixelRow, off);
+ }
+ gl.texImage2D(
+ target, level, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE,
+ pixels);
+}
+
+function printMat(mat) {
+ debug("" + mat[0] + ", " + mat[1] + ", " + mat[2] + ", " + mat[3] + ", ");
+ debug("" + mat[4] + ", " + mat[5] + ", " + mat[6] + ", " + mat[7] + ", ");
+ debug("" + mat[8] + ", " + mat[9] + ", " + mat[10] + ", " + mat[11] + ", ");
+ debug("" + mat[12] + ", " + mat[13] + ", " + mat[14] + ", " + mat[15] + ", ");
+}
+
+function axisRotation(axis, angle) {
+ var dst = new Float32Array(16);
+ var x = axis[0];
+ var y = axis[1];
+ var z = axis[2];
+ var n = Math.sqrt(x * x + y * y + z * z);
+ x /= n;
+ y /= n;
+ z /= n;
+ var xx = x * x;
+ var yy = y * y;
+ var zz = z * z;
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ var oneMinusCosine = 1 - c;
+
+ dst[ 0] = xx + (1 - xx) * c;
+ dst[ 1] = x * y * oneMinusCosine + z * s;
+ dst[ 2] = x * z * oneMinusCosine - y * s;
+ dst[ 3] = 0;
+ dst[ 4] = x * y * oneMinusCosine - z * s;
+ dst[ 5] = yy + (1 - yy) * c;
+ dst[ 6] = y * z * oneMinusCosine + x * s;
+ dst[ 7] = 0;
+ dst[ 8] = x * z * oneMinusCosine + y * s;
+ dst[ 9] = y * z * oneMinusCosine - x * s;
+ dst[10] = zz + (1 - zz) * c;
+ dst[11] = 0;
+ dst[12] = 0;
+ dst[13] = 0;
+ dst[14] = 0;
+ dst[15] = 1;
+
+ return dst;
+};
+
+function mulMatrix(a, b) {
+ var dst = new Float32Array(16);
+ var a00 = a[0];
+ var a01 = a[1];
+ var a02 = a[2];
+ var a03 = a[3];
+ var a10 = a[ 4 + 0];
+ var a11 = a[ 4 + 1];
+ var a12 = a[ 4 + 2];
+ var a13 = a[ 4 + 3];
+ var a20 = a[ 8 + 0];
+ var a21 = a[ 8 + 1];
+ var a22 = a[ 8 + 2];
+ var a23 = a[ 8 + 3];
+ var a30 = a[12 + 0];
+ var a31 = a[12 + 1];
+ var a32 = a[12 + 2];
+ var a33 = a[12 + 3];
+ var b00 = b[0];
+ var b01 = b[1];
+ var b02 = b[2];
+ var b03 = b[3];
+ var b10 = b[ 4 + 0];
+ var b11 = b[ 4 + 1];
+ var b12 = b[ 4 + 2];
+ var b13 = b[ 4 + 3];
+ var b20 = b[ 8 + 0];
+ var b21 = b[ 8 + 1];
+ var b22 = b[ 8 + 2];
+ var b23 = b[ 8 + 3];
+ var b30 = b[12 + 0];
+ var b31 = b[12 + 1];
+ var b32 = b[12 + 2];
+ var b33 = b[12 + 3];
+ dst[ 0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
+ dst[ 1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
+ dst[ 2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
+ dst[ 3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
+ dst[ 4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
+ dst[ 5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
+ dst[ 6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
+ dst[ 7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
+ dst[ 8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
+ dst[ 9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
+ dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
+ dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
+ dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
+ dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
+ dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
+ dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
+ return dst;
+};
+</script>
+</body>
+</html>
+
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-limit.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-limit.html
new file mode 100644
index 0000000000..3e093b3a53
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-limit.html
@@ -0,0 +1,167 @@
+<!--
+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 texture size limit conformance test.</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="example" width="32" height="32" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description("Checks various size limits of textures")
+var canvas;
+
+function numLevelsFromSize(size) {
+ var levels = 0;
+ while ((size >> levels) > 0) {
+ ++levels;
+ }
+ return levels;
+}
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var tests = [
+ { format: gl.ALPHA, type: gl.UNSIGNED_BYTE, size: 1, dataType: Uint8Array },
+ { format: gl.LUMINANCE, type: gl.UNSIGNED_BYTE, size: 1, dataType: Uint8Array },
+ { format: gl.LUMINANCE_ALPHA, type: gl.UNSIGNED_BYTE, size: 2, dataType: Uint8Array },
+ { format: gl.RGB, type: gl.UNSIGNED_BYTE, size: 3, dataType: Uint8Array },
+ { format: gl.RGB, type: gl.UNSIGNED_SHORT_5_6_5, size: 1, dataType: Uint16Array },
+ { format: gl.RGBA, type: gl.UNSIGNED_BYTE, size: 4, dataType: Uint8Array },
+ { format: gl.RGBA, type: gl.UNSIGNED_SHORT_4_4_4_4, size: 1, dataType: Uint16Array },
+ { format: gl.RGBA, type: gl.UNSIGNED_SHORT_5_5_5_1, size: 1, dataType: Uint16Array }
+];
+
+// Note: We expressly only use 2 textures because first a texture will be defined
+// using all mip levels of 1 format, then for a moment it will have mixed formats which
+// may uncover bugs.
+var targets = [
+ { target: gl.TEXTURE_2D,
+ maxSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
+ maxLevel: 1000,
+ targets: [gl.TEXTURE_2D]
+ },
+ { target: gl.TEXTURE_CUBE_MAP,
+ maxSize: gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE),
+ maxLevel: 5,
+ targets: [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ]
+ }
+];
+
+gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+var trg = 0;
+var tt = 0;
+var tex = null;
+runNextTest();
+
+function runNextTest() {
+ var t = targets[trg];
+
+ if (tt == 0) {
+ gl.deleteTexture(tex);
+ tex = gl.createTexture();
+ gl.bindTexture(t.target, tex);
+
+ debug("");
+ debug("max size for " + wtu.glEnumToString(gl, t.target) + ": " + t.maxSize);
+ var numLevels = numLevelsFromSize(t.maxSize);
+ debug("num levels " + numLevels);
+ }
+
+ var test = tests[tt];
+ testFormatType(t, test);
+ ++tt;
+ if (tt == tests.length) {
+ tt = 0;
+ ++trg;
+ if (trg == targets.length) {
+ finishTest();
+ return;
+ }
+ }
+ wtu.dispatchPromise(runNextTest);
+}
+
+function testFormatType(t, test) {
+ debug("");
+ debug("testing: " + wtu.glEnumToString(gl, test.format) + ", " + wtu.glEnumToString(gl, test.type));
+
+ for (var j = 0; j < t.targets.length; ++j) {
+ var target = t.targets[j];
+ debug("");
+ debug(wtu.glEnumToString(gl, target));
+ var numLevels = numLevelsFromSize(t.maxSize);
+
+ // out of bounds tests
+ for (var i = 0; i < numLevels; i++) {
+ // width and height out of bounds
+ var size = t.maxSize >> i;
+ gl.texImage2D(target, i, test.format, size + 1, size + 1, 0, test.format, test.type, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "width or height out of bounds: should generate INVALID_VALUE: level is " + i + ", size is "
+ + (size + 1) + "x" + (size + 1));
+ }
+ // level out of bounds
+ gl.texImage2D(target, numLevels, test.format, 1, 1, 0, test.format, test.type, null);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "level out of bounds: should generate INVALID_VALUE: level is: "
+ + numLevels + ", size is 1x1.");
+
+ // Probe to discover the max non-OOM level.
+ // For instance, on some drivers (at least Intel+Mesa) we can create
+ // a maxLevel L8 texture, but only a maxLevel-1 RGB8 texture.
+ var maxLevelsForFormat = numLevels;
+ while (true) {
+ gl.texImage2D(target, maxLevelsForFormat-1, test.format, 1, 1, 0, test.format, test.type, null);
+ var err = gl.getError();
+ if (err == gl.OUT_OF_MEMORY) {
+ debug("Probe failed for level=" + (maxLevelsForFormat-1) + ", reducing...");
+ maxLevelsForFormat -= 1;
+ if (!maxLevelsForFormat) {
+ testFailed("Failed to allocate any levels for format " + test.format);
+ return;
+ }
+ continue;
+ }
+ if (err) {
+ testFailed("Should not hit non-OOM errors during max level probing.");
+ return;
+ }
+ break;
+ }
+ var numTestLevels = Math.min(maxLevelsForFormat, t.maxLevel);
+ for (var l = 0; l < numTestLevels; ++l) {
+ // Do bottom levels first;
+ var size = 1 << l;
+ var level = maxLevelsForFormat - l - 1;
+ var otherDimension = t.target == gl.TEXTURE_2D ? 1 : size;
+ gl.texImage2D(target, level, test.format, size, otherDimension, 0, test.format, test.type, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no error for level: " + level + " " + size + "x" + otherDimension);
+ if (otherDimension != size) {
+ gl.texImage2D(target, level, test.format, otherDimension, size, 0, test.format, test.type, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no error for level: " + level + " " + otherDimension + "x" + size);
+ }
+ }
+ }
+}
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size.html
new file mode 100644
index 0000000000..12d99ac89f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size.html
@@ -0,0 +1,217 @@
+<!--
+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 texture size conformance test.</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="example" width="32" height="32" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+attribute vec3 texCoord0;
+varying vec3 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+ texCoord = texCoord0;
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform samplerCube tex;
+varying vec3 texCoord;
+void main()
+{
+ gl_FragColor = textureCube(tex, normalize(texCoord));
+}
+</script>
+<script>
+"use strict";
+description("Checks that various sizes of textures render")
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+var program2D = wtu.setupTexturedQuad(gl);
+var programCubeMap = wtu.setupProgram(
+ gl, ['vshader', 'fshader'], ['vPosition', 'texCoord0'], [0, 1]);
+gl.disable(gl.DEPTH_TEST);
+gl.disable(gl.BLEND);
+var tex = gl.createTexture();
+var max2DSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
+var maxCubeMapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
+debug("MAX_TEXTURE_SIZE:" + max2DSize);
+debug("MAX_CUBE_MAP_TEXTURE_SIZE:" + maxCubeMapSize);
+// Assuming 2048x2048xRGBA (22meg with mips) will run on all WebGL platforms
+var max2DSquareSize = Math.min(max2DSize, 2048);
+// I'd prefer this to be 2048 but that's 16meg x 6 faces or 128meg (with mips)
+// 1024 is 33.5 meg (with mips)
+var maxCubeMapSize = Math.min(maxCubeMapSize, 1024);
+
+var colors = [
+ { name: "green", rgba: [0, 0, 255, 255] },
+ { name: "red", rgba: [255, 0, 0, 255] },
+ { name: "blue", rgba: [0, 255, 0, 255] },
+ { name: "yellow", rgba: [255, 255, 0, 255] },
+ { name: "magenta", rgba: [255, 0, 255, 255] },
+ { name: "cyan", rgba: [0, 255, 255, 255] }
+];
+
+var count = 0;
+var power = 0;
+runTest();
+
+function runTest() {
+ function doTest() {
+ var size = Math.pow(2, power);
+ if (size > max2DSize) {
+ return false;
+ }
+ gl.useProgram(program2D);
+ if (!checkTexture(size, 1, false)) return false;
+ if (!checkTexture(1, size, false)) return false;
+ if (size <= max2DSquareSize) {
+ if (!checkTexture(size, size, false)) {
+ return false;
+ }
+ }
+ if (size <= maxCubeMapSize) {
+ gl.useProgram(programCubeMap);
+ if (!checkTexture(size, size, true)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (doTest()) {
+ ++power;
+ setTimeout(runTest, 0);
+ } else {
+ finishTest();
+ }
+}
+
+function checkTexture(width, height, cubeMap) {
+ debug("");
+ count = (count + 1) % colors.length;
+ var color = colors[count];
+ var tex = gl.createTexture();
+ var target = cubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;
+ var type = cubeMap ? "cube map" : "2D texture";
+ debug("check " + width + ", " + height + " " + type);
+ gl.bindTexture(target, tex);
+ gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ fillLevel(0, width, height, color.rgba, cubeMap);
+ var err = gl.getError();
+ if (err == gl.OUT_OF_MEMORY) {
+ debug("out of memory");
+ return false;
+ }
+ if (err != gl.NO_ERROR) {
+ testFailed("unexpected gl error: " + wtu.glEnumToString(gl, err));
+ }
+ wtu.clearAndDrawUnitQuad(gl);
+ var tolerance = 3;
+ wtu.checkCanvas(gl, color.rgba,
+ type + " of size " + width + "x" + height + " with no mips should draw with " + color.name,
+ tolerance);
+ count = (count + 1) % colors.length;
+ color = colors[count];
+ fillLevel(0, width, height, color.rgba, cubeMap);
+ gl.generateMipmap(target);
+ var err = gl.getError();
+ if (err == gl.OUT_OF_MEMORY) {
+ debug("out of memory");
+ return false;
+ }
+ if (err != gl.NO_ERROR) {
+ testFailed("unexpected gl error: " + wtu.glEnumToString(gl, err));
+ }
+ gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, color.rgba,
+ type + " of size " + width + "x" + height + " with mips should draw with " + color.name,
+ tolerance);
+
+ count = (count + 1) % colors.length;
+ color = colors[count];
+ fillLevel(0, width, height, color.rgba, cubeMap, true);
+ gl.generateMipmap(target);
+
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(gl, color.rgba,
+ type + " of size " + width + "x" + height + " with mips should draw with " + color.name,
+ tolerance);
+
+ gl.deleteTexture(tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+ return true;
+}
+
+function fillLevel(level, width, height, color, opt_cubemap, opt_subTex) {
+ var numPixels = width * height;
+ var pixels = null;
+ var largeDim = Math.max(width, height);
+ var smallDim = Math.min(width, height);
+
+ var pixelRow = new Uint8Array(largeDim * 4);
+ for (var jj = 0; jj < largeDim; ++jj) {
+ var off = jj * 4;
+ pixelRow[off + 0] = color[0];
+ pixelRow[off + 1] = color[1];
+ pixelRow[off + 2] = color[2];
+ pixelRow[off + 3] = color[3];
+ }
+
+ if (largeDim == numPixels) {
+ pixels = pixelRow;
+ } else {
+ var pixels = new Uint8Array(numPixels * 4);
+ for (var jj = 0; jj < smallDim; ++jj) {
+ var off = jj * largeDim * 4;
+ pixels.set(pixelRow, off);
+ }
+ }
+
+ var targets = opt_cubemap ? [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] :
+ [gl.TEXTURE_2D];
+
+ for (var ii = 0; ii < targets.length; ++ii) {
+ // debug(wtu.glEnumToString(gl, targets[ii]));
+ var index = (ii + power) % targets.length;
+ var target = targets[index];
+ if (opt_subTex) {
+ gl.texSubImage2D(
+ target, level, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE,
+ pixels);
+ } else {
+ gl.texImage2D(
+ target, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
+ pixels);
+ }
+ }
+}
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-srgb-upload.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-srgb-upload.html
new file mode 100644
index 0000000000..3508670563
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-srgb-upload.html
@@ -0,0 +1,253 @@
+<!--
+Copyright (c) 2022 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>Upload texture from video into srgb internalformats</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>
+ <div id="description"></div>
+ <div id="console"></div>
+ <div>
+ Video:
+ <canvas id="e_rgba" width="300" height="200"></canvas>
+ 0x7f: <canvas id="e_rgba_color" width="30" height="200"></canvas>
+ <div>GL.RGBA</div>
+ </div>
+ <hr>
+ <div>
+ Video:
+ <canvas id="e_srgb8" width="300" height="200"></canvas>
+ 0x7f: <canvas id="e_srgb8_color" width="30" height="200"></canvas>
+ <div>GL.SRGB8</div>
+ </div>
+ <hr>
+ <div>
+ Video:
+ <canvas id="e_srgb8_alpha8" width="300" height="200"></canvas>
+ 0x7f: <canvas id="e_srgb8_alpha8_color" width="30" height="200"></canvas>
+ <div>GL.SRGB8_ALPHA8</div>
+ </div>
+<script>
+"use strict";
+const wtu = WebGLTestUtils;
+description();
+
+const DATA_URL_FOR_720p_png_bt709_bt709_tv_yuv420p_vp9_webm = '\
+data:video/webm;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEA\
+AAAAAAMBEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHGTbuMU6uEElTDZ1OsggElTbuMU6u\
+EHFO7a1OsggLr7AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmoCrXsYMPQ\
+kBNgIRMYXZmV0GETGF2ZkSJiEBEAAAAAAAAFlSua9quAQAAAAAAAFHXgQFzxYgAAAAAAAAAAZyBACK1\
+nIN1bmSGhVZfVlA5g4EBI+ODhAJiWgDgAQAAAAAAAB6wggUAuoIC0JqBAlWwkFW6gQFVsYEBVbuBAVW\
+5gQESVMNn43NzAQAAAAAAAFljwItjxYgAAAAAAAAAAWfIAQAAAAAAABxFo4dFTkNPREVSRIePTGF2Yy\
+BsaWJ2cHgtdnA5Z8iiRaOIRFVSQVRJT05Eh5QwMDowMDowMC4wNDAwMDAwMDAAAB9DtnVBWOeBAKNBU\
+oEAAICCSYNCQE/wLPYAOCQcGAAYAFB/N9H/HZUjnnscu9GvIJt3936AAAAAACh4E4g/fJ8GmILlgmQ6\
+iUMwWlrCvdZpJAjY24ONeWCZEIrug5k4YTeAAAAAaXgTiD98nwaYguWCZDq6Zy9PLtRqFgTRRWpDzEC\
+RrKr8wtgzCibnQJwWtOOaHH9ZRjl4+aOQHHoHk/YUdplRSYiwuJO6LIyUXumq92uzm/wLAqBN0N9kRR\
+evcxyTv6VcsFqLJ5W5INE4AAAAAGN4E3vgaWsaGceNeWlTmlA/W7BnrSNUEx9X/o/hlK8PPDCgN5Kpw\
+0gRJkKtiMQMtYO7DQAUWLnf3+GjIUUj4hiAGdY+FNLJIdswhZLCeSDQfqV1btKL/ns57OfXQc0R3HFz\
+YyB4E3vgaWsaGceNeWjppQzBaWtIcWVNbYO5ARh7kHkq6WBosnlbkfoAHFO7a5G7j7OBALeK94EB8YI\
+BjfCBAw==';
+
+function invoke(fn) { return fn(); }
+
+invoke(async () => {
+ const video = document.createElement("video");
+ video.src = DATA_URL_FOR_720p_png_bt709_bt709_tv_yuv420p_vp9_webm;
+ //video.src = "Big_Buck_Bunny_360_10s_1MB.mp4";
+ //video.src = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";
+ video.muted = true;
+ video.loop = true;
+ video.crossOrigin = "anonymous";
+ await video.play();
+
+ function renderTex(canvas, fn_tex_image) {
+ const gl = canvas.gl = wtu.create3DContext(canvas);
+
+ const vs = `
+attribute float a_VertexID;
+varying vec2 v_uv;
+void main() {
+ float id = a_VertexID;
+ v_uv.x = mod(id, 2.0);
+ id -= v_uv.x;
+ id /= 2.0;
+ v_uv.y = mod(id, 2.0);
+ gl_Position = vec4(2.0 * v_uv - 1.0, 0, 1);
+}`;
+
+ const fs = `
+precision mediump float;
+uniform sampler2D tex;
+varying vec2 v_uv;
+void main() {
+ gl_FragColor = texture2D(tex, v_uv);
+}`;
+
+ const program = gl.createProgram();
+ let shader = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(shader, vs);
+ gl.compileShader(shader);
+ gl.attachShader(program, shader);
+ shader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(shader, fs);
+ gl.compileShader(shader);
+ gl.attachShader(program, shader);
+ gl.bindAttribLocation(program, 0, 'a_VertexID');
+ gl.linkProgram(program);
+ gl.useProgram(program);
+ if (gl.getError()) throw 'Error during linking';
+
+ const vbuf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbuf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,1,2,3]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+
+ const texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ const draw = function() {
+ //requestAnimationFrame(draw);
+ fn_tex_image(gl);
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ };
+ draw();
+
+ if (gl.getError()) throw 'Error during drawing';
+ }
+
+ const GL = WebGL2RenderingContext;
+ const COLOR_DATA = new Uint8Array([127, 127, 127, 255]);
+
+ function internalformat_webgl1or2(gl, internalformat_name) {
+ let internalformat = gl[internalformat_name];
+ if (!internalformat) {
+ const ext = gl.getExtension('EXT_srgb');
+ if (!ext) {
+ testPassed('EXT_srgb not supported. (ok!)');
+ return;
+ }
+ switch (internalformat_name) {
+ case 'SRGB8':
+ internalformat = ext.SRGB_EXT;
+ break;
+ case 'SRGB8_ALPHA8':
+ internalformat = ext.SRGB_ALPHA_EXT;
+ break;
+ default:
+ throw internalformat_name;
+ }
+ }
+ return internalformat;
+ }
+
+ function begin(e_video, e_color, internalformat_name, unpackformat) {
+ renderTex(e_video, gl => {
+ const internalformat = internalformat_webgl1or2(gl, internalformat_name);
+ if (!gl.SRGB8) {
+ unpackformat = internalformat; // Must match in webgl1.
+ }
+ gl.texImage2D(GL.TEXTURE_2D, 0, internalformat,
+ unpackformat, GL.UNSIGNED_BYTE, video);
+ });
+ renderTex(e_color, gl => {
+ const internalformat = internalformat_webgl1or2(gl, internalformat_name);
+ if (!gl.SRGB8) {
+ unpackformat = internalformat; // Must match in webgl1.
+ }
+ gl.texImage2D(GL.TEXTURE_2D, 0, internalformat, 1, 1, 0,
+ unpackformat, GL.UNSIGNED_BYTE, COLOR_DATA);
+ });
+ }
+
+ begin(e_rgba, e_rgba_color, 'RGBA', GL.RGBA);
+ begin(e_srgb8, e_srgb8_color, 'SRGB8', GL.RGB);
+ begin(e_srgb8_alpha8, e_srgb8_alpha8_color, 'SRGB8_ALPHA8', GL.RGBA);
+
+ // -
+
+ const GREY50_COLOR_COORD = {
+ x: 0,
+ y: 0,
+ };
+ const GREY50_TEX_COORD = {
+ x: e_rgba.width/2 + 1,
+ y: e_rgba.height/2 + 1,
+ };
+ const fn_test = (canvas, coord, data) => {
+ wtu.checkCanvasRect(canvas.gl, coord.x, coord.y, 1, 1, data,
+ `${canvas.id} @${JSON.stringify(coord)}`);
+ }
+
+ debug('');
+ debug('e_rgba');
+ fn_test(e_rgba_color, GREY50_COLOR_COORD, [0x7f, 0x7f, 0x7f, 0xff]);
+ fn_test(e_rgba, GREY50_TEX_COORD, [0x7f, 0x7f, 0x7f, 0xff]);
+
+ debug('');
+ debug('e_srgb8');
+ fn_test(e_srgb8_color, GREY50_COLOR_COORD, [0x36, 0x36, 0x36, 0xff]);
+ fn_test(e_srgb8, GREY50_TEX_COORD, [0x36, 0x36, 0x36, 0xff]);
+
+ debug('');
+ debug('e_srgb8_alpha8');
+ fn_test(e_srgb8_alpha8_color, GREY50_COLOR_COORD, [0x36, 0x36, 0x36, 0xff]);
+ fn_test(e_srgb8_alpha8, GREY50_TEX_COORD, [0x36, 0x36, 0x36, 0xff]);
+
+ finishTest();
+});
+
+/*
+async function blobToDataURL(blob) {
+ const fr = new FileReader();
+ return await new Promise((yes, no) => {
+ fr.addEventListener('loadend', ev => {
+ if (fr.result) {
+ return yes(fr.result);
+ }
+ return no(fr.error);
+ });
+ fr.readAsDataURL(blob);
+ });
+}
+
+async function fetchDataUrl(url, wrapAt) {
+ const r = await fetch(url);
+ const b = await r.blob();
+ const durl = await blobToDataURL(b);
+ return durl;
+}
+
+function wrapLines(str, wrapAt) {
+ const lines = [];
+ let remaining = str;
+ while (remaining) {
+ lines.push(remaining.slice(0, wrapAt));
+ remaining = remaining.slice(wrapAt);
+ }
+ return lines;
+}
+
+(async () => {
+ const url = '720p.png.bt709.bt709.tv.yuv420p.vp9.webm';
+ const ident = 'DATA_URL_FOR_' + url.replaceAll('.', '_');
+ const durl = await fetchDataUrl(url);
+ const lines = wrapLines(durl, 79);
+ console.log(ident, '= \'\\\n' + lines.join('\\\n') + '\';');
+})();
+*/
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-sub-image-cube-maps.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-sub-image-cube-maps.html
new file mode 100644
index 0000000000..ca5740766a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-sub-image-cube-maps.html
@@ -0,0 +1,316 @@
+<!--
+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 texture texSubImage2Ds cube map conformance test.</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="example" width="256" height="256" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script id="vshader" type="x-shader/x-vertex">
+attribute vec4 vPosition;
+uniform mat4 rotation;
+varying vec3 texCoord;
+void main()
+{
+ gl_Position = vPosition;
+ vec4 direction = vec4(vPosition.x * 0.5, vPosition.y * 0.5, 1, 1);
+ texCoord = normalize((rotation * direction).xyz);
+}
+</script>
+
+<script id="fshader" type="x-shader/x-fragment">
+precision mediump float;
+uniform samplerCube tex;
+varying vec3 texCoord;
+void main()
+{
+ gl_FragColor = textureCube(tex, normalize(texCoord));
+}
+</script>
+<script>
+"use strict";
+var canvas;
+description("Checks issues with size of cube map textures");
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+
+var gl = wtu.create3DContext(canvas);
+wtu.setupUnitQuad(gl, 0, 1);
+var program = wtu.setupProgram(
+ gl,
+ ['vshader', 'fshader'],
+ ['vPosition', 'texCoord0'], [0, 1]);
+var rotLoc = gl.getUniformLocation(program, "rotation");
+
+var size = 16;
+
+var colors = [
+ {name: 'red', color: [255, 0, 0, 255]},
+ {name: 'green', color: [ 0, 255, 0, 255]},
+ {name: 'blue', color: [ 0, 0, 255, 255]},
+ {name: 'yellow', color: [255, 255, 0, 255]},
+ {name: 'cyan', color: [ 0, 255, 255, 255]},
+ {name: 'magenta', color: [255, 0, 255, 255]}
+];
+
+var targets = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
+
+var rotations = [
+ {axis: [0, 1, 0], angle: Math.PI / 2},
+ {axis: [0, 1, 0], angle: -Math.PI / 2},
+ {axis: [1, 0, 0], angle: -Math.PI / 2},
+ {axis: [1, 0, 0], angle: Math.PI / 2},
+ {axis: [0, 1, 0], angle: 0},
+ {axis: [0, 1, 0], angle: Math.PI},
+];
+
+var halfRotations = [
+ {colors: [3, 4], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4}]},
+ {colors: [4, 2], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4}]},
+ {colors: [5, 3], rotations: [{axis: [1, 0, 0], angle: Math.PI / 4 * 3}]},
+ {colors: [2, 5], rotations: [{axis: [1, 0, 0], angle: -Math.PI / 4 * 3}]},
+ {colors: [3, 0], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
+ {axis: [1, 0, 0], angle: Math.PI / 4}]},
+ {colors: [0, 2], rotations: [{axis: [0, 1, 0], angle: Math.PI / 2},
+ {axis: [1, 0, 0], angle: -Math.PI / 4}]},
+];
+
+var count = 0;
+testSize(size);
+
+function testSize(size) {
+ debug("");
+ debug("testing size: " + size);
+ var canvasSize = Math.max(size / 4, 2);
+ canvas.width = canvasSize;
+ canvas.height = canvasSize;
+ gl.viewport(0, 0, canvasSize, canvasSize);
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+
+ // Seems like I should be using LINEAR here with some other math
+ // to make sure I get more mip coverage but that's easier said
+ // than done.
+
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ for (var jj = 0; jj < 2; ++jj) {
+ for (var tt = 0; tt < targets.length; ++tt) {
+ var color = colors[(tt + count) % colors.length];
+ fillLevel(targets[tt], 0, size, color.color);
+ }
+ if (jj == 1) {
+ debug("use mipmap");
+ gl.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER,
+ gl.NEAREST_MIPMAP_NEAREST);
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ }
+
+ var err = gl.getError();
+ if (err == gl.OUT_OF_MEMORY) {
+ debug("out of memory");
+ return false;
+ }
+ if (err != gl.NO_ERROR) {
+ testFailed("unexpected gl error: " + wtu.glEnumToString(gl, err));
+ }
+
+
+ for (var rr = 0; rr < rotations.length; ++rr) {
+ var rot = rotations[rr];
+ var color = colors[(rr + count) % colors.length];
+ var rotMat = axisRotation(rot.axis, rot.angle);
+ gl.uniformMatrix4fv(rotLoc, false, rotMat);
+ wtu.clearAndDrawUnitQuad(gl);
+ wtu.checkCanvas(
+ gl, color.color,
+ wtu.glEnumToString(gl, targets[rr]) + " should be " + color.name);
+ }
+
+ for (var rr = 0; rr < halfRotations.length; ++rr) {
+ var h = halfRotations[rr];
+ var rots = h.rotations;
+ var rotMat = axisRotation(rots[0].axis, rots[0].angle);
+ for (var ii = 1; ii < rots.length; ++ii) {
+ var tmpMat = axisRotation(rots[ii].axis, rots[ii].angle);
+ var rotMat = mulMatrix(tmpMat, rotMat);
+ }
+ gl.uniformMatrix4fv(rotLoc, false, rotMat);
+ wtu.clearAndDrawUnitQuad(gl);
+
+ for (var ii = 0; ii < 2; ++ii) {
+ checkRect(
+ 0,
+ canvasSize / 2 * ii,
+ canvasSize,
+ canvasSize / 2,
+ colors[(h.colors[ii] + count) % colors.length]);
+ }
+ }
+ ++count;
+ }
+
+ gl.deleteTexture(tex);
+ return true;
+}
+
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+
+function checkRect(x, y, width, height, color) {
+ wtu.checkCanvasRect(
+ gl,
+ x,
+ y,
+ width,
+ height,
+ color.color,
+ "" + x + ", " + y + ", " + width + ", " + height +
+ " should be " + color.name);
+}
+
+function fillLevel(target, level, size, color) {
+ var numPixels = size * size;
+ var halfPixelRow = new Uint8Array(size * 2);
+ for (var jj = 0; jj < size; ++jj) {
+ var off = jj * 4;
+ halfPixelRow[off + 0] = color[0];
+ halfPixelRow[off + 1] = color[1];
+ halfPixelRow[off + 2] = color[2];
+ halfPixelRow[off + 3] = color[3];
+ }
+ gl.texImage2D(
+ target, level, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE,
+ null);
+ for (var jj = 0; jj < size; ++jj) {
+ gl.texSubImage2D(
+ target, level, 0, jj, size / 2, 1, gl.RGBA, gl.UNSIGNED_BYTE, halfPixelRow);
+ gl.texSubImage2D(
+ target, level, size / 2, jj, size / 2, 1, gl.RGBA, gl.UNSIGNED_BYTE, halfPixelRow);
+ }
+}
+
+function printMat(mat) {
+ debug("" + mat[0] + ", " + mat[1] + ", " + mat[2] + ", " + mat[3] + ", ");
+ debug("" + mat[4] + ", " + mat[5] + ", " + mat[6] + ", " + mat[7] + ", ");
+ debug("" + mat[8] + ", " + mat[9] + ", " + mat[10] + ", " + mat[11] + ", ");
+ debug("" + mat[12] + ", " + mat[13] + ", " + mat[14] + ", " + mat[15] + ", ");
+}
+
+function axisRotation(axis, angle) {
+ var dst = new Float32Array(16);
+ var x = axis[0];
+ var y = axis[1];
+ var z = axis[2];
+ var n = Math.sqrt(x * x + y * y + z * z);
+ x /= n;
+ y /= n;
+ z /= n;
+ var xx = x * x;
+ var yy = y * y;
+ var zz = z * z;
+ var c = Math.cos(angle);
+ var s = Math.sin(angle);
+ var oneMinusCosine = 1 - c;
+
+ dst[ 0] = xx + (1 - xx) * c;
+ dst[ 1] = x * y * oneMinusCosine + z * s;
+ dst[ 2] = x * z * oneMinusCosine - y * s;
+ dst[ 3] = 0;
+ dst[ 4] = x * y * oneMinusCosine - z * s;
+ dst[ 5] = yy + (1 - yy) * c;
+ dst[ 6] = y * z * oneMinusCosine + x * s;
+ dst[ 7] = 0;
+ dst[ 8] = x * z * oneMinusCosine + y * s;
+ dst[ 9] = y * z * oneMinusCosine - x * s;
+ dst[10] = zz + (1 - zz) * c;
+ dst[11] = 0;
+ dst[12] = 0;
+ dst[13] = 0;
+ dst[14] = 0;
+ dst[15] = 1;
+
+ return dst;
+};
+
+function mulMatrix(a, b) {
+ var dst = new Float32Array(16);
+ var a00 = a[0];
+ var a01 = a[1];
+ var a02 = a[2];
+ var a03 = a[3];
+ var a10 = a[ 4 + 0];
+ var a11 = a[ 4 + 1];
+ var a12 = a[ 4 + 2];
+ var a13 = a[ 4 + 3];
+ var a20 = a[ 8 + 0];
+ var a21 = a[ 8 + 1];
+ var a22 = a[ 8 + 2];
+ var a23 = a[ 8 + 3];
+ var a30 = a[12 + 0];
+ var a31 = a[12 + 1];
+ var a32 = a[12 + 2];
+ var a33 = a[12 + 3];
+ var b00 = b[0];
+ var b01 = b[1];
+ var b02 = b[2];
+ var b03 = b[3];
+ var b10 = b[ 4 + 0];
+ var b11 = b[ 4 + 1];
+ var b12 = b[ 4 + 2];
+ var b13 = b[ 4 + 3];
+ var b20 = b[ 8 + 0];
+ var b21 = b[ 8 + 1];
+ var b22 = b[ 8 + 2];
+ var b23 = b[ 8 + 3];
+ var b30 = b[12 + 0];
+ var b31 = b[12 + 1];
+ var b32 = b[12 + 2];
+ var b33 = b[12 + 3];
+ dst[ 0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30;
+ dst[ 1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31;
+ dst[ 2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32;
+ dst[ 3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33;
+ dst[ 4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30;
+ dst[ 5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31;
+ dst[ 6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32;
+ dst[ 7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33;
+ dst[ 8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30;
+ dst[ 9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31;
+ dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32;
+ dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33;
+ dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30;
+ dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31;
+ dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32;
+ dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33;
+ return dst;
+};
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+
+</body>
+</html>
+
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-transparent-pixels-initialized.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-transparent-pixels-initialized.html
new file mode 100644
index 0000000000..7fcf384edc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-transparent-pixels-initialized.html
@@ -0,0 +1,87 @@
+<!--
+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">
+<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>
+"use strict";
+var wtu = WebGLTestUtils;
+var gl = null;
+var texture;
+var textureLoc = null;
+var successfullyParsed = false;
+
+function init()
+{
+ description('Tests there is no garbage in transparent regions of images uploaded as textures');
+
+ wtu = WebGLTestUtils;
+ gl = wtu.create3DContext("example");
+ var program = wtu.setupTexturedQuad(gl);
+ gl.clearColor(0.5,0.5,0.5,1);
+ gl.clearDepth(1);
+
+ textureLoc = gl.getUniformLocation(program, "tex");
+
+ // The input texture has 8 characters; take the leftmost one
+ var coeff = 1.0 / 8.0;
+ var texCoords = new Float32Array([
+ coeff, 1.0,
+ 0.0, 1.0,
+ 0.0, 0.0,
+ coeff, 1.0,
+ 0.0, 0.0,
+ coeff, 0.0]);
+
+ var vbo = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
+ gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(1);
+ gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
+
+ texture = wtu.loadTexture(gl, "../../../resources/bug-32888-texture.png", runTest);
+}
+
+// These two declarations need to be global for "shouldBe" to see them
+var buf = null;
+var idx = 0;
+
+function runTest()
+{
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+ // Bind the texture to texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ // Point the uniform sampler to texture unit 0
+ gl.uniform1i(textureLoc, 0);
+ // Draw the triangles
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+
+ // Spot check a couple of 2x2 regions in the upper and lower left
+ // corners; they should be the rgb values in the texture.
+ var color = [0, 0, 0];
+ debug("Checking lower left corner");
+ wtu.checkCanvasRect(gl, 1, gl.canvas.height - 3, 2, 2, color,
+ "shouldBe " + color);
+ debug("Checking upper left corner");
+ wtu.checkCanvasRect(gl, 1, 1, 2, 2, color,
+ "shouldBe " + color);
+
+ finishTest();
+}
+</script>
+</head>
+<body onload="init()">
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-cube-maps.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-cube-maps.html
new file mode 100644
index 0000000000..c0104fe127
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-cube-maps.html
@@ -0,0 +1,52 @@
+<!--
+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">
+<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="example" width="2" height="2"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+description('Tests texImage2D and texSubImage2D upload path for TEXTURE_CUBE_MAP');
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas);
+wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+function testOneTarget(target, width, height) {
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from bindTexture(TEXTURE_CUBE_MAP).");
+
+ gl.texImage2D(target, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from texImage2D.");
+
+ var buf = new Uint8Array(width * height * 3);
+ gl.texSubImage2D(target, 0, 0, 0, width, height, gl.RGB, gl.UNSIGNED_BYTE, buf);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from texSubImage2D.");
+}
+
+testOneTarget(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 16, 16);
+testOneTarget(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 16, 16);
+testOneTarget(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 16, 16);
+testOneTarget(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 16, 16);
+testOneTarget(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 16, 16);
+testOneTarget(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 16, 16);
+
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-size.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-size.html
new file mode 100644
index 0000000000..a0f30dc89f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-size.html
@@ -0,0 +1,151 @@
+<!--
+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 texture upload size conformance test</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"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+enableJSTestPreVerboseLogging();
+description("Checks that the size of a texture uploaded from an element is set correctly.");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("canvas");
+
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+
+var testUpload = function(upload, expectedWidth, expectedHeight) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, upload);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "when calling texImage2D");
+ wtu.checkTextureSize(gl, expectedWidth, expectedHeight);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, upload);
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "when calling texSubImage2D with the same texture upload");
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, upload);
+ wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "when calling texSubImage2D with the same texture upload with offset 1, 1");
+};
+
+var testImage = function(test, img) {
+ var width = img.width;
+ var height = img.height;
+ testUpload(img, width, height);
+
+ debug("Testing changing the width and height attributes of the image");
+ img.width *= 2;
+ img.height *= 2;
+ if (test.isSVG) {
+ testUpload(img, img.width, img.height);
+ } else {
+ testUpload(img, width, height);
+ }
+};
+
+var testVideo = function(test, video) {
+ // Assuming that the video is not anamorphic, nor has clean aperture data
+ // that would make the frame size in pixels different.
+ var width = video.videoWidth;
+ var height = video.videoHeight;
+ testUpload(video, width, height);
+
+ debug("Testing changing the width and height attributes of the video");
+ video.width *= 2;
+ video.height *= 2;
+ testUpload(video, width, height);
+};
+
+var createCanvas2DContext = function(width, height) {
+ var canvas = document.createElement("canvas");
+ canvas.width = width;
+ canvas.height = height;
+ var ctx = canvas.getContext("2d");
+ ctx.fillRect(0, 0, width, height);
+ return ctx;
+};
+
+var testImageData = function(test) {
+ var ctx = createCanvas2DContext(test.width, test.height);
+ var imageData = ctx.getImageData(0, 0, test.width, test.height);
+ testUpload(imageData, test.width, test.height);
+};
+
+var testCanvas = function(test) {
+ var ctx = createCanvas2DContext(test.width, test.height);
+ testUpload(ctx.canvas, test.width, test.height);
+
+ debug("Testing changing the dimensions of the same canvas");
+ ctx.canvas.width = test.width + 1;
+ ctx.canvas.height = test.height + 1;
+ testUpload(ctx.canvas, ctx.canvas.width, ctx.canvas.height);
+};
+
+var tests = [
+ {type: "ImageData", width: 123, height: 456},
+ {type: "canvas", width: 123, height: 456},
+ {type: "img", isSVG: false, src: "../../../resources/red-green.png"},
+ {type: "img", isSVG: true, src: "../../../resources/red-green.svg"},
+ {type: "video", src: "../../../resources/red-green.mp4", videoType: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'},
+ {type: "video", src: "../../../resources/red-green.bt601.vp9.webm", videoType: 'video/webm; codecs="vp9"'},
+ {type: "video", src: "../../../resources/red-green.webmvp8.webm", videoType: 'video/webm; codecs="vp8, vorbis"'},
+ {type: "video", src: "../../../resources/red-green.theora.ogv", videoType: 'video/ogg; codecs="theora, vorbis"'},
+];
+
+var testIndex = 0;
+
+var runNextTest = function() {
+ if (testIndex < tests.length) {
+ debug("");
+ var test = tests[testIndex];
+ ++testIndex;
+ if (test.type == "img") {
+ debug("HTMLImageElement" + (test.isSVG ? " (SVG)" : ""));
+ var img = wtu.makeImage(test.src, function() {
+ testImage(test, img);
+ setTimeout(runNextTest, 0);
+ }, function () {
+ testFailed("could not create image" + (test.isSVG ? " (SVG)" : ""));
+ setTimeout(runNextTest, 0);
+ });
+ } else if (test.type == "video") {
+ debug("HTMLVideoElement (" + test.videoType + ")");
+ var video = wtu.makeVideo(test.src);
+ if(!video.canPlayType(test.videoType).replace(/no/, '')) {
+ debug(test.videoType + " unsupported");
+ setTimeout(runNextTest, 0);
+ return;
+ }
+ wtu.startPlayingAndWaitForVideo(video, function() {
+ testVideo(test, video);
+ setTimeout(runNextTest, 0);
+ });
+ } else if (test.type == "ImageData") {
+ debug("ImageData");
+ testImageData(test);
+ setTimeout(runNextTest, 0);
+ } else if (test.type == "canvas") {
+ debug("HTMLCanvasElement");
+ testCanvas(test);
+ setTimeout(runNextTest, 0);
+ }
+ } else {
+ finishTest();
+ }
+};
+
+runNextTest();
+</script>
+</body>
+</html>
+
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-video-transparent.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-video-transparent.html
new file mode 100644
index 0000000000..9cc34debb8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-video-transparent.html
@@ -0,0 +1,164 @@
+<!--
+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>Upload texture from animating transparent WebM or HEVC</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>
+"use strict";
+const wtu = WebGLTestUtils;
+let gl;
+let successfullyParsed;
+let video;
+
+initTestingHarness();
+
+function logVisibility(isOnload)
+{
+ let prefix = '';
+ if (isOnload)
+ prefix = 'Upon load: ';
+ if (document.hidden) {
+ console.log(prefix + '*** Tab was backgrounded (if running in automated test harness, why?) ***');
+ } else {
+ console.log(prefix + 'Tab was foregrounded');
+ }
+}
+
+function init()
+{
+ description("Upload texture from animating transparent WebM or HEVC");
+
+ document.addEventListener("visibilitychange", visibilityChanged, false);
+
+ logVisibility(true);
+
+ const canvas = document.getElementById("example");
+ gl = wtu.create3DContext(canvas);
+
+ const program = wtu.setupTexturedQuad(gl);
+ const texture = gl.createTexture();
+ // Bind the texture to texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ const textureLoc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(textureLoc, 0);
+
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ video = document.getElementById("vid");
+ const typeWebM = 'video/webm; codecs="vp8"';
+ const typeHEVC = 'video/mp4; codecs="hvc1"';
+ if (!video.canPlayType) {
+ testFailed("video.canPlayType required method missing");
+ finishTest();
+ return;
+ }
+ if (!video.canPlayType(typeWebM).replace(/no/, '') && !video.canPlayType(typeHEVC).replace(/no/, '')) {
+ debug(typeWebM + " unsupported");
+ debug(typeHEVC + " unsupported");
+ finishTest();
+ return;
+ };
+ wtu.startPlayingAndWaitForVideo(video, runTest);
+}
+
+function visibilityChanged() {
+ logVisibility(false);
+}
+
+function runTest(videoElement)
+{
+ let i = 0;
+ requestAnimationFrame(function frame() {
+ runOneIteration(videoElement, false);
+ runOneIteration(videoElement, true);
+
+ ++i;
+ if (i < 120) {
+ requestAnimationFrame(frame);
+ } else {
+ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
+ finishTest();
+ }
+ });
+
+}
+
+function runOneIteration(videoElement, useTexSubImage2D)
+{
+ // Upload the videoElement into the texture
+ if (useTexSubImage2D) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
+ } else {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
+ }
+
+ // Set up texture parameters
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+ // Draw the triangles
+ wtu.clearAndDrawUnitQuad(gl, [255, 0, 0, 255]);
+
+ const tolerance = 20;
+ const red = [255, 0, 0];
+ const green = [0, 255, 0];
+ const blue = [0, 0, 255];
+
+ // Check the left and right sides. Make sure that EITHER:
+
+ // - Left is green and right is transparent-blended-with-red
+ let leftIsGreen = false, leftIsRed = false, rightIsBlue = false, rightIsRed = false;
+ let greenRedError = "", redBlueError = "";
+ let leftGreenError = "", rightBlueError = "";
+ let bufLeft, bufRight;
+ wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, green, tolerance,
+ /* sameFn */ () => { leftIsGreen = true; }, /* differentFn */ (m, b) => { leftGreenError = m; bufLeft = b;}, debug);
+ wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, red, tolerance,
+ /* sameFn */ () => { rightIsRed = true; }, /* differentFn */ (m, b) => { greenRedError = m; bufRight = b;}, debug);
+
+ // - Right is blue and left is transparent-blended-with-red
+ wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, blue, tolerance,
+ /* sameFn */ () => { rightIsBlue = true; }, /* differentFn */ (m, b) => { rightBlueError = m; bufRight = b;}, debug);
+ wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, red, tolerance,
+ /* sameFn */ () => { leftIsRed = true; }, /* differentFn */ (m, b) => { redBlueError = m; bufLeft = b;}, debug);
+
+ if (leftIsGreen) {
+ if (rightIsRed) {
+ testPassed("left is green, right is transparent-blended-with-red");
+ } else {
+ testFailed("left is green, but: " + greenRedError + "\n" + bufRight);
+ }
+ } else if (rightIsBlue) {
+ if (leftIsRed) {
+ testPassed("right is blue, left is transparent-blended-with-red");
+ } else {
+ testFailed("right is blue, but: " + redBlueError + "\n" + bufLeft);
+ }
+ } else {
+ testFailed("neither left is green nor right is blue \n" + leftGreenError + "\n" + rightBlueError + "\n" + bufLeft + "\n" + bufRight);
+ }
+}
+</script>
+</head>
+<body onload="init()">
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<video id="vid" style="display:none;">
+ <source src="../../../resources/transparent-2frames.mp4" type='video/mp4; codecs="hvc1"' />
+ <source src="../../../resources/transparent-2frames.webm" type='video/webm; codecs="vp8"' />
+</video>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html
new file mode 100644
index 0000000000..6f080f0eea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html
@@ -0,0 +1,72 @@
+<!--
+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 texture upload with FlipY and PremultiplyAlpha.</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="example" width="32" height="32" style="width: 40px; height: 40px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+// Regression test for crbug.com/765469
+"use strict";
+description("Checks uploading textures with FlipY and PremultiplyAlpha generates INVALID_OPERATION with invalid format/type");
+
+var canvas;
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext("example");
+
+var tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+
+function testUpload() {
+ // Because WEBGL_depth_texture is enabled, UNSIGNED_SHORT becomes a valid type, but RGBA/UNSIGNED_SHORT is invalid.
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_SHORT, new Uint16Array(2*2*4));
+ wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "texImage2D() with invalid format/type combination");
+}
+
+var ext = gl.getExtension('WEBGL_depth_texture');
+if (ext) {
+ debug("");
+ debug("Testing with FlipY = false, PremultiplyAlpha = false");
+ testUpload();
+
+ debug("");
+ debug("Testing with FlipY = true, PremultiplyAlpha = false");
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
+ testUpload();
+
+ debug("");
+ debug("Testing with FlipY = false, PremultiplyAlpha = true");
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
+ testUpload();
+
+ debug("");
+ debug("Testing with FlipY = true, PremultiplyAlpha = true");
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
+ testUpload();
+} else {
+ testPassed("WEBGL_depth_texture not supported, skipping tests.");
+}
+
+gl.deleteTexture(tex);
+
+debug("");
+var successfullyParsed = true;
+</script>
+<script src="../../../js/js-test-post.js"></script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/upload-from-srcset-with-empty-data.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/upload-from-srcset-with-empty-data.html
new file mode 100644
index 0000000000..6899e31334
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/upload-from-srcset-with-empty-data.html
@@ -0,0 +1,44 @@
+<!--
+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">
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<title>Upload From Srcset With Empty Data</title>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<img srcset="data:,a 1x, data:,b 1w" id="i">
+<script>
+"use strict";
+var wtu = WebGLTestUtils;
+
+var successfullyParsed;
+
+description("This test ensures WebGL implementations handle srcsets with empty data.");
+debug("Regression test for <a href='http://crbug.com/1085044'>http://crbug.com/1085044</a>");
+
+let gl = wtu.create3DContext();
+
+// Note we run this test synchronously, rather than running it in an async
+// function called after "wtu.awaitOrTimeout(img.decode());". This reproduces
+// the bug more reliably.
+let img = document.getElementById("i");
+let tex = gl.createTexture();
+gl.bindTexture(gl.TEXTURE_2D, tex);
+// Implementations can decide how to respond to these kinds of bad
+// inputs, as long as they don't crash.
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
+
+finishTest();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/video-rotation.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/video-rotation.html
new file mode 100644
index 0000000000..b336ed6ede
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/video-rotation.html
@@ -0,0 +1,167 @@
+<!--
+Copyright (c) 2021 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>Verifies rotation metadata tag is respected when uploading videos to WebGL textures.</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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+</head>
+
+<body onload="run()">
+ <canvas id="c" width="256" height="256"></canvas>
+ <div id="description"></div>
+ <div id="console"></div>
+ <script>
+ "use strict";
+ description();
+ let wtu = WebGLTestUtils;
+ let tiu = TexImageUtils;
+ let canvas = document.getElementById("c");
+ let gl = wtu.create3DContext(canvas);
+ let program = tiu.setupTexturedQuad(gl, gl.RGBA);
+ const resourcePath = "../../../resources/";
+ const mp4Tolerance = 10;
+ // Significantly higher tolerance needed for VP9 tests. http://crbug.com/1219015 .
+ const vp9Tolerance = 45;
+
+ const expectedColors = {
+ top: { location: [0.5, 0.25], color: [255, 0, 0] },
+ left: { location: [0.4, 0.5], color: [0, 0, 255] },
+ right: { location: [0.6, 0.5], color: [255, 255, 0] },
+ bottom: { location: [0.5, 0.75], color: [0, 255, 0] },
+ }
+
+ function output(str) {
+ debug(str);
+ bufferedLogToConsole(str);
+ }
+
+ function checkPixels(tolerance) {
+ for (let place in expectedColors) {
+ let color = expectedColors[place];
+ let loc = color.location;
+ let x = loc[0];
+ let y = loc[1];
+ output(" Checking " + place);
+ wtu.checkCanvasRect(gl, Math.floor(canvas.width * x), Math.floor(canvas.height * y), 1, 1,
+ color.color, "shouldBe " + color.color + " +/-" + tolerance, tolerance);
+ }
+ }
+
+ function loadVideoElement(filename) {
+ return new Promise((resolve) => {
+ const video = document.createElement('video');
+ video.crossOrigin = 'anonymous';
+ video.src = resourcePath + filename;
+ wtu.startPlayingAndWaitForVideo(video, resolve);
+ });
+ }
+
+ async function testVideoElement(filename, isVP9) {
+ const video = await loadVideoElement(filename);
+
+ output("----------------------------------------------------------------");
+ output("Testing " + filename + " via HTMLVideoElement");
+
+ output(" Testing texImage2D");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ const localTolerance = isVP9 ? vp9Tolerance : mp4Tolerance;
+ checkPixels(localTolerance);
+
+ output(" Testing texSubImage2D");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, video.videoWidth, video.videoHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, video);
+ wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
+ checkPixels(localTolerance);
+ }
+
+ async function run() {
+ await (async () => {
+ const video = document.createElement('video');
+ if (!video.canPlayType) {
+ testFailed("video.canPlayType required method missing");
+ return;
+ }
+
+ let supports_h264 = !!video.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/no/, '');
+ let supports_vp9 = !!video.canPlayType('video/mp4; codecs="vp09.00.10.08"').replace(/no/, '');
+ if (!supports_h264 && !supports_vp9) {
+ testFailed("No supported video types.");
+ return;
+ }
+
+ let tex = gl.createTexture();
+ // Bind the texture to the default texture unit 0
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ // Set up texture parameters
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+ // These files were created by converting exif-orientation-test.psd to mp4
+ // files, rotating them using the transpose filter, and adding rotate metadata, all
+ // using the ffmpeg command-line tool.
+ //
+ // From sdk/tests/resources/ directory:
+ //
+ // 0:
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96 -pix_fmt yuv420p -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=0 video-rotation-0.mp4
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=0 video-rotation-0.vp9.mp4
+ //
+ // 90:
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2 -pix_fmt yuv420p -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=270 video-rotation-90.mp4
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=270 video-rotation-90.vp9.mp4
+ //
+ // 180:
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2,transpose=2 -pix_fmt yuv420p -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=180 video-rotation-180.mp4
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2,transpose=2 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=180 video-rotation-180.vp9.mp4
+ //
+ // 270:
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=1 -pix_fmt yuv420p -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=90 video-rotation-270.mp4
+ // ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=1 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
+ // ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=90 video-rotation-270.vp9.mp4
+
+ const filenames = [
+ "video-rotation-0",
+ "video-rotation-90",
+ "video-rotation-180",
+ "video-rotation-270",
+ ];
+
+ if (supports_h264) {
+ for (let fn of filenames)
+ await testVideoElement(fn + ".mp4", false);
+ }
+
+ if (supports_vp9) {
+ for (let fn of filenames)
+ await testVideoElement(fn + ".vp9.mp4", true);
+ }
+ })();
+
+ finishTest();
+ }
+
+ var successfullyParsed = true;
+ </script>
+</body>
+
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..549e0808ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..3bdd311bde
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..27ace886fe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..38b37c8422
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..fd87fd2053
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..f8955c891d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..b9491232cb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..cee000e426
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-svg-image.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..c2f1c72e7e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..d985f3875d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..4c6e263474
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..6eaf2065d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..a4675599ee
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..b07d911e1f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..df27fd9932
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..de35a7b355
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-video.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/00_test_list.txt
new file mode 100644
index 0000000000..66a3a84456
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/00_test_list.txt
@@ -0,0 +1,8 @@
+tex-2d-rgb-rgb-unsigned_byte.html
+tex-2d-rgb-rgb-unsigned_short_5_6_5.html
+tex-2d-rgba-rgba-unsigned_byte.html
+tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
+tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
+tex-2d-luminance-luminance-unsigned_byte.html
+tex-2d-alpha-alpha-unsigned_byte.html
+tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html
new file mode 100644
index 0000000000..5870ebaba7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("ALPHA", "ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html
new file mode 100644
index 0000000000..9c551d0232
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE", "LUMINANCE", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
new file mode 100644
index 0000000000..d25216cb87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("LUMINANCE_ALPHA", "LUMINANCE_ALPHA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html
new file mode 100644
index 0000000000..889b5f1fe5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
new file mode 100644
index 0000000000..ceb0f09ff9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGB", "RGB", "UNSIGNED_SHORT_5_6_5", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html
new file mode 100644
index 0000000000..20711c46dc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_BYTE", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
new file mode 100644
index 0000000000..bebf83cd01
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_4_4_4_4", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
new file mode 100644
index 0000000000..0d448009eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html
@@ -0,0 +1,38 @@
+<!--
+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.
+-->
+
+<!--
+
+This file is auto-generated from py/tex_image_test_generator.py
+DO NOT EDIT!
+
+-->
+
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<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 src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
+<script src="../../../js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js"></script>
+</head>
+<body>
+<canvas id="example" width="32" height="32"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+"use strict";
+function testPrologue(gl) {
+ return true;
+}
+
+generateTest("RGBA", "RGBA", "UNSIGNED_SHORT_5_5_5_1", testPrologue, "../../../resources/", 1)();
+</script>
+</body>
+</html>